Joshi的回答是正确但简短的。我会稍微扩展一下,并展示一个使用现代类的替代方法。
Date
没有时区
你的代码calendar.getTime()
从java.util.Calendar
对象中提取一个java.util.Date
对象。
java.util.Date
类有一个善意的但令人困惑的特性,即其toString
方法在生成字符串时应用JVM的当前默认时区。这会产生Date
类具有时区的错觉,但实际上它没有。一个Date
表示时间线上的一个瞬间,以自1970年UTC第一个时刻参考日期的毫秒计数为基础(1970-01-01T00:00:00Z
)。(更让人困惑的是,Date
类实际上确实有一个深藏不露且与本讨论无关的时区。)
避免使用过时的日期时间类
旧的日期时间类现在已经过时,被java.time类所取代。请只使用java.time类。
Instant
要表示UTC上的一个瞬间,相当于java.util.Date
,请使用Instant
类。Instant
类表示UTC时间轴上的一个瞬间,精确到纳秒(小数点后最多九位)。
Instant instant = Instant.now(); // Current moment in UTC.
ZonedDateTime
若要按照特定区域的壁钟时间查看相同时刻,请应用ZoneId
获取ZonedDateTime
。
请以continent/region
的格式指定正确的时区名称,例如America/Montreal
、Africa/Casablanca
或Pacific/Auckland
。请勿使用3-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,没有标准化,甚至不唯一(!)。
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );
在Stack Overflow上搜索此主题的许多其他问题和答案。这个问题实际上是其他许多问题的重复。
关于java.time
java.time框架内置于Java 8及以上版本。这些类替代了老旧的遗留日期时间类,例如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time项目现处于维护模式,建议迁移到java.time类。
要了解更多信息,请查看
Oracle教程。在Stack Overflow上搜索许多示例和解释。规范是
JSR 310。
在哪里获取java.time类?
这个
ThreeTen-Extra 项目扩展了 java.time 的附加类。该项目是 java.time 可能未来添加的地方。您可能会在这里找到一些有用的类,例如
Interval
、
YearWeek
、
YearQuarter
和
更多。