Odd behavior during timezone conversion

I am trying to convert between a date printed out in an EST timezone into a date printed out in GMT/UTC

package com.stefano;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;


public class MainEntry {

/**
 * @param args
 * @throws ParseException 
 */


public static void main(String[] args) throws ParseException {


    String dateTime = "1307011200"; //12:00PM 01 July 2013
    System.out.println("Input -> " + dateTime);
    SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm");
    format.setTimeZone(TimeZone.getTimeZone("EST"));
    Date date = format.parse(dateTime);
    System.out.println("Intermediate -> " + date);
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    System.out.println("Output -> " + format.format(date));


    }

}

The output it gives is:

Input -> 1307011200
Intermediate -> Mon Jul 01 17:00:00 BST 2013
Output -> 1307011600

Even though the time difference between EST and GMT is always 5, it is somehow getting involved with BST.

I cannot use Joda-Time.

Answers


The javadoc of the SimpleDateFormat.parse(String) method refers to the parse(String, ParsePosition) method, that says:

This parsing operation uses the calendar to produce a Date. As a result, the calendar's date-time fields and the TimeZone value may have been overwritten, depending on subclass implementations. Any TimeZone value that has previously been set by a call to setTimeZone may need to be restored for further operations.

According to this you can't use this method to tell the SimpleDateFormat which timezone the given date is in. You can fix this method like this:

String dateTime = "1307011200"; // 12:00PM 01 July 2013
dateTime += " EST"; // append the timezone information to the input string
System.out.println("Input -> " + dateTime);
SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmm z"); // tell the formatter to look for the timezone info
Date date = format.parse(dateTime);
System.out.println("Intermediate -> " + date);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("Output -> " + format.format(date));

This will also print the Date object using your local timezone, but it shows a way to parse the dateTime string using a given timezone.


The answer by zovits is correct.

US East Coast Offset

If by EST you mean the east coast of the United States (and parts of Canada), then your statement the time difference between EST and GMT is always 5 is incorrect. With Daylight Saving Time (DST), the offset may be -05:00 or -04:00. Indeed, your specified date-time does have DST in effect.

Avoid 3-4 Letter Time Zone Codes

Those three or four letter time zone codes are neither standardized nor unique. Avoid them. Use proper time zone names, most of which are continent+city.

Comparison To Joda-Time

For comparison, here is some Joda-Time example code. The java.util.Date & .Calendar classes bundled with Java are so notoriously troublesome that every Java programmer should move to either Joda-Time or the new Java 8 java.time package (inspired by Joda-Time, defined by JSR 310).

While a java.util.Date seems to have a time zone but actually does not, note that a Joda-Time DateTime does truly know its own assigned time zone.

Joda-Time uses the ISO 8601 standard for its defaults. You can use other formats as well, as seen with the Montréal example below.

Example Code
String input = "1307011200"; //12:00PM 01 July 2013
DateTimeFormatter formatterSmooshed = DateTimeFormat.forPattern( "yyMMddHHmm" );
DateTimeZone timeZoneNewYork = DateTimeZone.forID( "America/New_York" );
DateTime dateTimeNewYork = formatterSmooshed.withZone( timeZoneNewYork ).parseDateTime( input );
DateTime dateTimeUtc = dateTimeNewYork.withZone( DateTimeZone.UTC );
String outputMontréal = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH ).print( dateTimeNewYork );
String outputSmooshed = formatterSmooshed.print( dateTimeNewYork ); // Expect same as input.

Dump to console…

System.out.println( "input: " + input );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "outputMontréal: " + outputMontréal );
System.out.println( "outputSmooshed: " + outputSmooshed );

When run…

input: 1307011200
dateTimeNewYork: 2013-07-01T12:00:00.000-04:00
dateTimeUtc: 2013-07-01T16:00:00.000Z
outputMontréal: lundi 1 juillet 2013 12 h 00 EDT
outputSmooshed: 1307011200

Need Your Help

List array of values from mongo collection

node.js mongoose

I am having a mongo document like this:

Issue with Bootstrap Modal and Select2 in Yii

php jquery twitter-bootstrap yii

I have posted this question on Yii developers forum as well but didn't get any reply so far, so I thought it worth to try to post the quietsion here.