2017-03-23 11 views
3

我有一个'HH:mm'格式的输入字符串,其中时间分隔符是根据区域设置设置的(例如,'10:45'代表美国或'10 .45'代表意大利)。我需要将其转换为分钟数量。如何将HH:mm分析为考虑语言环境时间分隔符的分钟数?

这里是我想出了:

String timeSeparator = getTimeSeparator(locale); 
String[] duration = durationString.split(Pattern.quote(timeSeparator)); 
int minutes = Integer.valueOf(duration[0])*60 + Integer.valueOf(duration[1]); 

getTimeSeparator方法从https://stackoverflow.com/a/7612009/7753225

采取有什么简单的方法?例如使用`java.time'。

+0

你可以删除Integer.valueOf(),(即使在当时,它会被autoboxed)。我认为JodaTime有这个选择。从日期时间获取分钟数/秒/无论如何 – Wietlol

+3

为什么不直接忽略分隔符? int minute = Integer.parseInt(durationString.substring(0,2))* 60 + Integer.parseInt(durationString.substring(3))' – Andreas

回答

0

您可以使用getLocalizedDateTimePattern方法获得一个模式,用于初始化DateTimeFormatter,以使用给定的语言环境解析时间。第一个null是你不需要的日期。

String timePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
      null, FormatStyle.SHORT, IsoChronology.INSTANCE, locale); 

然后你使用它来创建一个格式化(请注意,您必须再次指定区域):

DateTimeFormatter dtf = DateTimeFormatter.ofPattern(timePattern, locale); 

如果不是你期望"HHcmm"localeSHORT时间格式,其中'c'是非数字字符,即locale的时间分隔符,则:

  1. extract nu从文本

    String[] duration = durationString.split("\\D"); 
    int minutes = parseInt(duration[0])*60 + parseInt(duration[1]); 
    
  2. mbers做出DateTimeFormatter与时间分隔符

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
         String.format("HH%smm", timeSeparator), locale); 
    LocalTime time = LocalTime.parse(text, dtf); 
    int minutes = time.toSecondOfDay()/60; 
    

    ,或者如果你必须

    int minutes = ChronoUnit.MINUTES.between(LocalTime.MIN, time); 
    
+0

如果locale是US,那么这里也会是DateTimeParseException,因为输入在'HH: mm“格式,而不是'HH:mm aa' – Lega

1

在Java 8,你可以使用DateTimeFormatter.ofLocalizedTime获得区域特定的日期时间格式化程序。那么你可以使用它来parse the string into a LocalTimeextract the minute field

public static int getMinute(String timeString, Locale locale) { 
    DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT) 
               .withLocale(locale); 
    LocalTime time = LocalTime.parse(timeString, formatter); 
    return time.getHour()*60 + time.getMinute(); 
} 

例子:

System.out.println(getMinute("10.47", new Locale("fi"))); // 647 
System.out.println(getMinute("11:23", Locale.ROOT));  // 683 

如果你不计较时间分隔符,我们可以用一个固定的模式来代替。

public static int getMinute(String timeString, Locale locale) { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH[:][.]mm", locale); 
    LocalTime time = LocalTime.parse(timeString, formatter); 
    return time.getHour()*60 + time.getMinute(); 
} 

(该[…]意味着可选的,所以它会匹配HH:mmHH.mmHHmmHH:.mm

+0

如果语言环境为美国,将会出现DateTimeParseException,因为timeString的格式为'HH:mm',而不是'HH:mm aa' – Lega

+1

@Lega那么意思是'HH:mm'不是美国的预期区域设置格式。查看更新以获取替代方案。 – kennytm

+0

'return time.getMinute();'将仅返回LocalTime的一小部分,这应该是'return time.getHour()* 60 + time.getMinute();'从午夜返回分钟 – tomasz77

0

首先解析时间为LocalTime实例,随后计算差值的一天使用Duration开始:

以上
DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
      .appendLocalized(null, FormatStyle.SHORT) 
      .toFormatter(Locale.ITALY); 
    LocalTime time = LocalTime.from(formatter.parse("10.45")); 
    long minutes = Duration.between(LocalTime.MIN, time).toMinutes(); 

结果645

+0

如果locale是US,那么这里也会是DateTimeParseException,因为输入是'HH:mm'格式,而不是'HH:mm aa' – Lega

1

TL;博士

Duration.parse( 
    "PT" + 
    "10:45".replace(":" , "M") 
      .replace("-" , "M") 
      .replace("." , "M") 
      .replace("," , "M") 
    + "S" 
).toMinutes() 

“10:45” →PT10M45S→10

ISO 8601格式

ISO 8601标准定义的时间跨度这样的格式不附着至时间线:PnYnMnDTnHnMnS

P标记t他开始。 T将小时 - 分钟 - 秒内的任意年 - 月 - 日分开。所以一个半小时是PT1H30M。你十分钟四十五秒的例子是PT10M45S

执行简单的字符串操作将输入转换为此格式。

String input = "10:45" ; 
String inputStandardized = "PT" + 
    input.replace(":" , "M") 
     .replace("-" , "M") 
     .replace("." , "M") 
     .replace("," , "M") 
     + "S" ; 

PT10M45S

Duration

解析作为Duration。分析和生成字符串时,java.time类默认使用ISO 8601格式。所以不需要指定格式化模式。

Duration duration = Duration.parse(inputStandardized); 

duration.toString():PT10M45S

可以使用Duration对象做日期 - 时间数学,传递给plusminus。所以你可能不需要分钟数作为整数。但你可以要求在这段时间内的总分钟数。

long minutes = duration.toMinutes(); 

看到这个code run live at IdeOne.com

提示:在一段时间内使用时钟时间格式会造成麻烦。歧义导致混淆和错误。我建议使用标准ISO 8601格式的持续时间,因为它们被设计为明确,易于阅读和易于解析。

1

注很优雅,但你甚至不使用整数会做的工作

String pattern = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT) 
    .withLocale(locale).format(LocalTime.MIN) 
    .replaceFirst("\\d*", "H").replaceFirst("\\d.*", "mm"); 
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale); 
int minutes = formatter.parse(string).get(ChronoField.MINUTE_OF_DAY); 
相关问题