JodaStephen的答案是正确的,应该被接受。
Joda-Time 团队已指示我们迁移到 Java 8 及更高版本中内置的 java.time 框架。所以我很想在 java.time 中尝试这个问题并比较结果。
问题说输入数据是CET
从 UTC 偏移的,但问题中的代码忽略了这一事实。我下面的代码使用 UTC 前一小时的偏移量来解释CET
.
java.time
这意味着比UTCCET
提前一小时。由于我们只有一个offset-from-UTC而不是full time zone,所以我使用类 for 。OffsetDateTime
+01:00
LocalDateTime localDateTime = LocalDateTime.of ( 1854 , 1 , 1 , 0 , 0 , 0 , 0 ); // The nineteenth century.
ZoneOffset offset = ZoneOffset.of ( "+01:00" ); // “CET” means one hour ahead of UTC.
OffsetDateTime odt = OffsetDateTime.of ( localDateTime , offset );
Instant instant = odt.toInstant (); // A moment on the timeline in UTC, with resolution in nanoseconds.
long m = instant.toEpochMilli ();
System.out.println ( "odt: " + odt + " | millis: " + m );
odt: 1854-01-01T00:00+01:00 | 毫:-3660598800000
乔达时间
相同的代码,但使用 Joda-Time 2.9.3。
DateTimeZone zone = DateTimeZone.forOffsetHoursMinutes ( 1 , 0 );
DateTime dateTime = new DateTime ( 1854 , 1 , 1 , 0 , 0 , zone );
long millis = dateTime.getMillis ();
System.out.println ( "dateTime: " + dateTime + " | millis: " + millis );
日期时间:1854-01-01T00:00:00.000+01:00 | 毫:-3660598800000
结果与 java.time 相同。
java.util.日历
仅供比较。通常您应该避免使用旧的 java.util.Date/.Calendar 类,因为它们已被证明设计不佳、令人困惑且麻烦。
Calendar calendar = Calendar.getInstance ();
calendar.set ( 1854 , 0 , 1 , 0 , 0 , 0 );
TimeZone zone = TimeZone.getTimeZone ( "GMT+01:00" );
calendar.setTimeZone ( zone );
long millis = calendar.getTimeInMillis ();
System.out.println ( "calendar: " + calendar + " | millis: " + millis );
日历:java.util.GregorianCalendar[time=-3660598799715,areFieldsSet=true,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+01:00",offset=3600000,dstSavings =0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1854,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR= 1,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=285,ZONE_OFFSET=3600000,DST_OFFSET=0] | 毫秒:-3660598799715
结果不同。在这里,我们-3660598799715
与-3660598800000
java.time 和 Joda-Time 相比,差异为285
.
Europe/Brussels
我还尝试了所有三个时区Europe/Brussels
而不是UTC偏移量。
在 java.time. 使用ZonedDateTime
类而不是OffsetDateTime
.
LocalDateTime localDateTime = LocalDateTime.of ( 1854 , 1 , 1 , 0 , 0 , 0 , 0 ); // The nineteenth century.
ZoneId zoneId = ZoneId.of ( "Europe/Brussels" );
ZonedDateTime zdt = ZonedDateTime.of ( localDateTime , zoneId );
Instant instant = zdt.toInstant (); // A moment on the timeline in UTC, with resolution in nanoseconds.
long m = instant.toEpochMilli ();
System.out.println ( "zdt: " + zdt + " | millis: " + m );
zdt: 1854-01-01T00:00+00:17:30[欧洲/布鲁塞尔] | 毫:-3660596250000
在乔达时代。只有第一行不同。
DateTimeZone zone = DateTimeZone.forID ( "Europe/Brussels" );
日期时间:1854-01-01T00:00:00.000+00:17:30 | 毫:-3660596250000
在 java.util.Calendar 中。TimeZone
除该行之外的一些代码:
TimeZone zone = TimeZone.getTimeZone ( "Europe/Brussels" );
日历:java.util.GregorianCalendar[time=-3660598799151,areFieldsSet=true,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Brussels",offset=3600000,dstSavings=3600000 ,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Brussels,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=- 1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA =1,YEAR=1854,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR=1,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0 ,SECOND=0,MILLISECOND=849,ZONE_OFFSET=3600000,DST_OFFSET=0] | 毫秒:-3660598799151
所有三个使用都Europe/Brussels
与他们的版本不同,偏移量为+01:00
.
再次 java.time 和 Joda-Time 彼此一致(-3660596250000
),而与Calendar
(-3660598799151
)不同,相差2,549,151
(大约 42 分半钟)。