如何将java.util.date转换为JodaTime并获得相同的日期

时间:2012-09-12 07:37:38

标签: java datetime jodatime

我关注此问题:Convert from java.util.date to JodaTime

我有约会时间:太阳1月01日00:00:00 CET 1854 现在我想将它转换为joda datetime:

  

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()

UPDATE2:

可能存在milseconds问题:

    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

但我不知道为什么

UPDATE3:

enter image description here

5 个答案:

答案 0 :(得分:7)

Joda-Time使用准确的时区数据库,该数据库在时区开始前已有Local Mean Time (LMT)年。引用维基百科:

  

局部平均时间是太阳时的一种形式,它可以校正局部视在时间的变化,在特定的经度上形成统一的时间尺度。

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

答案 1 :(得分:3)

好的,我解决了。不是很好,但它的作用很重要

  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);

答案 2 :(得分:0)

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

java.util.Date date = ....
DateTime dateTime = new DateTime(date.getTime());

答案 3 :(得分: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内置的日历和日期,它们是令人厌恶的。

答案 4 :(得分:0)

Answer by JodaStephen是正确的,应该被接受。

Joda-Time团队已指示我们迁移到Java 8及更高版本中内置的java.time框架。所以我很想在java.time中尝试这个问题并比较结果。

问题表明输入数据是针对UTC的CET偏移量,但问题中的代码忽略了这一事实。我的下面的代码使用比UTC早一个小时的偏移量来计算CET

java.time

CET表示比UTC提前一小时。由于我们只有offset-from-UTC而不是full time zone,因此+01:00使用OffsetDateTime类。

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 );
  

dateTime:1854-01-01T00:00:00.000 + 01:00 |毫秒:-3660598800000

结果与java.time相同。

java.util.Calendar中

仅供比较。通常你应该避免旧的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 );
  

calendar: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 =假,过渡= 0,lastRule =空],Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 1854年,月= 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

不同的结果。这里我们在java.time和amp;中有-3660598799715-3660598800000。 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

在Joda-Time。只有第一行不同。

DateTimeZone zone = DateTimeZone.forID ( "Europe/Brussels" ); 
  

dateTime:1854-01-01T00:00:00.000 + 00:17:30 |毫秒:-3660596250000

在java.util.Calendar中。除TimeZone行之外的一些代码:

TimeZone zone = TimeZone.getTimeZone ( "Europe/Brussels" ); 
  

calendar:java.util.GregorianCalendar [time = -3660598799151,areFieldsSet = true,areAllFieldsSet = false,lenient = true,zone = sun.util.calendar.ZoneInfo [id =“Europe / Brussels”,offset = 3600000, dstSavings = 3600000,useDaylight =真,过渡= 184,lastRule = java.util.SimpleTimeZone中[ID =欧洲/布鲁塞尔,偏移= 3600000,dstSavings = 3600000,useDaylight =真,startYear = 0,STARTMODE = 2,startMonth = 2,朝九特派= -1,startDayOfWeek = 1,开始时间= 3600000,startTimeMode = 2,endMode = 2,endMonth = 9,endday指定= -1,一个endDayOfWeek = 1,结束时间= 3600000,endTimeMode = 2]],Firstdayofweek可= 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 1854年,月= 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分半)。