为什么程序会用不同的TimeZone
处理相同的输出/时间?
Calendar cal = GregorianCalendar.getInstance();
TimeZone timeZone_1 = TimeZone.getTimeZone("Asia/Rangoon");
cal.setTimeZone(timeZone_1);
System.out.println(cal.getTime());
TimeZone timeZone_2 = TimeZone.getTimeZone("Asia/Tokyo");
cal.setTimeZone(timeZone_2);
System.out.println(cal.getTime());
字符串
输出示例:
Thu Nov 22 09:00:33 MMT 2012
Thu Nov 22 09:00:33 MMT 2012
型
我的预期输出是:
Thu Nov 22 09:00:33 MMT 2012
Thu Nov 22 11:30:33 MMT 2012
型
2条答案
按热度按时间pkmbmrz71#
你的代码很好,只是调试输出有问题(误导)。
cal.getTime()
返回Date
对象,它与时区无关。但是Date.toString()
总是用系统的时区打印这个日期。Date.toString()
是如此违反直觉(它用系统时区显示日历时间,而它几乎不存储毫秒数),它应该被禁止/弃用。要获得准确的日志记录,请使用
SimpleDateFormat
或调用各种Calendar.get*()
方法:字符串
和往常一样,对于Java日期/时间处理的任何问题,请考虑jodatime.
mkh04yzy2#
tl;dr
字符串
java.util.Date#toString
说谎The Answer by Tomasz Nurkiewicz是正确的。您对
cal.getTime()
的调用将返回一个java.util.Date
对象,该对象的toString
方法属于您。该Date#toString
方法具有动态将当前默认时区应用于其值的反功能,该值实际上存储为UTC中的时刻(从UTC偏移0小时-分钟-秒)。这个反特性是避免使用
Date
和Calendar
类的原因之一。避免使用旧的日期时间类
您正在使用有严重缺陷的日期-时间类,这些类在几年前就被JSR 310中定义的现代 java.time 类所取代。
ZonedDateTime
要表示当前时刻,请使用
Instant
。你可以调整那个时刻,让它在一个特定的时区中被看到。应用一个
ZoneId
来生成一个[ZonedDateTime][2]
]对象。型
由变量
instant
、zdtRangoon
和zdtTokyo
引用的对象都表示非常相同的时刻,时间轴上的相同点-三个视图,一个时刻。调用
ZonedDateTime#toString
生成标准ISO 8601的文本,并明智地将时区名称附加在方括号中。型
请看这段代码run at Ideone.com。注意日期和时间的不同。
型
要获得本地化的输出,请使用
DateTimeFormatter.ofLocalizedDateTime
。搜索堆栈溢出以查找更多信息。