将 new Date() 转换为不同时区

问题描述 投票:0回答:3

如果我有:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"));

String dateStr = dateFormat.format(new Date());
System.out.println(dateStr);

当我的当地时间是2014-09-30 16:19:17时,输出将是:2014-09-30 14:19:17

我需要获取特定时区的Date类型,而不是String类型!

我的问题是,我怎样才能在“欧洲/伦敦”时区获得new Date()

java date datetime time timezone
3个回答
1
投票

你问:

我的问题是,我怎样才能在“欧洲/伦敦”时区获得

new Date()

你不能。

java.util.Date
类代表时间中的瞬间。它不与任何当地时区对齐。

在内部,它跟踪自 UTC 1970 年 1 月 1 日午夜以来的毫秒数。 当您使用时,可能会应用本地时区,但

Date
类本身不包含时区设置。


0
投票

使用日历,例如:

TimeZone timeZone= TimeZone.getTimeZone("Europe/London"));

Calendar cal = Calendar.getInstance(timeZone);

此外,日期的好处是它们不依赖于 TimeZone ,它只是自纪元(不久前的某个时间)以来以毫秒为单位的时间。您现在使用的方式实际上是正确的解决方案。


0
投票

正如 Matt Johnson-Pint 提到的

java.util.Date
不是真正的日期时间表示。因此,这个类的名称具有误导性;更好的名字应该是
EpochMillis
。从
java.util.Date
的对象了解不同时区的日期时间的唯一方法是使用指定时区设置的
SimpleDateFormat
,返回类型是
String

java.time

2014 年 3 月,Java 8 引入了现代的

java.time
日期时间 API,取代了容易出错的旧版
java.util
日期时间 API
。任何新代码都应使用
java.time
API。

使用现代日期时间 API 的解决方案

您可以使用

ZonedDateTime
。以下是其文档的摘录:

ISO-8601 日历系统中带有时区的日期时间,例如

2007-12-03T10:15:30+01:00 Europe/Paris

它最好的事情是它会根据 DST 自动调整区域偏移,即如果其 ZoneId 遵守 DST,则其区域偏移

变化
。我已经在下面的演示中展示了它。

注意:如果您想要一种保存带有固定区域偏移的日期时间的类型,例如

2007-12-03T10:15:30+01:00
,可以使用
OffsetDateTime

演示:

class Main {
    public static void main(String[] args) {
        // Using the default ZoneId set to your JVM i.e. it is the same as
        // ZonedDateTime.now(ZoneId.systemDefault())
        ZonedDateTime nowInDefaultZone = ZonedDateTime.now();
        System.out.println(nowInDefaultZone);

        // Using a specified ZoneId. Note: India does not observe DST
        ZonedDateTime nowInIndia = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        System.out.println(nowInIndia);

        // ZoneId.of("America/New_York") observes DST
        ZoneId zoneId = ZoneId.of("America/New_York");

        // A date-time in ZoneId.of("America/New_York") during DST
        ZonedDateTime zdtNyDuringDST = ZonedDateTime.of(
                LocalDate.of(2024, Month.DECEMBER, 20),
                LocalTime.MIN,
                zoneId);
        System.out.println(zdtNyDuringDST);

        // A date-time in ZoneId.of("America/New_York") outside DST period
        ZonedDateTime zdtNyOutsideDST = ZonedDateTime.of(
                LocalDate.of(2025, Month.MAY, 20),
                LocalTime.MIN,
                zoneId);
        System.out.println(zdtNyOutsideDST);
    }
}

在 UTC/GMT 在 JVM 上执行时的sample输出:

2024-12-20T13:34:15.009891Z[GMT]
2024-12-20T19:04:15.062966+05:30[Asia/Kolkata]
2024-12-20T00:00-05:00[America/New_York]
2025-05-20T00:00-04:00[America/New_York]

在线演示

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

© www.soinside.com 2019 - 2024. All rights reserved.