10

在英国,我想获得 UTC/GMT 的当前偏移量。目前偏移量是 1 小时,但似乎没有办法找到它。

代码

    TimeZone timeZone = TimeZone.getDefault();
    logger.debug("Timezone ID is '" + timeZone.getID() + "'");
    if (timeZone.getID().equals("GMT")) {
        timeZone = TimeZone.getTimeZone("Europe/London");
        logger.debug("New timezone is '" + timeZone.getID() + "'");
    }
    Long eventDateMillis = Long.parseLong(eventDateValue.getKeyValue());
    int timezoneOffset = timeZone.getOffset(eventDateMillis);
    logger.debug("Offset for " + eventDateValue + "(" + eventDateMillis + ") using timezone " + timeZone.getDisplayName() + " is " + timezoneOffset);

返回调试输出

Wed 2012/09/19 16:38:19.503|Debug|DataManagement|Timezone ID is 'GMT'
Wed 2012/09/19 16:38:19.503|Debug|DataManagement|New timezone is 'GMT'
Wed 2012/09/19 16:38:19.557|Debug|DataManagement|Offset for 18 Sep 2012 09:00(1347958800000) using timezone Greenwich Mean Time is 0

换句话说,时区“GMT”返回的偏移量为零,我找不到如何将其设置为确实返回正确偏移量的东西。

如果有人可以为 JodaTime 提供一个工作代码示例,那就可以了,但我真的很想避免仅仅为了应该是一个单行代码而安装一个单独的库。

Java版本是7。

4

5 回答 5

13

换句话说,时区“GMT”返回的偏移量为零,我找不到如何将其设置为确实返回正确偏移量的东西。

0GMT 的正确偏移量,永久。

您想要“欧洲/伦敦”,这是在 GMT 和 BST 之间切换的时区。

编辑:我最初并没有注意到您正在尝试获得欧洲/伦敦。看起来您的 JVM 使用的时区数据库基本上是一团糟。您可以尝试修复,也可以简单地使用带有自己的 tzdb 副本的 Joda Time。示例代码:

DateTimeZone zone = DateTimeZone.forID("Europe/London");
long offset = zone.getOffset(new Instant());
System.out.println(offset); // 3600000
于 2012-09-19T17:09:51.457 回答
1

我自己也遇到过这个。

我试过 TimeZone.getTimeZone("London"); 它奏效了。

不,我不知道为什么 - 'London' 不是 TimeZone 返回的 ID 之一......

于 2012-10-19T14:17:11.827 回答
1

java.time

java.time.ZonedDateTime旨在自动调整时区偏移。

演示:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        LocalTime time = LocalTime.of(10, 20);
        ZoneId zoneId = ZoneId.of("Europe/London");

        // A winter date-time
        ZonedDateTime zdtWinter = ZonedDateTime.of(LocalDate.of(2020, 11, 22), time, zoneId);
        System.out.println(zdtWinter);

        // A summer date-time
        ZonedDateTime zdtSummer = ZonedDateTime.of(LocalDate.of(2021, 07, 22), time, zoneId);
        System.out.println(zdtSummer);
    }
}

输出:

2020-11-22T10:20Z[Europe/London]
2021-07-22T10:20+01:00[Europe/London]

ONLINE DEMO

Z输出中的 是零时区偏移的时区指示符。它代表 Zulu 并指定Etc/UTC时区(时区偏移量为+00:00小时)。

java.util日期时间 API 及其格式化 API已SimpleDateFormat过时且容易出错。建议完全停止使用它们并切换到现代 Date-Time API *。但是,无论出于何种原因,如果您需要将 的对象转换为ZonedDateTime的对象java.util.Date,您可以执行以下操作:

Date date = Date.from(zdtSummer.toInstant());

从Trail: Date Time了解有关现代日期时间 API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

于 2021-07-23T18:51:58.253 回答
1

使用 timezone.getOffset(0),而不是 timezone.getOffset(eventDateMillis)。

这将为您提供截至格林威治标准时间 1970 年 1 月 1 日的偏移量,在欧洲/伦敦的情况下为 3600000,由于威尔士和北爱尔兰的历史问题而不是零。

于 2015-08-05T15:39:33.697 回答
0

这让我有了窍门:

String zone = "Europe/London";
int plusHoursGMT = TimeZone.getTimeZone(zone).getRawOffset() / 3600000;
assertThat(plusHoursGMT, is(0));
于 2016-11-21T17:51:02.770 回答