我一直在寻找这个,但到目前为止没有成功。你知道是否有" DateFormat" ish class,这将允许我使用" 00:00:00"和" 24:00:00"作为输入参数(它们都是午夜)但是当被调用时#34; getHour()"结果我会得到0或24?
使用" kk"只会让我有< 1:24>范围,同时我正在寻找< 0:24>范围格式
答案 0 :(得分:8)
值24:00
未在LocalTime
中表示,因为它严格属于第二天。考虑了24:00
可以表示为LocalTime
的一部分的模型,但结论是在很多用例中它会非常混乱,并且会产生比它解决的更多错误。
然而,24:00
支持java.time
。完全可以使用标准格式化技术对其进行解析,但是必须使用SMART或LENIENT模式,请参阅ResolverStyle。默认模式为SMART,但DateTimeFormatter
上的DateTimeFormatter.ISO_LOCAL_DATE_TIME
上的formtter常量处于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
请注意,这也适用于OffsetDateTime
和ZonedDateTime
。 Instant
的标准解析器支持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做一个很好的补充。
答案 1 :(得分:6)
首先让我们明确时间 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 对此特殊时段也没有真正的支持。您可以在这里做的最好的事情是使用parseExcessDays()应用DateTimeFormatter
的原始解析数据。你可以使用这样的解决方法:
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
(类似于LocalTime
的链接),对完整的日期时间表示无效(它会有矛盾,包含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