tl:博士
Instant.EPOCH
.toString()
1970-01-01T00:00:00Z
Date::toString
谎言
您已经了解了避免使用 java.util.Date/Calendar 类的众多原因之一:Date
实例没有时区信息,但它的toString
方法在呈现字符串以供显示时使用您的默认时区。令人困惑,因为它暗示 Date 有一个时区,而实际上它没有。
避免Date
/Calendar
您应该使用Joda-Time或 JSR 310 中的新 Java 8 类 java.time.* 而不是日期/日历。
java.time
使用Instant
类相当于Date
, UTC 时间轴上的时刻。
Instant.now()
对于纪元参考日期,使用常量。
Instant.EPOCH.toString()
1970-01-01T00:00:00Z
如果“忽略所有时间”是指您真的想要一个没有时间的仅日期值,请使用LocalDate
该类。
LocalDate.ofEpochDay( 0L )
1970-01-01
Joda-Time 示例
更新:Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time 类。
在 Joda-Time 中,DateTime 实例确实知道自己的时区。如果需要,您可以使用格式化程序在其他时区创建字符串输出。
这是针对Unix 时间 Epoch的代码,但使用的是 Joda-Time 2.3。
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" );
DateTime epochParis = new DateTime( 0L, timeZone_Paris );
DateTime epochUtc = new DateTime( 0L, DateTimeZone.UTC );
转储到控制台...</p>
System.out.println( "epochParis: " + epochParis );
System.out.println( "epochUtc: " + epochUtc );
运行时……</p>
epochParis: 1970-01-01T01:00:00.000+01:00
epochUtc: 1970-01-01T00:00:00.000Z
转换为 UTC/GMT
那么,我怎样才能强制使用 GMT,而忽略所有当地时间?
要使用UTC /GMT(无时区偏移),请执行以下任一操作:
- 将 DateTime 转换为具有不同时区的另一个实例
(Joda-Time 使事物不可变以保证线程安全,因此我们实际上并不转换,而是基于旧实例创建新实例。)
- 使用格式化程序创建为指定时区显示的字符串。
// To use UTC/GMT instead of local time zone, create new instance of DateTime.
DateTime nowInParis = new DateTime( timeZone_Paris );
DateTime nowInUtcGmt = nowInParis.toDateTime( DateTimeZone.UTC );
转储到控制台...</p>
System.out.println( "nowInParis: " + nowInParis );
System.out.println( "nowInUtcGmt: " + nowInUtcGmt );
运行时……</p>
nowInParis: 2013-12-22T08:40:01.443+01:00
nowInUtcGmt: 2013-12-22T07:40:01.443Z