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.