Explaination of time format (Google Directions API) - java

I have read the documentation of the Google Directions API for making a direction request. An example of a URL is given as
http://maps.googleapis.com/maps/api/directions/json?origin=Brooklyn&destination=Queens&sensor=false&departure_time=1343605500&mode=transit
The value of the departure_time variable is supposed to reflect the following information:
July 30, 2012 at 09:45 am.
Can someone please explain this time format.
Thanks.

It's a timestamp - seconds elapsed since the Unix epoch, 1970-01-01 00:00:00 UTC. If you want "right now" in that format, you can use System.currentTimeMillis() / 1000, or if you have a Date object, you can use date.getTime() / 1000.

That's an epoch unix timestamp (number of seconds since Jan 1 1970). You can create a date by
Date d = new Date(1343605500L);
Or use http://www.epochconverter.com/

Flaw In Google Documentation
Googling for that particular number led to places such as this similar StackOverflow.com question. These pages lead me to conclude that the documentation for Google Directions API is flawed.
You and others report that the doc says 1343605500 = July 30, 2012 at 09:45 am in New York. But that is incorrect. Both the day of month and the hour of day are wrong.
1343605500 seconds from the beginning of the year 1970 UTC/GMT:
In New York is 2012-07-29T19:45:00.000-04:00
In UTC/GMT is 2012-07-29T23:45:00.000Z
Getting Date-Time From A Number
As the other answers stated, apparently Google is handing you the number of seconds since the Unix Epoch at the beginning of the year 1970 in UTC/GMT (no time zone offset).
Alternatively to using java.util.Date/Calendar classes, you can use the third-party open-source Joda-Time library.
Here is some example source code to show you how to parse the text into a date-time with time zone.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Starting data.
String string = "1343605500";
String timeZoneName = "America/New_York";
// Convert string of seconds to number of milliseconds.
long millis = Long.parseLong( string ) * 1000 ; //
// Specify time zone rather than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( timeZoneName );
// Instantiate DateTime object.
DateTime dateTime = new DateTime( millis, timeZone );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.toDateTime( DateTimeZone.UTC ) );
When run…
dateTime: 2012-07-29T19:45:00.000-04:00
dateTime in UTC/GMT: 2012-07-29T23:45:00.000Z
When using a count from epoch, you must be careful about:
Which epoch (Unix Time is but one of several possibilities)
Precision of count (seconds, milliseconds, nanoseconds)

Related

Create instance of joda DateTime from integer representing # of days since epoch?

In my application, it saves a preference which is an integer that is the number of days since the epoch. (not relevant but it is used to create backups every x days)
Given this value, how can I reliably create an instance of joda DateTime?
I'm tempted to convert it to milliseconds by doing the multiplication value * 24 * 60 * 60 * 1000 but this will be wrong due to astronomy / solar time?
Multiplying number of days into the number of milliseconds might be more readable if you use a library function. I highly recommend using Joda. :)
You have a number of days since epoch (GMT), and you want a DateTime (date + time + timezone). At a bare minimum, before you get further, you'll need to specify how you want to treat the time and timezone calculation.
The simplest way (which might not be what you intend) would be to create an instant in the local timezone representing the beginning of epoch, and then use plusDays to add the right number of days:
// in class - note that this will cache the current default timezone
private static final DateTime EPOCH_START_INSTANT = new DateTime(0);
// West of Greenwich, this will actually represent the "day" before.
// Day 0 will be Dec 31, 1969, local time.
DateTime localTime = EPOCH_START_INSTANT.plusDays(yourDayCount);
For the purpose of creating a backup every X days, you might instead want a LocalDate initialized at epoch (January 1, 1970), plus the number of days you want. That could then be changed to a specified local time relatively easily.
// in class
private static final EPOCH_LOCALDATE = new LocalDate(1970, 1, 1);
private static final THREE_AM = new LocalTime(3, 0);
LocalDate localDate = EPOCH_LOCALDATE.plusDays(yourDayCount);
// Midnight (or closest valid time thereto) in the default time zone
DateTime startOfDay = localDate.toDateTimeAtStartOfDay();
// 3 AM in the default time zone
DateTime threeAM = localDate.toDateTime(THREE_AM);
The answer by Jeff Bowman is correct.
I'll show the same idea in the java.time framework, intended to succeed Joda-Time.
java.time
Java 8 and later has the new java.time framework built-in. These new classes supplant the old java.util.Date/.Calendar classes. They are inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project.
I am assuming your count-of-day-from-epoch is in UTC. So we can use the Instant class, basically a count of nanoseconds from the first moment of 1970 in UTC.
long myCountOfDays = 16_721L;
Instant instant = Instant.EPOCH.plus ( myCountOfDays , ChronoUnit.DAYS );
Let's adjust into a time zone. Choosing Montreal arbitrarily. Use a proper time zone name, never the 3-4 letter codes like "EST" or "IST".
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
Dump to console.
System.out.println ( "myCountOfDays: " + myCountOfDays + " from epoch: " + Instant.EPOCH + " in UTC is: " + instant + " and in Montréal is: " + zdt + "." );
When run.
myCountOfDays: 16721 from epoch: 1970-01-01T00:00:00Z in UTC is: 2015-10-13T00:00:00Z and in Montréal is: 2015-10-12T20:00-04:00[America/Montreal].
According to the FAQ:
Joda-Time does not support leap seconds. Leap seconds can be supported by writing a new, specialized chronology, or by making a few enhancements to the existing ZonedChronology class. In either case, future versions of Joda-Time will not enable leap seconds by default. Most applications have no need for it, and it might have additional performance costs.
That suggests to me that you need not worry about that aspect.
But rather than doing the math, I would use DateTime#plusDays or MutableDateTime#addDays instead, using The Epoch as your starting point.
I assume, though, that your "days since The Epoch" is allowing for leap days (and that you're using the Gregorian chronology so JodaTime is, too).

how to add a (big)difference between to dates to another date

In a Jython script I want to move a date with the same amount an another date is changed. So in my script I get two variables:
scheduledDate and scheduledDate_previous
Both are java Date objects. I want to apply the difference to another Date: reservationDate
The problem is that with big differences, I get a 'cannot convert to integer'-error on the calendar.add() function. Here's my code:
from java.util import Date
form java.util import Calendar
myDiff = int(scheduledDate.getTime() - scheduledDate_previous.getTime())
reservationCal = Calendar.getInstance()
reservationCal.setTime(reservationDate)
reservationCal.add(Calendar.MILLISECOND, myDiff)
reservationDate = reservationCal.getTime()
If the difference between two dates becomes to large, the myDiff is no longer an Int, but a Big Int
(note that it can also be a negative number!)
So I tried something like this:
reservationCal.add(Calendar.MINUTE, int(myDiff / 60000) )
I don't need that insane presicion anyway. But this didn't work all the time. EDIT It would result in a 'add(): second arg cant be coerced to an int'-error Which seemed fair since if you had a weird difference the division could result in a float. So I tried this:
from java.lang import Math
reservationCal.add(Calendar.MINUTE, int(math.floor(myDiff / 60000)))
I still get an error like:
TypeError: unsupported operant type(s) for: 'java.math.BigInterger' and 'int'
The weird thing is that I don't get this error when I change the date a few days. It happens when I change it 3 months. User are able to change the date and time. They need to change it within a few years.
due to compatibility issues the machine is still on java 32 bit 1.6.0_25. It uses jython 2.5.2
Is there a solution or do I need different approuch?
My other answer correctly solves the direct problem raised in the Question. This answer is a bonus, an alternate avenue to accomplish the goal of calculating and applying elapsed time.
Doing this kind of date-time work is much easier if using either of these libraries:
Joda-Time
java.time package(built into Java 8, inspired by Joda-Time, defined by JSR 310)
The old date-time classes (java.util.Date, .Calendar, java.text.SimpleDateFormat) bundled with Java are notoriously troublesome, confusing, and flawed. Avoid them. If required you can convert to-and-fro with either library listed above.
Joda-Time
The code example below is using Joda-Time 2.5.
Elapsed Time
You can count elapsed time in either of two ways:
Calendar styleNumber of months, weeks, days, and such.
Stopwatch styleTotal number of milliseconds, as if measured with a running stopwatch.
These two ways to measure elapsed time may give different results! This code example shows both.
Time Zone
Unlike j.u.Date, a DateTime object in Joda-Time actually knows its own assigned time zone. That is crucial if you count elapsed time by the calendar style (months, days, and so on). Note how this example uses Montréal, Québec time zone (arbitrarily chosen).
Example Code
// Simulate inputs, a trio of java.util.Date objects.
java.util.Date dateStart = new DateTime( 2014 , 1 , 2 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
java.util.Date dateStop = new DateTime( 2014 , 3 , 2 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
java.util.Date dateTarget = new DateTime( 2014 , 7 , 1 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
// Convert inputs to Joda-Time
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Or DateTimeZone.UTC.
DateTime start = new DateTime( dateStart , timeZone );
DateTime stop = new DateTime( dateStop , timeZone );
DateTime target = new DateTime( dateTarget , timeZone );
// Determine elapsed time in three fashions: (a) pair of points on timeline, (b) An amount of weeks, days, hours, and such, and (c) actual milliseconds.
Interval interval = new Interval( start , stop );
Period period = interval.toPeriod();
Duration duration = interval.toDuration();
// Add elapsed time to target date-time. Show results of adding either period or duration.
DateTime laterByPeriod = target.plus( period );
DateTime laterByDuration = target.plus( duration );
Dump to console.
System.out.println( "dateStart: " + dateStart ); // BEWARE: j.u.Date objects are in UTC by definition, but "toString" method applies the JVM's current default time zone. Misleading!
System.out.println( "dateStop: " + dateStop );
System.out.println( "dateTarget: " + dateTarget );
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "target: " + target );
System.out.println( "interval: " + interval );
System.out.println( "period: " + period );
System.out.println( "duration: " + duration );
System.out.println( "laterByPeriod: " + laterByPeriod ); // Notice the change in offset because of DST (Daylight Saving Time) in Québec.
System.out.println( "laterByDuration: " + laterByDuration );
When run.
dateStart: Wed Jan 01 16:00:00 PST 2014
dateStop: Sat Mar 01 16:00:00 PST 2014
dateTarget: Mon Jun 30 17:00:00 PDT 2014
start: 2014-01-01T19:00:00.000-05:00
stop: 2014-03-01T19:00:00.000-05:00
target: 2014-06-30T20:00:00.000-04:00
interval: 2014-01-01T19:00:00.000-05:00/2014-03-01T19:00:00.000-05:00
period: P2M
duration: PT5097600S
laterByPeriod: 2014-08-30T20:00:00.000-04:00
laterByDuration: 2014-08-28T20:00:00.000-04:00
Use a long (64-bit integer) rather than an int (32-bit integer). As described in the Tutorial by Oracle.

Compensating for BST when calculating difference between 2 times

I need some help or a pointer in the right direction.
I am trying to get the difference between 2 times. I am in UK on GMT with timezone set to adjust for daylight saving automatically.
When I preform the following it is always 1 hour out unless, I switch off automatically adjust for daylight saving.
String strDate = new java.text.SimpleDateFormat("HH:mm:ss").format(new Date().getTime() - oldDate.getTime());
If I run the following there is not the 1 hour difference the 2.
System.out.println("Current time " + Formats.HOURMIN.formatValue(new Date().getTime()));
System.out.println("Old time " + Formats.HOURMIN.formatValue(oldDate.getTime()));
Any assistance would be appreciated.
The cardinal rule for calculating time intervals when different timezones are involved is to make sure to convert the times to UTC before subtracting.
Each time, no matter what zone and DST offset is in effect at the time (pun somewhat intended), converts to a unique UTC instant. Once you have the times in UTC, calculating the difference is a simple subtraction. The result is time-zone-independent.
The java.util.Date class has no time zone attached to it yet confusingly uses your default time zone when rendering a string. I'm guessing this may be your problem. One of many reasons to avoid java.util.Date/Calendar classes.
The Joda-Time 2.3 library makes this kind of work easier. Look at the Period, Duration, and Interval classes.
In contrast to a java.util.Date, in Joda-Time a DateTime instance does indeed know its assigned time zone.
The ISO 8601 standard defines a way to describe durations as hours, minutes, and such in a PnYnMnDTnHnMnS format. I use that in my example code below. Joda-Time offers other ways as well.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTimeZone timeZone = DateTimeZone.forID( "Europe/London" );
DateTime dateTimeNew = new DateTime( timeZone );
DateTime dateTimeOld = dateTimeNew.minusHours( 2 );
Period period = new Period( dateTimeOld, dateTimeNew );
Dump to console…
System.out.println( "dateTimeNew: " + dateTimeNew );
System.out.println( "dateTimeOld: " + dateTimeOld );
System.out.println( "period: " + period );
When run…
dateTimeNew: 2014-01-02T23:19:45.021Z
dateTimeOld: 2014-01-02T21:19:45.021Z
period: PT2H

Java and Joda-Time: date wrong value

I'm getting a wrong date in Joda-Time when I try to parse a string date like this:
2013-11-20 18:20:00 +01:00
I'm expecting to obtain the following date:
Wed Nov 20 19:20:00 CET 2013
but I'm getting:
Wed Nov 20 18:20:00 CET 2013
I'm using Joda-Time and this is my code:
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
DateTime temp = formatter.parseDateTime(dateString);
Date date = temp.toDate();
Expectations
Your expectation is wrong.
The "+01:00" means that time is one hour ahead of UTC/GMT. So, adjusting to UTC means subtracting an hour (17:20) rather than adding (19:20).
The "+01:00" has the same effect as saying CET (Central European Time), meaning one hour ahead of UTC/GMT. So…
2013-11-20 18:20:00 +01:00 = Wed Nov 20 18:20:00 CET 2013
…those are two different ways of stating the same time, same hour.
When I run your code here in United States west coast time, I get… (note the same hours)
temp: 2013-11-20T09:20:00.000-08:00
date: Wed Nov 20 09:20:00 PST 2013
j.u.Date Confusion
As the answer by Stroboskop said, you may be fooled by java.util.Date. The object itself does not have time zone information. Yet it's implementation of the toString() method uses the default time zone in rendering the text to be displayed. Confusing. One of many reasons to avoid using the java.util.Date/Calendar classes. In contrast, Joda-Time DateTime objects do indeed know their own time zone.
Specify Time Zone
Your real problem is an all too common one: Ignoring time zones. By not specifying a time zone, your default time zone was used. As you can see above, my default time zone is different than yours, so I got different results while running the same code.
A better practice is to always specify your time zone. If you want UTC/GMT, say so. If you want CET, say so. (Actually, don't use the three-letter code like CET as they are not standardized and have duplicates – use a time zone name such as Europe/Prague or Europe/Paris.) When parsing that string, specify the time zone to be incorporated within the new DateTime object.
Example Code
Here is some example code showing how to specify the time zone while parsing. Note the call to withZone().
Note that the result of all three parsings is the same moment in the time line of the Universe. To make that point, my code dumps to the console the milliseconds since the Unix Epoch backing each DateTime object. Usually I try to not use nor think about the milliseconds-since-epoch. But here the use of milliseconds-since-epoch proves a point.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
// Time Zone list… http://joda-time.sourceforge.net/timezones.html (not quite up-to-date, read page for details)
DateTime dateTimeInUtc = formatter.withZone( DateTimeZone.UTC ).parseDateTime( dateString );
DateTime dateTimeInPrague = formatter.withZone( DateTimeZone.forID( "Europe/Prague" ) ).parseDateTime(dateString);
DateTime dateTimeInVancouver = formatter.withZone( DateTimeZone.forID( "America/Vancouver" ) ).parseDateTime(dateString);
Dump to console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc + " … In Milliseconds since Unix Epoch: " + dateTimeInUtc.getMillis() );
System.out.println( "dateTimeInPrague: " + dateTimeInPrague + " … In Milliseconds since Unix Epoch: " + dateTimeInPrague.getMillis() );
System.out.println( "dateTimeInVancouver: " + dateTimeInVancouver + " … In Milliseconds since Unix Epoch: " + dateTimeInVancouver.getMillis() );
When run… (Note that whether this code runs on your computer or mine, we both get the same results!)
dateTimeInUtc: 2013-11-20T17:20:00.000Z … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInPrague: 2013-11-20T18:20:00.000+01:00 … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInVancouver: 2013-11-20T09:20:00.000-08:00 … In Milliseconds since Unix Epoch: 1384968000000
Standard question: what time zone are you in? CET?
I assume the parsed DateTime is correct? What timezone does it have?
Bear in mind that Date doesn't have timezones. I'm not even sure if it actually considers Timezone.getDefault().
So, in short it looks like you have a timezone different from +1 and that's why your time is moved by one hour.
-- edit --
hold on. why do you even expect 19:20? The text says 18:20 +1, Joda parses this just like that and Date drops the timezone. That's it.

Joda-Time, Daylight Saving Time change and date time parsing

I have the following problem using Joda-Time for parsing and producing date and time around Daylight Saving Time (DST) hours. Here is an example (please, note that March 30th 2008 is Daylight Saving change in Italy):
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime x = dtf.parseDateTime("30/03/2008 03:00:00");
int h = x.getHourOfDay();
System.out.println(h);
System.out.println(x.toString("dd/MM/yyyy HH:mm:ss"));
DateTime y = x.toDateMidnight().toDateTime().plusHours(h);
System.out.println(y.getHourOfDay());
System.out.println(y.toString("dd/MM/yyyy HH:mm:ss"));
I get the following output:
3
30/03/2008 03:00:00
4
30/03/2008 04:00:00
When i parse hour I get hour is 3. In my data structure I save the day storing midnight time, and then I have some value for each hour of the day (0-23). Then, when I write out the date, I re-compute the full date time making midnight plus hour. When I sum 3 hours to my midnight I get 04:00:00! And if I parse it again, I get hour 4!
Where is my mistake? Is there some way to get hour 2 when I parse or get hour three when I print out?
I have also tried to build output by hand:
String.format("%s %02d:00:00", date.toString("dd/MM/yyyy"), h);
but in this case for hour 2, I produce 30/03/2008 02:00:00 which is not a valid date (since hour 2 does not exist) and cannot be parsed any more.
Thank you in advance for your help.
Filippo
When I sum 3 hours to my midnight I get 04:00:00! And if I parse it again, I get hour 4! Where is my mistake?
You mentioned already that this date is exactly when the time changes. So there is no mistake. March 30, 2010 00:00 CEST (the timezone in Italy) is precisely speaking March 29, 2010 23:00 UTC. When you add 3 hours, you will get March 30, 2010 02:00 UTC. But this is post the moment, that we switch times (which happens on 01:00 UTC), so when you convert time to local timezone you get March 30, 04:00. That's correct behavior.
Is there some way to get hour 2 when I parse or get hour three when I print out?
No, because March 30, 2010 02:00 CEST does not exist. Precisely at March 30, 2010 01:00 UTC we switch time from +1 hour to +2 hours versus UTC, so March 30, 2010 00:59 UTC is March 30, 2010: 01:59 CEST, but March 30, 2010 01:00 UTC become March 30, 2010 03:00 CEST. No 02:xx hour exist on that particular date.
BTW. In a week you can expect another "fun". Can you tell what date in UTC this refers to:
October 31, 2010 02:15 CEST ?
Well, the funny part is, we do not know. It could be either 0ctober 31, 2010 00:15 UTC (before actual time switch) or October 31, 2010 01:15 UTC (after the switch).
That's exactly why you should always store date and times in relation to UTC and convert them to local time zone before displaying, otherwise you risk an ambiguity.
HTH.
The data structure you are saving your data is not very optimal for the days with daylight saving time. Your day in this particular day should only have 23 hours.
If you do:
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss").withLocale(Locale.US);
DateTime x = dtf.parseDateTime("30/03/2008 00:00:00");
DateTimeFormatter parser = DateTimeFormat.fullDateTime();
System.out.println("Start:"+parser.print(x));
DateTime y = x.plusHours(4);
System.out.println("After add of 4:"+parser.print(y));
You get the expected result, that the time is 05:00.
I recommend that you change the way you store your day and use a date. If not, you must handle daylight saving time when storing the hour of day.
You might do something like this:
In the case where we move the time forward one hour, as this case, you must store 4 and not 5 as the time for 5. And when you calculate the time, you should use the plusHours() method to get the actual time. I think you might get away with something like:
public class DateTest {
private static final int HOUR_TO_TEST = 2;
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime startOfDay = dtf.parseDateTime("30/03/2008 00:00:00");
/* Obtained from new DateTime() in code in practice */
DateTime actualTimeWhenStoring = startOfDay.plusHours(HOUR_TO_TEST);
int hourOfDay = actualTimeWhenStoring.getHourOfDay();
int hourOffset = startOfDay.plusHours(hourOfDay).getHourOfDay();
System.out.println("Hour of day:" + hourOfDay);
System.out.println("Offset hour:" + hourOffset);
int timeToSave = hourOfDay;
if (hourOffset != hourOfDay) {
timeToSave = (hourOfDay + (hourOfDay - hourOffset));
}
System.out.println("Time to save:" + timeToSave);
/* When obtaining from db: */
DateTime recalculatedTime = startOfDay.plusHours(timeToSave);
System.out.println("Hour of time 'read' from db:" + recalculatedTime.getHourOfDay());
}
}
...or basicly something like that. I'd write a test for it if you choose for going down this route. You can change the HOUR_TO_TEST to see that it moves passed the daylight saving time.
Building on the correct answers by Paweł Dyda & Knubo…
ISO 8601 For String Format
You should never store (serialize) a date-time as a string in the format you mentioned: "30/03/2008 03:00:00". Problems:
Omitted time zone.
Day, Month, Year order is ambiguous.
Should have been translated to UTC time.
If you must serialize a date-time value to text, use a reliable format. The obvious choice is the ISO 8601 standard format. Even better is converting the local time to UTC (Zulu) time zone and then out to ISO 8601 format. Like this: 2013-11-01T04:48:53.044Z
No Midnight
The midnight methods in Joda-Time are deprecated in favor of the Joda-Time method withTimeAtStartOfDay() (see doc). Some days do not have a midnight.
Example Code in Joda-Time 2.3
Some comments about this source code:
// © 2013 Basil Bourque. This source code may be used freely forevery by anyone taking full responsibility for doing so.
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
Example showing 23 hours in the day of DST (Daylight Saving Time) in Rome Italy, while the day after has 24 hours. Note that the time zone (for Rome) is specified.
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
org.joda.time.DateTimeZone romeTimeZone = org.joda.time.DateTimeZone.forID("Europe/Rome");
org.joda.time.DateTime dayOfDstChange = new org.joda.time.DateTime( 2008, 3, 30, 0, 0, romeTimeZone ) ; // Day when DST
org.joda.time.DateTime dayAfter = dayOfDstChange.plusDays(1);
// How many hours in this day? Should be 23 rather than 24 on day of Daylight Saving Time "springing ahead" to lose one hour.
org.joda.time.Hours hoursObjectForDay = org.joda.time.Hours.hoursBetween(dayOfDstChange.withTimeAtStartOfDay(), dayAfter.withTimeAtStartOfDay());
System.out.println( "Expect 23 hours, got: " + hoursObjectForDay.getHours() ); // Extract an int from object.
// What time is 3 hours after midnight on day of DST change?
org.joda.time.DateTime threeHoursAfterMidnightOnDayOfDst = dayOfDstChange.withTimeAtStartOfDay().plusHours(3);
System.out.println( "Expect 4 AM (04:00) for threeHoursAfterMidnightOnDayOfDst: " + threeHoursAfterMidnightOnDayOfDst );
// What time is 3 hours after midnight on day _after_ DST change?
org.joda.time.DateTime threeHoursAfterMidnightOnDayAfterDst = dayAfter.withTimeAtStartOfDay().plusHours(3);
System.out.println( "Expect 3 AM (03:00) for threeHoursAfterMidnightOnDayAfterDst: " + threeHoursAfterMidnightOnDayAfterDst );
Example of storing a date-time by first translating to UTC. Then upon restoring the date-time object, adjust to the desired time zone.
// Serialize DateTime object to text.
org.joda.time.DateTimeZone romeTimeZone = org.joda.time.DateTimeZone.forID("Europe/Rome");
org.joda.time.DateTime dayOfDstChangeAtThreeHoursAfterMidnight = new org.joda.time.DateTime( 2008, 3, 30, 0, 0, romeTimeZone ).withTimeAtStartOfDay().plusHours(3);
System.out.println("dayOfDstChangeAtThreeHoursAfterMidnight: " + dayOfDstChangeAtThreeHoursAfterMidnight);
// Usually best to first change to UTC (Zulu) time when serializing.
String dateTimeSerialized = dayOfDstChangeAtThreeHoursAfterMidnight.toDateTime( org.joda.time.DateTimeZone.UTC ).toString();
System.out.println( "dateTimeBeingSerialized: " + dateTimeSerialized );
// Restore
org.joda.time.DateTime restoredDateTime = org.joda.time.DateTime.parse( dateTimeSerialized );
System.out.println( "restoredDateTime: " + restoredDateTime );
// Adjust to Rome Italy time zone.
org.joda.time.DateTime restoredDateTimeAdjustedToRomeItaly = restoredDateTime.toDateTime(romeTimeZone);
System.out.println( "restoredDateTimeAdjustedToRomeItaly: " + restoredDateTimeAdjustedToRomeItaly );
When run:
dayOfDstChangeAtThreeHoursAfterMidnight: 2008-03-30T04:00:00.000+02:00
dateTimeBeingSerialized: 2008-03-30T02:00:00.000Z
restoredDateTime: 2008-03-30T02:00:00.000Z
restoredDateTimeAdjustedToRomeItaly: 2008-03-30T04:00:00.000+02:00

Categories

Resources