简体   繁体   English

解析Java中的一段时间

[英]Parse period of time in Java

I want to be able to parse period of time (days, hours, minutes) + optional string so the input looks like this: <time>(white_spaces)<optional_string> . 我希望能够解析一段时间(天,小时,分钟)+可选字符串,因此输入如下所示: <time>(white_spaces)<optional_string> As i know regex is the right tool for such things so i came up with such expression: 我知道正则表达式是这类东西的正确工具所以我想出了这样的表达:

Pattern.compile("((?<days>\\d+)d)?((?<hours>\\d+)h)?((?<minutes>\\d+)m)?\\s+?(?<reason>.+)?");

Basically it works as expected however in this expression all times groups (days, hours, minutes) are optional and i want the input to atleast contain minutes group. 基本上它按预期工作,但在此表达式中,所有时间组(天,小时,分钟)都是可选的,我希望输入至少包含分钟组。 However if hours or days are specified, minutes are not required. 但是,如果指定了小时或天,则不需要分钟。 Also, all combinations of time groups (d+h, h+m, d+m, d+h+m) are possible. 此外,时间组的所有组合(d + h,h + m,d + m,d + h + m)都是可能的。 So how can i correct my expression? 那我怎么能纠正我的表情呢? Or maybe there is other way to parse period of time? 或者也许有其他方式来解析一段时间?

EDIT: examples of inputs: 编辑:输入的例子:

12h64m - correct 12h64m - 正确

12d43m dsd - correct 12d43m dsd - 正确

- empty string - not correct - 空字符串 - 不正确

12m - correct 12m - 正确

12d32h43m - correct 12d32h43m - 正确

sdsds - not correct - no "time group specified" sdsds - 不正确 - 没有“时间组指定”

tl;dr TL;博士

Duration.parse( 
    "P"
    .concat( "12d32h43m".replace( "d" , "DT" ) )
    .toUpperCase()
).toHoursPart()

8 8

You said: 你说:

As i know regex is the right tool for such things 我知道正则表达式是这类事情的正确工具

Nope. 不。 No need for regex. 不需要正则表达式。

ISO 8601 ISO 8601

Your input string format is close to the format formally defined by the ISO 8601 standard: PnYnMnDTnHnMnS 您的输入字符串格式接近ISO 8601标准正式定义的格式: PnYnMnDTnHnMnS

The P marks the beginning. P标志着开始。 The T separates any years-months-days from any hours-minutes-seconds. T将任何年 - 月 - 天与任何小时 - 分钟 - 秒分开。

Convert your input to conform with the standard. 转换您的输入以符合标准。

String input =  "P".concat( "12d32h43m".replace( "d" , "DT" ) ).toUpperCase() ;

P12DT32H43M P12DT32H43M

java.time java.time

Java has a class for that, Duration (and Period ). Java有一个类, Duration (和Period )。 No need for regex. 不需要正则表达式。

You can interrogate for each part. 您可以询问每个部分。 Call to…Part methods added in Java 9 . 调用to…Part Java 9中添加的to…Part方法。 For Java 8, see this Question and this Question . 对于Java 8,请参阅此问题此问题

long daysPart = d.toDaysPart() ;
int hoursPart = d.toHoursPart() ;

Entire example: 整个例子:

String input = "P".concat( "12d32h43m".replace( "d" , "DT" ) ).toUpperCase();
Duration d = Duration.parse( input );
long daysPart = d.toDaysPart();
int hoursPart = d.toHoursPart();
long hoursTotal = d.toHours(); // Total elapsed hours of entire duration.

Dump to console. 转储到控制台。 Notice the math. 注意数学。 Your input of 32 hours is recalculated to be 8, and days went from 12 to 13 (an extra 24-hour chunk = a day). 您输入的32小时重新计算为8,日期从12到13(额外的24小时大块=一天)。

System.out.println( "input: " + input );
System.out.println( "d.toString()" + d );
System.out.println( "daysPart: " + daysPart );  // 13, not the 12 days seen in the input string. 24 hours were taken from the excessive `32h` of the input string, leaving 8 in the hours part.
System.out.println( "hoursPart: " + hoursPart );
System.out.println( "hoursTotal: " + hoursTotal );  // ( ( 13 * 24 ) + 8 ) = ( 312 + 8 ) = 320 

input: P12DT32H43M 输入:P12DT32H43M

d.toString()PT320H43M d.toString()PT320H43M

daysPart: 13 daysPart:13

hoursPart: 8 小时数:8

hoursTotal: 320 小时总数:320

Duration versus Period DurationPeriod

Use Duration for hours-minutes-seconds values. 使用Duration表示小时 - 分钟 - 秒值。 Use Period for years-months-days values. 使用Period表示年 - 月 - 日值。

  • In a Duration , “days” are understood to be generic chunks of 24-hours unrelated to dates and the calendar. Duration ,“天”被理解为与日期和日历无关的24小时的通用块。
  • If you want dates, you should be using the Period class. 如果您想要日期,则应使用Period类。
  • If you want both, think again. 如果你想要两者,那就再想一想。 It usually does not make sense to mix the two concepts, though this may seem counter-intuitive at first thought. 混合这两个概念通常没有意义,尽管这可能在最初的想法中看起来是反直觉的。 But if you insist, see the PeriodDuration class available in the ThreeTen-Extra project. 但是如果你坚持,请参阅ThreeTen-Extra项目中提供的PeriodDuration类。

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. 使用符合JDBC 4.2或更高版本的JDBC驱动程序 ,您可以直接与数据库交换java.time对象。 No need for strings nor java.sql.* classes. 不需要字符串也不需要java.sql。*类。

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

((?<minutes>\\\\d+)m)? means, the minutes group is optional. 表示分钟组是可选的。 But you want it to be mandatory, so remove the trailing question mark. 但您希望它是强制性的,因此请删除尾随问号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM