Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joda Time Interval between two dates including time zone

Tags:

jodatime

I use JodaTime library for time operations. I have two dates: Date One:

DateTime time_server = new DateTime(server_time_milisecs).
    withZone(DateTimeZone.forID("Europe/Zurich"));  //+0100

Shows: 2013-01-27 13:44:42

Date two:

DateTime time_local = new DateTime(DateTime.now()).
    withZone(DateTimeZone.getDefault());    //Have "Europe/Moscow" timezone  +0400

Shows: 2013-01-27 16:41:47

I need to find real interval including timezone

Interval interval = new Interval(time_local, time_server);
Long.toString(interval.toDurationMillis()));

Result: 174040 miliseconds - NOT CORRECT

int secs = Seconds.secondsBetween(time_local,time_server).getSeconds();

Result: 174 secs NOT CORRECT

Period period = new Period(time_local, time_server);
Integer.toString(period.getSeconds()) //**Wrong too**

Result must be: 10974 secs

like image 262
GeX Avatar asked Jan 27 '13 13:01

GeX


1 Answers

You should spend some time (no pun intended) to grasp the Jodatime concepts (eg) if you need to do time calculations involving different timezones.

For example, consider the following code

DateTime nowHere = DateTime.now();
DateTime nowZur = nowHere.withZone(DateTimeZone.forID("Europe/Zurich"));
System.out.println("now Here:   " + nowHere );
System.out.println("now Zurich: " + nowZur  );

This outputs (for me, 4 hours offset from Zurich) :

now Here:   2013-01-27T10:19:24.460-03:00
now Zurich: 2013-01-27T14:19:24.460+01:00

Pause and try to guess the output of the following lines:

Interval interv = new Interval(nowHere, nowZur);
System.out.println("Interval: " + interv.toDurationMillis());

The above prints 0 (zero). As it should.

Because nowHere and nowZur represent the same instant of time (in the physical line time), as represented in two different countries. They differ only in how they are represented, but physically they are the same time point (like 2.54 cm and 1 in are the same length, represented in two different forms).

Likewise, 2013-01-27T10:19:24.460-03:00 and 2013-01-27T14:19:24.460+01:00 are the same instant, the moment in which I run that code, only represented according the conventions of different countries; a martian could represent that same instant with his own martian calendar, and it would still be the same instant.

As those DateTimes represent the same time point, the physical interval (duration) between them must be zero. Now, if you want to get the "civil time difference" between the two, that's a wholly different thing. The LocalDateTime and the Period (totally different from DateTime and Duration) would then be the right concepts. For example:

Period per=new Period(nowHere.toLocalDateTime(),nowZur.toLocalDateTime());
System.out.println(per.toStandardSeconds().getSeconds());

This prints 14400 for me (4 "standard" -not physical- hours)

like image 98
leonbloy Avatar answered Sep 29 '22 18:09

leonbloy