解析时间字符串,如"1h 30min"

Jon*_*nik 36 java time parsing jodatime

任何人都知道Java库可以解析时间字符串,例如"30min"或"2h 15min"或"2d 15h 30min",作为毫秒(或某种Duration对象).Joda-Time可以这样做吗?

(我有一个丑陋的长方法来维护这种解析,并希望摆脱它/用更好的工作替换它.)

Bra*_*ace 33

你可能不得不为自己的格式稍微调整一下,但尝试以下几点:

PeriodFormatter formatter = new PeriodFormatterBuilder()
    .appendDays().appendSuffix("d ")
    .appendHours().appendSuffix("h ")
    .appendMinutes().appendSuffix("min")
    .toFormatter();

Period p = formatter.parsePeriod("2d 5h 30min");
Run Code Online (Sandbox Code Playgroud)

请注意,如果您需要使其更灵活appendSuffix,则需要variants参数.

更新:Joda Time已经添加Period.toStandardDuration(),从那里你可以getStandardSeconds()用来获得经过的时间,以秒为单位long.

如果您使用的是没有这些方法的旧版本,您仍然可以通过假设一天中标准24小时,60分钟/小时等来自行计算时间戳.(在这种情况下,请利用类中的常量DateTimeConstants来避免需要魔法数字.)


And*_*ejs 26

持续时间解析现在包含在Java 8中.使用标准ISO 8601格式Duration.parse.

Duration d = Duration.parse("PT1H30M")
Run Code Online (Sandbox Code Playgroud)

您可以将此持续时间转换为总长度(以毫秒为单位).请注意,Duration其分辨率为纳秒,因此您可能会将数据丢失从纳秒毫秒.

long milliseconds = d.toMillis();
Run Code Online (Sandbox Code Playgroud)

格式与您描述的格式略有不同,但可以轻松地从一个转换为另一个.

  • 当问题是关于“例如“ 30min”或“ 2h 15min”或“ 2d 15h 30min””时,这有什么帮助? (3认同)
  • 这也增加了支持ISO8601标准的持续时间的好处.ISO字符串必须与形式P [yY] [mM] [dD] [T [hH] [mM] [s [.s] S]]匹配.它使用Java 8中的标准Java类,还有Java 6和7的后端程序,请参阅:http://www.threeten.org/threetenbp/ (2认同)

Vic*_*tor 14

我想让日,小时和分钟可选,这似乎可以做到这一点.请注意,appendSuffix()调用在字符后面没有空格.

使用Joda 2.3.

PeriodParser parser = new PeriodFormatterBuilder()
        .appendDays().appendSuffix("d").appendSeparatorIfFieldsAfter(" ")
        .appendHours().appendSuffix("h").appendSeparatorIfFieldsAfter(" ")
        .appendMinutes().appendSuffix("min")
        .toParser();
Run Code Online (Sandbox Code Playgroud)

上面的代码通过了这些测试.

@Test
public void testConvert() {
    DurationConverter c = new DurationConverter();

    Duration d;
    Duration expected;

    d = c.convert("1d");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardDays(1),1);
    assertEquals(d, expected);

    d = c.convert("1d 1h 1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardDays(1),1)
            .withDurationAdded(Duration.standardHours(1),1)
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);


    d = c.convert("1h 1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardHours(1),1)
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);

    d = c.convert("1h");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardHours(1),1);
    assertEquals(d, expected);

    d = c.convert("1min");
    expected = Duration.ZERO
            .withDurationAdded(Duration.standardMinutes(1),1);
    assertEquals(d, expected);

}
Run Code Online (Sandbox Code Playgroud)


bek*_*kce 6

仅供参考,只写了一个小时以上的时间,只使用java.time.*,非常容易理解和定制以满足任何需要;

这个版本适用于像这样的字符串;3d12h2y9m10d,等。

import java.time.Duration;
import java.time.Instant;
import java.time.Period;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Locale;
Run Code Online (Sandbox Code Playgroud)
private static final Pattern periodPattern = Pattern.compile("([0-9]+)([hdwmy])");

public static Long parsePeriod(String period){
    if(period == null) return null;
    period = period.toLowerCase(Locale.ENGLISH);
    Matcher matcher = periodPattern.matcher(period);
    Instant instant=Instant.EPOCH;
    while(matcher.find()){
        int num = Integer.parseInt(matcher.group(1));
        String typ = matcher.group(2);
        switch (typ) {
            case "h":
                instant=instant.plus(Duration.ofHours(num));
                break;
            case "d":
                instant=instant.plus(Duration.ofDays(num));
                break;
            case "w":
                instant=instant.plus(Period.ofWeeks(num));
                break;
            case "m":
                instant=instant.plus(Period.ofMonths(num));
                break;
            case "y":
                instant=instant.plus(Period.ofYears(num));
                break;
        }
    }
    return instant.toEpochMilli();
}

Run Code Online (Sandbox Code Playgroud)