Using Joda-Time to get UTC offset for a given date and timezone

北城余情 提交于 2019-12-03 10:37:20

Simple Method for Obtaining Timezone Name and Offset in Hours

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)"
}

Couple caveats:

  • This gets the default DateTimeZone from JodaTime. You can modify it to accept a specific DateTimeZone that is passed into the method.
  • This returns it in a format like "Mountain Standard Time (-7 Hours)" but you can format it as you see fit quite easily.

Hope that helps.

JP

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; 
sjgp

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();

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));
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!