Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DST更改导致java.text.ParseException:不可解析的日期_Java_Simpledateformat_Dst_Datetime Parsing - Fatal编程技术网

DST更改导致java.text.ParseException:不可解析的日期

DST更改导致java.text.ParseException:不可解析的日期,java,simpledateformat,dst,datetime-parsing,Java,Simpledateformat,Dst,Datetime Parsing,以下是引发异常的代码段: SimpleDateformat dateFormatter = new SimpleDateFormat("yyyyMMddHHmm"); Date date = dateFormatter.parse("201710010200"); 上面的代码对凌晨2:00之后的所有日期都抛出了异常。它一直运行到凌晨1:30 夏令时已配置我正在使用澳大利亚/悉尼时区 在那之后,我可以看到凌晨3点的日志。 凌晨2:00到凌晨3:00之间的时间也不会被记录 日志: 01十月03:0

以下是引发异常的代码段:

SimpleDateformat dateFormatter = new SimpleDateFormat("yyyyMMddHHmm");
Date date = dateFormatter.parse("201710010200");
上面的代码对凌晨2:00之后的所有日期都抛出了异常。它一直运行到凌晨1:30

夏令时已配置我正在使用澳大利亚/悉尼时区

在那之后,我可以看到凌晨3点的日志。 凌晨2:00到凌晨3:00之间的时间也不会被记录

日志:

01十月03:02:01错误:不可解析日期:201710010200

原因:java.text.ParseException:不可解析日期:201710010200 位于java.text.DateFormat.parseDateFormat.java:357


如果指定了正确的日期格式,日期字符串201710010200未被解析的问题有什么解决方法?

您正在尝试解析一个未发生的日期/时间

我们现在知道这是在悉尼时区。2017年10月1日悉尼凌晨2点,时钟拨到凌晨3点。如果你每分钟看一次钟,你会看到:

01:58 01:59 03:00 03:01 因此,凌晨2点(含)到凌晨3点(不含)之间的任何日期/时间都不会发生在该时区。我们不知道是什么产生了您试图解析的值,但是:

如果它们是时间戳,那么几乎可以肯定,在UTC中格式化和解析会更好。如果生成它们的时区对于将来的分析很重要,则保留与UTC的偏移量和可能的时区ID。 如果它们是未链接到任何特定时区的日期/时间值,请不要像在时区中一样解析它们。理想情况下,使用Java8的Java.time包并将其解析为LocalDateTime值 tl;博士 2017-10-01T03:00+11:00[澳大利亚/悉尼]

如果than区域中该日期的时间无效,则ZonedDateTime类将进行调整

如果你害怕错误的输入,那就找一个陷阱

细节 答案是正确的。根据他的评论:在悉尼,当地时间2017年10月1日凌晨2点并不存在

java.time 现代的解决方案是java.time类,它取代了麻烦的旧遗留日期时间类

解析 定义与输入匹配的格式模式

String input = "201710010200" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmm" ) ;
LocalDateTime 您的输入缺少与UTC或时区的偏移指示器。因此,将其解析为LocalDateTime

ldt.toString:2017-10-01T02:00

如果没有时区或UTC偏移的上下文,此值就没有实际意义。它并不代表一个时刻,时间线上的一个点。这只是一个关于26-27小时范围内可能出现的时刻的模糊概念

要确定某个时刻,我们需要将该值放在时区或偏移的上下文中

您声称知道该值旨在表示澳大利亚/悉尼时区的某个时刻

ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
2017-10-01T03:00+11:00[澳大利亚/悉尼]

结果是凌晨3点。那个地区的人们所使用的语言在那个时候发生了变化,这是愚蠢的一种转变。当澳大利亚那一地区的时钟即将敲响凌晨2点时,时钟跳到凌晨3点。在那片土地上根本不存在凌晨2点。该类具有自动调整此类无效时刻的策略。一定要阅读文档,看看你是否理解并同意它的算法

因为这个挂钟时间从来就不存在,我怀疑你对代表澳大利亚/悉尼地区某一时刻的日志数据的看法是错误的

UTC 这里更大的解决方案是学习在UTC中思考、工作、记录和交换数据。认为UTC是一个真实的时间,而所有其他区域只是这个主题的一个变体。在工作编程/管理时,忘记你自己的狭隘时区

在java.time中,UTC值的基本类是Instant。该类表示时间线上的某个时刻,分辨率高达9位小数

此类可以捕获UTC中的当前时刻

Instant instant = Instant.now() ;  // Capture the current moment in UTC.
ISO 8601 Instant类还可以解析/生成标准格式的字符串

2018-01-23T12:34:56.734591Z

末端的Z是Zulu的缩写,表示UTC。这是原始问题的症结所在:您存储的日期时间值没有区域/偏移的指示器

解析:

Instant instant = Instant.parse( "2018-01-23T12:34:56.734591Z" ) 
我强烈建议使用ISO 8601格式来存储/交换文本日期时间值。请务必:

存储/交换时刻时包括偏移/区域,时间线上的精确点。 使用扩展格式,而不是这些最小化分隔符使用的“基本”格式。这些信息很难被人阅读,信息类型也不太明显,默认情况下在java.time中不使用。默认情况下,java.time类使用扩展格式。 关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。s 说明是

使用兼容的或更高版本,您可以直接与数据库交换java.time对象。不需要字符串,也不需要java.sql.*类

从哪里获得java.time类

,及以后 内置的。 标准JavaAPI的一部分,带有捆绑实现。 Java9添加了一些次要功能和修复。 和 大部分java.time功能都在中向后移植到Java6和Java7。 更高版本的Android捆绑包实现了java.time类。 对于早期的Android,该项目采用了上面提到的Three-Ten Backport。看见
该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,如、、和。

那么您所在的时区是什么?如果跳过了10月1日凌晨2点,这是有道理的-当地时间不存在。如果这些是时间戳,则应记录在UTC中,然后在UTC中解析…没有日期。。澳大利亚悉尼不知道你说的没有日期是什么意思,但正如我预测的那样,悉尼时区确实在10月1日凌晨2点向前移动。所以基本上,如果你在悉尼看一个正确的时钟,你永远不会看到凌晨2点或凌晨2:30。时钟将转到1:58、1:59、3:00。它们是格式为YYYYMMDDHHMM的日期和时间值。它们是格式为YYYYMMDDHHMM的日期和时间值yyyyMMddHHmm@RaghavAgarwal:但它表示一个日期/时间值,该值在您解析它的时区中根本没有出现。没有日期值可以返回,当使用相同的SimpleDataFormat重新格式化时,它将给出相同的字符串。@RaghavAgarwal:换句话说,您希望它返回什么?记住——你希望它在哪一刻回来?@RaghavAgarwal:这根本不能回答我的问题。这并不是说这个值代表的是什么瞬间,只是在重复问题中的代码。@RaghavAgarwal:我不清楚你是否读过我写的任何东西。你期望的毫秒数是多少?那将表示时间上的一瞬间。悉尼当地时间2017年10月1日凌晨2点,没有一个时刻是及时的。我想我们可以就此写一本书;答案不能延伸到这种情况。
Instant instant = Instant.now() ;  // Capture the current moment in UTC.
String output = Instant.now().toString() ;
Instant instant = Instant.parse( "2018-01-23T12:34:56.734591Z" )