1

Much like LotR, TimeZone conversions in Java is quite a saga. My requirement is simple. The issue is around using milliseconds to create DateTime objects.

I need to be able to take a local time in milliseconds, then convert it to UTC in milliseconds and then convert it back to the same local time, all using milliseconds. I have got some of the way with JodaTime, but converting UTC milliseconds time back to the original local time in the example below has been the problem. Here is where I got up to:

public static final TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
public static final String DATETIME_REVERSE = "yyyy-MM-dd 'T' HH:mm:ss";

private void thereAndBackAgain() {

    long nowTimeNumber = 1585715400000L;
    DateTime nowDt = new DateTime(nowTimeNumber);
    DateTimeFormatter formatter = DateTimeFormat.forPattern(DATETIME_REVERSE);
    // Get local time
    Timber.e(" -- 1. Local Time :" + nowDt.getMillis() + " -> " + formatter.print(nowDt));

    // Convert Local to UTC
    DateTime utcTime = nowDt.withZone(DateTimeZone.UTC); // Convert to UTC.
    String utcTimeStr = formatter.print(utcTime);
    long utcOfLocalInMilli = formatter.parseDateTime(utcTimeStr).withZone(DateTimeZone.UTC).getMillis();
    Timber.e(" -- 2. UTC Time   :" + utcOfLocalInMilli + " -> " + formatter.print(utcTime));

    // Convert UTC back to Local
    DateTime utc2 = new DateTime(utcOfLocalInMilli, DateTimeZone.UTC);
    DateTimeFormatter formatter2 = DateTimeFormat.forPattern(DATETIME_REVERSE);
    String utc2str = formatter2.print(utc2);
    long localOfUtcInMillis = formatter2.parseDateTime(utc2str).withZone(DateTimeZone.getDefault()).getMillis();
    Timber.e("  -- 3. Local Time :" + localOfUtcInMillis + " -> " + utc2str);
}

The output is:

 -- 1. Local Time :1585715400000 -> 2020-04-01 T 15:30:00
 -- 2. UTC Time   :1585675800000 -> 2020-04-01 T 04:30:00
 -- 3. Local Time :1585636200000 -> 2020-03-31 T 17:30:00

The issue I'm having is that when I create utc2, JodaTime still assumes the milliseconds value is a local timezone, even though when I declare it with a UTC timezone. But I most likely have misunderstood the usage of this constructor.

Basically, I want to be able to take a time from any timezone, convert to UTC in milliseconds, and then convert it back to any other timezone. The millisecond value is required for a database key. This example merely takes a local time, and converts back to the same time, but ideally this is intended to convert from one time zone to another, whilst using a single millisecond time value and then adjusting for zone.

angryITguy
  • 9,332
  • 8
  • 54
  • 82

0 Answers0