views:

231

answers:

3

Hi! I'm receiving a datetime from a SOAP webservice without timzone information. Hence, the Axis deserializer assumes UTC. However, the datetime really is in Sydney time. I've solved the problem by substracting the timezone offset:

Calendar trade_date = trade.getTradeDateTime();
TimeZone est_tz = TimeZone.getTimeZone("Australia/Sydney");
long millis = trade_date.getTimeInMillis() - est_tz.getRawOffset();
trade_date.setTimeZone( est_tz );
trade_date.setTimeInMillis( millis );

However, I'm not sure if this solution also takes daylight saving into account. I think it should, because all operations are on UTC time. Any experiences with manipulating time in Java? Better ideas on how to solve this problem?

+2  A: 

I pity the fool who has to do dates in Java.

What you have done will almost certainly go wrong around the timezone. The best way to to it is probably to create a new Calendar object, set the Timezone on it, and then set all of the fields individually, so year, month, day, hour, minute, second, getting the values from the Date object.

Edit:
To keep the everyone happy, you should probably do this:

Calendar utcTime = Calendar.getInstance(getTimeZone("UTC"));
Calendar sydneyTime = Calendar.getInstance(getTimeZone("Australia/Sydney");
utcTime.setTime(trade_date);
for (i = 0; i < Calendar.FIELD_COUNT)
  sydneyTime.set(i, utcTime.get(i));

Then you won't be using any deprecated methods.

Paul Wagland
-1: For suggesting using deprecated methods of java.util.Date class
Alexander Pogrebnyak
probably: `newCalendar.set(oldCalendar.get(Calender.YEAR), oldCalendar.get(Calendar.MONTH),..., oldCalendar.get(Calendar.SECOND));`
wds
@Alexander Pogrebnyak : I have updated the answer so that users are not lead to the dark side ;-)
Paul Wagland
@Paul Wagland: downvote removed.
Alexander Pogrebnyak
+1  A: 

However, I'm not sure if this solution also takes daylight saving into account. I think it should, because all operations are on UTC time.

Yes, you should take the daylight saving into account, since it affects the offset to UTC.

Any experiences with manipulating time in Java? Better ideas on how to solve this problem?

JodaTime is a better time API. Maybe the following snippet could be of help :

DateTimeZone zone; // TODO : get zone
DateTime fixedTimestamp = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, zone);

JodaTime types are immutable which is also a benefit.

Timo Westkämper
Thanks for the link to JodaTime. However, I won't introduce a new third-party library for that project. But I will consider JodaTime the nex time.
Martin
A: 

Hi, I've decided to reparse the datetime string received with the correct time zone set. This should also consider daylight saving:

public class DateTest {

    private static SimpleDateFormat soapdatetime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

    /**
     * @param args
     */
    public static void main(String[] args) {
        TimeZone oztz = TimeZone.getTimeZone("Australia/Sydney");
        TimeZone gmtz = TimeZone.getTimeZone("GMT");
        Calendar datetime = Calendar.getInstance( gmtz );

        soapdatetime.setTimeZone( gmtz );
        String soap_datetime = soapdatetime.format( datetime.getTime() );
        System.out.println( soap_datetime );

        soapdatetime.setTimeZone( oztz );
        datetime.setTimeZone( oztz );
        try {
            datetime.setTime(
                    soapdatetime.parse( soap_datetime )
            );
        } catch (ParseException e) {
            e.printStackTrace();
        }

        soapdatetime.setTimeZone( gmtz );
        soap_datetime = soapdatetime.format( datetime.getTime() );
        System.out.println( soap_datetime );
    }
}
Martin