I\'m trying to convert a long timestamp that is UTC to Eastern Standard Time and am totally lost. Any hints would be great!
Time format should be : 11/4/03 8:14 PM
You should not think in terms of converting a Date to a different timezone. Dates in Java are, and should always be, in UTC.
Rather, you can set a particular timezone when you want to format a Date. Here is an example:
public static void main(String[] args) throws Exception {
String tzid = "EST";
TimeZone tz = TimeZone.getTimeZone(tzid);
long utc = System.currentTimeMillis(); // supply your timestamp here
Date d = new Date(utc);
// timezone symbol (z) included in the format pattern for debug
DateFormat format = new SimpleDateFormat("yy/M/dd hh:mm a z");
// format date in default timezone
System.err.println(format.format(d));
// format date in target timezone
format.setTimeZone(tz);
System.err.println(format.format(d));
}
Output for me (my default timezone is GMT):
11/12/19 10:06 AM GMT
11/12/19 05:06 AM EST
Alternatively, you can set the timezone on a Calendar, and then access the Calendar fields you require. For example:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("EST"));
c.setTimeInMillis(utc);
System.err.printf("%d/%d/%d %d:%d %s\n", c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.HOUR), c.get(Calendar.MINUTE), (c.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM"));
(This does not give you the exact pattern you requested.)
Timezone conversion can be tricky. You should probably use Joda Time where timezone tables are constantly updated (and can be updated manually if needed
Using Joda time it is pretty easy:
public static Date convertJodaTimezone(LocalDateTime date, String localTimeZone, String destTimeZone) {
DateTime srcDateTime = date.toDateTime(DateTimeZone.forID(localTimeZone));
DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID(destTimeZone));
return dstDateTime.toLocalDateTime().toDateTime().toDate();
}
with timezones from the following table
Yesterday occasionally I wrote the following method that can help you:
private Date shiftTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
Calendar sourceCalendar = Calendar.getInstance();
sourceCalendar.setTime(date);
sourceCalendar.setTimeZone(sourceTimeZone);
Calendar targetCalendar = Calendar.getInstance();
for (int field : new int[] {Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND}) {
targetCalendar.set(field, sourceCalendar.get(field));
}
targetCalendar.setTimeZone(targetTimeZone);
return targetCalendar.getTime();
}
Now you just have to format the date. Use SimpleDateFormat for this. Here is the example:
DateFormat format = new SimpleDateFormat("dd/MM/yy hh:mm a");
format.format(date);
Under the hood Java keeps date value in UTC milliseconds so I think only way to shift value is by manipulating these millies e.g.
private void getShiftedDate(Date date, TimeZone targetZone) {
long sourceMillies = TimeUnit.MILLISECONDS.toMillis(TimeZone.getDefault().getRawOffset());
long targetMillies = TimeUnit.MILLISECONDS.toMillis(targetZone.getRawOffset());
long newMillies = date.getTime() + (targetMillies - sourceMillies);
Date shiftedDate = new Date(newMillies);
System.out.println("shifted => " + shiftedDate);
}
However, toString() of shiftedDate will still print default/source time zone string.