我试图将日期格式从yyyy-MM-dd HH:mm:ss转换为ISO日期格式yyyy-MM-dd' H&H:mm:ss + 5:30,并通过下面的代码进行了测试,并且在eclipse上运行时工作正常,并且通过jar在部署到服务器时导致问题。
问题是日期(输入:2016-01-08 10:22:03)转换为2016-01-08T10:22:03Z而不是2016-01-08T10:22:03 5:30
注意:我使用的是Java 8。
以下是用于转换日期的代码,
SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
SimpleDateFormat inputDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String FinalDate = outputDate.format(inputDate.parse(pickupDate));
System.out.println(finalDate);
其他奇怪的经历是,在某些机器上,问题是不可重复的,并且在某些机器中存在问题。是机器还是JVM依赖的东西?请帮忙。
提前谢谢。
答案 0 :(得分:3)
正如SimpleDateFormat的文档:
对于格式化,如果GMT的偏移值为0,则产生“Z”。如果 模式字母的数量是1,一小时的任何一小部分 忽略。例如,如果模式为“X”且时区为 产生“GMT + 05:30”,“+ 05”。
所以我的猜测可能是检查服务器的时区。因为它认为输入日期的时区是GMT 0。
答案 1 :(得分:1)
如果使用Java 8或更高版本,您应该使用java.time类而不是那些出了名的麻烦的日期时间类java.util.Date/.Calendar。
您的输入字符串接近标准ISO 8601格式。在解析和生成日期时间值的文本表示时,java.time类默认使用这些标准格式。无需为此类标准输入定义编码解析模式。
要完全符合ISO 8601,请使用T
替换中间的SPACE。
String inputStandardized = "2016-01-08 10:22:03".replace( " " , "T" );
此字符串没有与UTC或时区的偏移,因此我们首先创建LocalDateTime
。
LocalDateTime localDateTime = LocalDateTime.parse( inputStandardized );
这些对象是关于日期时间的模糊概念,但实际上并不在时间轴上。要在时间轴上定义真实时刻,我们必须应用时区。
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = localDateTime.atZone( zoneId );
请注意,特定日期+时间在指定时区内可能无效; java.time根据需要进行调整。请务必阅读the documentation以了解调整行为。
ZonedDateTime
上的toString
方法默认情况下会生成所需格式的字符串,但扩展为将时区名称附加在方括号中。
String output = zdt.toString();
2016-01-08T10:22:03 + 05:30 [亚/加尔各答]
此扩展名包含时区名称非常有意义。时区不仅仅是与UTC的偏移,它还包括处理夏令时(DST)等异常的当前和历史规则。
如果您真的不想要附加的时区名称,根据我的建议,您可以使用已在java.time中定义的备用格式设置模式ISO_OFFSET_DATE_TIME
作为常量。
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME ;
String output = zdt.format( formatter );
2016-01-08T10:22:03 + 05:30
顺便说一下,您可以通过在UTC偏移小时内始终包含前导填充零来避免问题。因此,请使用问题中的+05:30
而不是+5:30
。