使用Joda-Time获取给定日期和时区的UTC偏移量

时间:2013-01-30 11:11:58

标签: java timezone jodatime utc

我的日期格式为20Jan2013,08Aug2012等,具有自己的特定时区。例如,20Jan2013可能具有澳大利亚/墨尔本的时区ID,而08Aug2012可能具有欧洲/伦敦的ID。我想要做的是,根据这些时区和日期,计算给定日期该时区的UTC偏移量。到目前为止我已经想出了这个:

DateTimeFormatter dtf = DateTimeFormat.forPattern("ZZ");
DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY");

DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne");  

DateTime thisDate = dtf1.parseDateTime("30Jul2013");                                            
System.out.println("\nZone: " + thisDate.withZone(zone));

这给了我输出:

Zone: 2013-07-30T00:00:00.000+10:00

这是正确的,但我想从中提取UTC偏移量,在这种情况下是+10:00。我已经找到了办法,但找不到任何东西。有什么方法可以做到这一点吗?我看到的唯一选择是将输出转换为String并使用substring方法获取UTC偏移量。

以上代码确实考虑了夏令时(夏令时)。例如,如果我有: DateTime thisDate = dtf1.parseDateTime(“30Jan2013”​​);

输出将是:2013-01-30T00:00:00.000 + 11:00

(+ 11:00而不是+10:00)

所以基本上我需要做的就是找到一种从2013-07-30T00:00:00.000 + 11:00提取+11:00的方法。请帮忙!

5 个答案:

答案 0 :(得分:11)

获取时区名称和偏移量的简单方法

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

情侣警告:

  • JodaTime 获取默认DateTimeZone。您可以修改它以接受传递给方法的特定DateTimeZone。
  • 以“山地标准时间(-7小时)”的格式返回,但您可以根据需要轻松格式化。

希望有所帮助。

JP

答案 1 :(得分:3)

如果您只需要时区偏移量,请使用DateTimeZone.forID()获取时区,然后使用tz.getOffset(instant)获取UTC的偏移量(以毫秒为单位)。

您需要立即计算到UTC的偏移量,这可能看起来很奇怪,但这需要考虑夏令时以及时区的变化。是的,各国偶尔会更改时区:

  

Why does timezone data change?

     

时区设置在本地采用,并且没有世界时区权限。

编辑这会为您提供正确的结果:

    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

答案 2 :(得分:3)

为了让Joda给出正确的偏移量,您必须提供一个日期时间瞬间。没有日期时刻,由于我们有不同的偏移(夏令时),因此无法计算偏移量。这就是我如何使用Joda来获得+ HH:mm格式的偏移:

    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; 

答案 3 :(得分:1)

Java 8 introduced better Date and Time handling,以解决该领域以前的一些语言限制。我的一些项目已经开始使用它而不是Joda。

使用java.time包:

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

小时变量设置为11,分钟设置为0。

它还为部分小时的时区计算分钟偏移量,例如加拿大东部的纽芬兰和拉布拉多:

ZonedDateTime dateTime = LocalDate.of(2013, 1, 20).atStartOfDay( ZoneId.of("Canada/Newfoundland"));

在这种情况下,偏移量为-03:30(比UTC晚三个半小时),hours为-3,minutes为-30。

对于String表示,而不是整数小时和分钟,请使用ZoneOffset的toString()方法。因此,对于上面的示例,请使用:

String offsetString = zo.toString();

答案 4 :(得分:0)

当您知道偏移量和时间戳时,为了获得当前时间,您可以使用

 public static String formatMonthDayMinuteByGivenUtcOffset(long timestamp, int offset) {
        return JODA_FORMATTER.print(createDateTime(timestamp, offset));
    }