ZonedDateTime的字符串正在改变格式

String ip="2011-05-01T06:47:35.422-05:00"; ZonedDateTime mzt = ZonedDateTime.parse(ip).toInstant().atZone(ZoneOffset.UTC); System.out.println(mzt); System.out.println("-----"); String ip2="2011-05-01T00:00:00.000-05:00"; ZonedDateTime mzt2 = ZonedDateTime.parse(ip2).toInstant().atZone(ZoneOffset.UTC); System.out.println(mzt2); 

输出:

 2011-05-01T11:47:35.422Z ----- 2011-05-01T05:00Z 

为什么在案例2中更改日期格式? 由于这个原因,我收到SQLServer数据库错误。

这就是来自文档说的字符串

使用的格式将是最短的,输出省略的部分隐含为零的时间的完整值。

要解决此问题,您需要另一个格式化程序:

 String result = mzt2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'")); 

产量

 2011-05-01T11:47:35.422Z 2011-05-01T05:00:00:000Z 

只是为了补充YCF_L的答案:

在模式中使用带引号的字母,就像用Z做的那样(它在引号内: 'Z' )是错误的。 这会将Z视为文字并忽略对象的偏移量。

对于这种特殊情况 ,它可以工作,但最后的“Z”表示日期是UTC,你不能将其硬编码为文字。 将其放在引号内将始终打印“Z”,无论偏移是什么,都会给出错误的结果。

例:

 // wrong: it uses Z inside quotes DateTimeFormatter wrong = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSS'Z'"); // correct: it uses the offset pattern (X) DateTimeFormatter correct = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss:SSSXXX"); // print a date/time not in UTC String ip2 = "2011-05-01T00:00:00.000-05:00"; ZonedDateTime mzt = ZonedDateTime.parse(ip2); System.out.println(mzt.format(wrong)); // 2011-05-01T00:00:00:000Z System.out.println(mzt.format(correct)); // 2011-05-01T00:00:00:000-05:00 

请注意,错误的格式化程序打印Z,这是错误的,因为mzt的偏移量是-05:00

错误的格式化程序适用于您的情况,因为您使用的是UTC:

 // convert to UTC ZonedDateTime mzt2 = mzt.withZoneSameInstant(ZoneOffset.UTC); System.out.println(mzt2.format(wrong)); // 2011-05-01T05:00:00:000Z System.out.println(mzt2.format(correct)); // 2011-05-01T05:00:00:000Z 

在这种情况下,两个格式化程序都会输出正确的结果,但这是巧合 ,因为mzt2是UTC(所以偏移是“Z”)。 但对于任何不同于UTC的偏移量,只有正确的格式化程序才有效。

另请注意,我使用了withZoneSameInstant ,它与使用.toInstant().atZone(ZoneOffset.UTC)结果相同。