opfau
opfau

Reputation: 761

Convert DateTime to timezone, set time and convert back

I have a little utility method which converts a DateTime to a specific DateTimeZone, sets the time in that time zone and converts to another timezone again:

/**
 * Delivers a DateTime with changed time in the specified DateTimeZone.
 *
 * @param  dateTime      the date time to convert
 * @param  hour          the hour to set in the client timezone date time
 * @param  minute        the minute to set in the client timezone date time
 * @param  second        the second to set in the client timezone date time
 * @param  dtzConversion the client time zone
 * @param  dtzReturn     the time zone of the return date time (optionally: can be null)
 * @return the date time
 */
public DateTime convertDateTimeToTimeZone(final DateTime dateTime, final int hour, final int minute, final int second,
                                          final DateTimeZone dtzConversion, final DateTimeZone dtzReturn)
{
    // convert to given timezone        
    DateTime dtClientTimezone = dateTime.withZoneRetainFields(dtzConversion);
    // adjust time
    dtClientTimezone = dtClientTimezone.withTime(hour, minute, second, 0);

    if (dtzReturn != null) {
        // convert to target timezone
        dtClientTimezone = dtClientTimezone.withZoneRetainFields(dtzReturn);
    }

    return dtClientTimezone;
}

In my example dateTime is the german date 30.9.2015 22:00:00 UTC and dtzConversion is Europe/Berlin and dtzReturn is UTC with time to set 12:00:00 the result is 30.09.2015 12:00:00. But I would expect the 01.10.2015 10:00:00 because 30.09.2015 22:00:00 UTC to Europe/Berlin should be 01.10.2015 00:00:00. The the time is set to '12:00:00' which results in 01.10.2015 12:00:00. This in UTC is 01.10.2015 10:00:00. Where is my fault?

Upvotes: 3

Views: 886

Answers (1)

flo
flo

Reputation: 10281

The method withZoneRetainFields does not convert the fields values. Instead, it just changes the timezone (and the underlying milliseconds so that the fields have the same values in the new timezone as in the old one).

The method you are searching for is withZone, which adjusts the fields:

public static DateTime convertDateTimeToTimeZone(final DateTime dateTime, final int hour, final int minute,
        final int second,
        final DateTimeZone dtzConversion, final DateTimeZone dtzReturn)
{
    // convert to given timezone        
    DateTime dtClientTimezone = dateTime.withZone(dtzConversion);
    // adjust time
    dtClientTimezone = dtClientTimezone.withTime(hour, minute, second, 0);

    if (dtzReturn != null) {
        // convert to target timezone
        dtClientTimezone = dtClientTimezone.withZone(dtzReturn);
    }

    return dtClientTimezone;
}

public static void main(String[] args)
{
    DateTime parse = DateTime.parse("2015-09-30T22:00:00Z");
    DateTime convertDateTimeToTimeZone = convertDateTimeToTimeZone(parse, 12, 0, 0, DateTimeZone.forOffsetHours(2), DateTimeZone.UTC);
    System.out.println(convertDateTimeToTimeZone);
}

Result:

2015-10-01T10:00:00.000Z

Upvotes: 4

Related Questions