5

我遵循这个问题:从 java.util.date 转换为 JodaTime

我有日期:Sun Jan 01 00:00:00 CET 1854 现在我想将其转换为 joda 日期时间:

DateTime dateTime = new DateTime(date);

现在当我打印这个日期时,我得到了:1853-12-31T23:57:44.000+00:57:44

出了什么问题,为什么我的日期改变了?我怎样才能得到相同的日期?

更新:

我使用日历获取日期:

Calendar cal1 = Calendar.getInstance();
cal1.set(1854, 0, 1, 0, 0, 0);
cal1.getTime()

更新2:

可能有毫秒问题:

    Calendar cal1 = Calendar.getInstance();
    cal1.set(1854, 0, 1, 0, 0, 0);
    DateTime start = new DateTime(1854, 1, 1, 0, 0, 0);
    System.out.println(start.getMillis());
    System.out.println(cal1.getTime().getTime());

因为这段代码返回:

-3660598664000
-3660598799438

但我不知道为什么

更新3:

在此处输入图像描述

4

5 回答 5

8

Joda-Time 使用准确的时区数据库,该数据库在时区开始之前有多年的本地平均时间 (LMT)。引用维基百科:

当地平均时是太阳时的一种形式,它修正当地视时的变化,在特定经度形成统一的时标。

JDK 不使用 LMT,因此时代不同。

于 2012-09-13T11:33:36.377 回答
4

好的,我解决了。不是很好,但重要的是它有效

  Calendar calendar = Calendar.getInstance();
    calendar.setTime(datum);

    DateTime current = new DateTime(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1,
            calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
于 2012-09-12T08:42:56.227 回答
0

如果您将日期作为 java.util.date 的类型,则可以使用

java.util.Date date = ....
DateTime dateTime = new DateTime(date.getTime());
于 2012-09-12T07:43:51.497 回答
0

这段代码

Calendar cal1 = Calendar.getInstance();
    cal1.set(1854, 0, 1, 0, 0, 0);
    DateTime start = new DateTime(cal1.getTime());
    System.out.println(start);
    System.out.println(cal1.getTime());

输出:

1854-01-01T00:00:00.941Z
Sun Jan 01 00:00:00 GMT 1854

我想毫秒差异是日历选择现在的saem时间,开始毫秒计数。而 joda-time 选择午夜。或者类似的钝器。我尽量远离java内置的日历和日期,它们是可憎的。

于 2012-09-12T08:13:06.530 回答
0

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-3660598800000java.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 分半钟)。

于 2016-05-21T23:15:50.077 回答