(简单)允许24:00:00和00:00:00作为输入的DateFormat

我一直在寻找这个,到目前为止没有成功。 你知道是否有一个“DateFormat”ish类,这将允许我使用“00:00:00”和“24:00:00”作为输入参数(它们都是午夜)但是当被称为“getHour()”时“结果我会得到0或24?

使用“kk”只允许我有范围,同时我正在寻找范围格式

24:00未在LocalTime表示,因为它严格地是第二天的一部分。 考虑到24:00可以表示为LocalTime一部分的模型,但结论是它在很多用例中会非常混乱,并且会产生比它解决的更多错误。


但是在java.time支持24:00 。 完全可以使用标准格式化技术对其进行解析,但是必须使用SMART或LENIENT模式,请参阅ResolverStyle 。 默认模式为SMART,但DateTimeFormatter上的formtter常量(如DateTimeFormatter.ISO_LOCAL_DATE_TIME处于STRICT模式。 因此, ofPattern()默认为SMART模式:

 static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"); LocalDateTime ldt = LocalDateTime.parse("2012-12-03T24:00", FORMATTER); System.out.println(ldt); // 2012-12-04T00:00 

请注意,这也适用于OffsetDateTimeZonedDateTimeInstant的标准解析器支持24:00没有特殊的格式化程序:

 Instant instant = Instant.parse("2015-01-01T24:00:00Z"); System.out.println(instant); // 2015-01-02T00:00:00Z 

可以使用withResolverStyle()将任何格式化程序转换为SMART或LENIENT模式,如下所示:

 DateTimeFormatter f = ... // obtain a formatter somehow DateTimeFormatter smartMode = f.withResolverStyle(ResolverStyle.SMART); // for example f = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withResolverStyle(ResolverStyle.SMART); 

第二个支持元素是parseExcessDays() 。 这允许在仅解析时间时获得超出的日期:

 static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); TemporalAccessor parsed = TIME_FORMATTER.parse("24:00"); LocalTime lt = LocalTime.from(parsed); Period excessDays = parsed.query(DateTimeFormatter.parsedExcessDays()); System.out.println(lt + " + " + excessDays); // 00:00 + P1D 

最后,给高级用户注意。 从理论上讲,它应该可以编写自己的Temporal实现,它是LocalTime的副本,但支持24:00作为有效值。 这样的一个类,比如LocalTimeWithEndOfDay ,可以在没有问题的情况下与格式化程序/解析器一起运行(并且可能是对ThreeTen-Extra的一个很好的补充。

首先让我们说清楚24:00的时间是有效的ISO-8601时间 。 来自ISO-8601的引用:

 4.2 Time of day 4.2.1 General This International Standard is based on the 24-hour timekeeping System that is now in common use. In expressions of time of day hour is represented by two digits from [00] to [24]. The representation of the hour by [24] is only allowed to indicate the end of a calendar day, see 4.2.3. 

除非您使用SimpleDateFormat宽松解析模式,否则Java本身不支持24:00。 但是即使这样,支持也不可用,因为如果你在小时内询问结果( java.util.Date一个实例),你就会得到零。 类似的想法对java.util.GregorianCalendar有效。 解析后,没有机会确定输入是否是24:00(不知道原始输入是什么)。

Java-8也没有真正支持这个特殊时刻。 你可以做的最好的事情是使用应用于DateTimeFormatter的原始解析数据的parseExcessDays() 。 你可以使用这样的解决方法:

 String input = "24:00:00"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); TemporalAccessor raw = dtf.parse(input); int hour = raw.query(LocalTime::from).getHour(); Period period = raw.query(DateTimeFormatter.parsedExcessDays()); if (period.equals(Period.ofDays(1))) { hour = 24; } System.out.println("iso-hour=" + hour); // output: iso-hour=24 

受欢迎的第三方图书馆Joda-Time不支持24:00。 情况类似于SimpleDateFormat

我所知道的唯一具有内置支持的库是我自己编写的Time4J 。 完全支持仅限于PlainTime (与PlainTime类似的吊坠),对完整的日期时间表示无效(在这里它会有矛盾,包含24:00的时间戳将自动标准化为次日00:00):

 PlainTime time = Iso8601Format.EXTENDED_WALL_TIME.parse("24:00:00"); System.out.println(time.get(PlainTime.ISO_HOUR)); // 24 

请注意,类PlainTime的状态空间稍微扩展,以便它可以保存此特殊的ISO时间值。 因此,这样的直接程序访问是可能的:

 PlainTime time24 = PlainTime.midnightAtEndOfDay(); // or: PlainTime.of(24, 0); System.out.println(time24); // T24