Java日期和时间从给定日期中删除时区“;2019-12-03T10:00:00-06:00“;预计日期为;2019-12-03T10:00:00“;
上述代码按预期工作,但如果时区不可用,则不工作 给定输入日期:2019-12-03T10:00:00-06:00或2019-12-03T10:00:00 预计o/p日期:2019-12-03T10:00:00Java日期和时间从给定日期中删除时区“;2019-12-03T10:00:00-06:00“;预计日期为;2019-12-03T10:00:00“;,java,java-8,Java,Java 8,上述代码按预期工作,但如果时区不可用,则不工作 给定输入日期:2019-12-03T10:00:00-06:00或2019-12-03T10:00:00 预计o/p日期:2019-12-03T10:00:00 我的代码应适用于有时区和无时区输入日期 给定输入日期:2019-12-03T10:00:00-06:00或2019-12-03T10:00:00 那是两种截然不同的动物 第一个代表一个时刻,时间线上的一个特定点。第二种情况并非如此。第二次是上午10点在东京,上午10点在图卢兹,或上午10点
我的代码应适用于有时区和无时区输入日期 给定输入日期:2019-12-03T10:00:00-06:00或2019-12-03T10:00:00 那是两种截然不同的动物 第一个代表一个时刻,时间线上的一个特定点。第二种情况并非如此。第二次是上午10点在东京,上午10点在图卢兹,或上午10点在托莱多-三个非常不同的时刻相隔几个小时 第一个应该被解析为
OffsetDateTime
。第二个应该被解析为LocalDateTime
错误类型
对于输入,如2019-12-03T10:00:00-06:00
,解析为OffsetDateTime
。您使用了LocalDateTime
,它无法处理该字符串末尾与UTC的偏移量
无需指定格式化模式。您的输入符合默认使用的ISO 8601标准
LocalDateTime formatOrderEndDateTime;
try {
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
formatOrderEndDateTime = LocalDateTime.parse("2019-12-03T10:00:01+01:00", formatter);
System.out.println(formatOrderEndDateTime);
} catch (Exception e) {
throw new IllegalArgumentException();
}
错误格式化程序
要生成省略偏移量的ISO 8601格式的文本,请使用
偏移量与时区
时区不工作
您的输入没有时区。它们与UTC有一个偏移量。偏移量只是小时分秒数
时区更重要。时区是特定地区人民使用的偏移量的过去、现在和未来变化的历史。时区的名称为
大陆/地区
格式,例如欧洲/巴黎
,我认为您必须使用一对不同的格式化程序,如下面的代码所示。从DateTimeFormatter.ISO\u DATE\u TIME
的文档中:
类似ISO的日期-时间格式化程序,可使用偏移量和区域(如果可用)格式化或解析日期-时间,如“2011-12-03T10:15:30”、“2011-12-03T10:15+01:00”或“2011-12-03T10:15:30+01:00[欧洲/巴黎]”
然后,您必须使用不同的格式化程序将其转换为字符串,而不是使用LocalDateTime.toString()
因此,这允许以任何支持的格式提供输入,然后以我们想要的格式创建字符串。您不应该需要LocalDateTime
例如:两个字符串2019-12-03T10:00:01+09:00
和2019-12-03T10:00:01-08:00
表示相隔17小时的时间点,但将被解析为相等的LocalDateTime
对象。我想你不想那样
另外,LocalDateTime
可能不适合订单结束时间。它不知道任何时区或UTC的偏移量,因此每个人和看到它的每段代码都可以自由地解释为他们碰巧想到的时区,而不是预期的时区。这就留下了意外结果的巨大风险。对于20个目的中的至少19个,您最好使用即时
、偏移日期时间
或分区日期时间
使用和不使用偏移量解析:定义默认时区
您需要接受没有偏移量的字符串。然后,您还需要知道为这些字符串假定哪个时区—默认时区。然后你也可以解析它们
例如:
LocalDateTime formatOrderEndDateTime;
try {
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
formatOrderEndDateTime = LocalDateTime.parse(line.trim(), formatter);
DateTimeFormatter f2 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
System.out.println(formatOrderEndDateTime.format( f2 ));
} catch (Exception e) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
此代码段的输出为:
我在格式模式字符串中使用
[XXX]
来表示可选偏移量。对parseBest()
的调用可以解析为OffsetDateTime
(如果可以)(偏移量存在),否则将解析为我随后转换的LocalDateTime
。最后,我将所有解析的日期和时间转换为一个时区,以便用户可以看到一致的结果。如果ISO\u OFFSET\u DATE\u time
失败(即DateTimeParseException
),请尝试ISO\u LOCAL\u DATE\u time
。如果这也失败了,请为2019-12-03T10:00:00-06:00或2019-12-03T10:00:00处理例外输出2019-12-03T10:00:00“我的代码应适用于有时区和无时区输入日期”?那么您想忽略任何表示时区偏移的内容吗?这意味着您积极地想要分析错误的日期,您明白吗?2019-12-03T10:00:00
,第二个不明白。第二个是上午10点在东京,上午10点在图卢兹,还是上午10点在托莱多
。这不是UTC的默认格式吗?
String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) ;
LocalDateTime formatOrderEndDateTime;
try {
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
formatOrderEndDateTime = LocalDateTime.parse(line.trim(), formatter);
DateTimeFormatter f2 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
System.out.println(formatOrderEndDateTime.format( f2 ));
} catch (Exception e) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
ZoneId defaultTimeZone = ZoneId.of("America/Guatemala");
ZoneId resultTimeZone = ZoneId.of("Europe/Rome");
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX]")
.toFormatter();
for (String input : new String[] {
"2019-12-03T10:00:01+01:00",
"2019-12-03T10:00:00-06:00",
"2019-12-03T10:00:00"
}) {
TemporalAccessor parsed = formatter.parseBest(input,
OffsetDateTime::from, LocalDateTime::from);
ZonedDateTime dateTime;
if (parsed instanceof OffsetDateTime) {
dateTime = ((OffsetDateTime) parsed).atZoneSameInstant(resultTimeZone);
} else {
dateTime = ((LocalDateTime) parsed).atZone(defaultTimeZone)
.withZoneSameInstant(resultTimeZone);
}
System.out.format("%-25s is parsed into %s%n", input, dateTime);
}
2019-12-03T10:00:01+01:00 is parsed into 2019-12-03T10:00:01+01:00[Europe/Rome]
2019-12-03T10:00:00-06:00 is parsed into 2019-12-03T17:00+01:00[Europe/Rome]
2019-12-03T10:00:00 is parsed into 2019-12-03T17:00+01:00[Europe/Rome]