I have dates in the format 20Jan2013, 08Aug2012 etc, with their own specific timezones. So for example, 20Jan2013 might have a timezone ID of Australia/Melbourne, and 08Aug2
Java 8 introduced better Date and Time handling to address some of the language's previous limitations in that area. A few of my projects have started to use it rather than Joda.
Using the java.time package:
ZonedDateTime dateTime = LocalDate.of(2013 , 1 , 20).atStartOfDay( ZoneId.of("Australia/Melbourne"));
ZoneOffset zo = dateTime.getOffset();
int offset = zo.getTotalSeconds();
long hours = TimeUnit.SECONDS.toHours(offset);
long minutes = TimeUnit.SECONDS.toMinutes(offset % 3600);
The hours variable is set to 11 and the minutes to 0.
It also calculates the minutes-offset, for time zones that are partial hours, such as Newfoundland and Labrador in eastern Canada:
ZonedDateTime dateTime = LocalDate.of(2013, 1, 20).atStartOfDay( ZoneId.of("Canada/Newfoundland"));
In this case, the offset is -03:30
(three and a half hours behind UTC), hours
is -3 and minutes
is -30.
For the String representation, rather than the integer number of hours and minutes, use the ZoneOffset's toString() method. So for the example above, use:
String offsetString = zo.toString();
public static String getCurrentTimeZoneOffset() {
DateTimeZone tz = DateTimeZone.getDefault();
Long instant = DateTime.now().getMillis();
String name = tz.getName(instant);
long offsetInMilliseconds = tz.getOffset(instant);
long hours = TimeUnit.MILLISECONDS.toHours( offsetInMilliseconds );
String offset = Long.toString( hours );
return name + " (" + offset + " Hours)";
// Example: "Mountain Standard Time (-7 Hours)"
}
DateTimeZone
from JodaTime. You can modify it to accept a specific DateTimeZone that is passed into the method.Hope that helps.
JP
When you know offset and timestamp so in order to get current time you can use
public static String formatMonthDayMinuteByGivenUtcOffset(long timestamp, int offset) {
return JODA_FORMATTER.print(createDateTime(timestamp, offset));
}
If you just need the timezone offset, use DateTimeZone.forID()
to get the time zone and then tz.getOffset(instant)
to get the offset to UTC in milliseconds.
It may look odd that you need an instant to calculate the offset to UTC but this is necessary to take Daylight Savings into account as well as changes in the timezone. Yes, countries change their timezones once in a while:
Why does timezone data change?
Timezone settings are adopted locally, and there is no world timezone authority.
EDIT This gives you the correct result:
DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");
DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");
DateTime thisDate = dtf1.parseDateTime("30Jul2013").withZone(zone);
assertEquals( 10 * CommonConstants.MILLISECONDS_PER_HOUR,
zone.getOffset( thisDate ) );
thisDate.get
In order for Joda to give the correct offset, you must provide a datetime instant.Without a datetime instant, it is impossible to calculate the offset since we have different offsets(daylight savings). This is how I would use Joda to get offset in + HH:mm format :
int offsetInMillis = DateTimeZone.forID(zoneId).getOffset(new DateTime().getMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000),
Math.abs((offsetInMillis / 60000) % 60));
offset = (offsetInMillis >= 0 ? "+" : "-") + offset;