java - ZonedDateTime & LocalDateTime are different for 100 years ago -


the behaviour see strange - localdatetime equal zoneddatetime, other times differ 1 hour or 2 , it's 30 minutes. these strange differences depend on year subtract. can explain what's happening? tried jdk1.8.0_65 , jdk1.8.0_91, macos 10.11.5. work utc:

zoneoffset offset = zoneoffset.utc; 

here experiments. 1919 values may differ nano or milliseconds, expected:

assertequals(                        localdatetime.now(offset).minusyears(85).toinstant(offset),                      zoneddatetime.now().minusyears(85).withzonesameinstant(offset).toinstant()); 

for 1919 it's 1 hour difference:

assertequals(                    localdatetime.now(offset).minusyears(86).toinstant(offset),                       zoneddatetime.now().minusyears(86).withzonesameinstant(offset).toinstant());  expected :<1930-05-28t20:19:10.383z>  actual   :<1930-05-28t21:19:10.383z> 

for 1920 it's 2 hours difference:

assertequals(                       localdatetime.now(offset).minusyears(95).toinstant(offset),                         zoneddatetime.now().minusyears(95).withzonesameinstant(offset).toinstant());  expected :<1921-05-28t20:21:45.094z>  actual   :<1921-05-28t18:21:45.094z> 

for 1921 again milli or nano seconds difference:

assertequals(                         localdatetime.now(offset).minusyears(96).toinstant(offset),                       zoneddatetime.now().minusyears(96).withzonesameinstant(offset).toinstant()); 

and weirdest of - 1930 year 30 mins difference:

assertequals(                         localdatetime.now(offset).minusyears(97).toinstant(offset),                     zoneddatetime.now().minusyears(97).withzonesameinstant(offset).toinstant());  expected :<1919-05-28t20:24:27.345z>  actual   :<1919-05-28t19:53:08.346z> 

update

as @tunaki pointed had specify offset zoneddatetime:

assertequals(                      localdatetime.now(offset).minusyears(95).toinstant(offset),                       zoneddatetime.now(offset).minusyears(95).withzonesameinstant(offset).toinstant()); 

the problem doesn't know time zones: localdatetime.now(offset).minusyears(97).toinstant(offset). there offset present. knows time zone: zoneddatetime.now().minusyears(97).toinstant()

  • zoneid contains information place , time difference @ place. knows n years ago in particular time zone offset 2 hours, not 3 now.
  • zoneoffset keeps track hours/minutes shift. doesn't know history of time changes in particular country. "adds hours".

the suggested (and little bit incorrect) solution let zoneddatetime forget zones , use offset instead: zoneddatetime.now(offset).minusyears(97). agree localdatetime same offset - both show same incorrect information. agree since both "just add hours" instead of understanding time difference @ point of history place:

zoneoffset offset = zoneid.of("europe/moscow").getrules().getoffset(instant.now()); assertequals(     localdatetime.now(offset).minusyears(97).toinstant(offset),                zoneddatetime.now(offset).minusyears(97).toinstant()); 

alternatively can set localdatetime show correct value time place:

zoneddatetime zoned = zoneddatetime.now(zoneid.of("europe/moscow")).minusyears(97); zoneoffset offset = zoned.getoffset();//agrees history assertequals(         localdatetime.now().minusyears(97).toinstant(offset),         zoned.toinstant()); 

ps: shows zoneddatetime can work differently in different situations - knows time zones, other times "adds hours" localdatetime setting offset manually. me weird implementation. jodatime still best java implementation. @ least don't have learn several days understand it.


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -