繁体   English   中英

如何在特定时区获取日期?

[英]How to get date in a specific timezone?

大家好 我正在使用以下方法获取 GMT 时区的当前时间

public static Timestamp getCurrentTimeGMT() {

        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        long time = c.getTimeInMillis();
        long offset = TimeZone.getDefault().getOffset(time);
        return new Timestamp(time - offset);

    }

但是当我尝试使用相同的方法并稍作更改以获取 GMT+3 中的当前时间时,它会给我与 GMT 相同的结果吗? 我不知道为什么:

public static Timestamp getCurrentTimeGMT3() {

    Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+3"));
    long time = c.getTimeInMillis();
    long offset = TimeZone.getDefault().getOffset(time);
    return new Timestamp(time - offset);

}

上面的代码为什么不能正常工作的任何想法,以及如何做这样的方法?

Timestamp扩展Date -它没有一个时区,从概念。 它只是代表时间的瞬间。

如果要在具有特定时区的特定日历中显示它,则是格式问题。 创建具有相关时区的适当日历,并在其中相应地设置时间戳。

(按照正常情况,我建议您在可能的情况下使用Joda Time而不是内置的API。它更加干净。)

为什么从最后一行的时间中减去偏移量? 这基本上是将您的时间重新设置为格林尼治标准时间。 您检索GMT + 3,然后减去3小时。

乔恩说了什么。 时间戳没有时区,始终为UTC,因此实际上不应滥用它来表示本地时间。 如果您确实需要对象来表示本地时间,那么Joda Time可以提供一个类

而且您应该意识到,“ GMT + 3”不是真正的有效时区。 时区不仅具有基本偏移量,而且还具有夏令时偏移量,该偏移量对于具有相同基本偏移量的时区可能会有所不同,甚至可能由于法规而在相同时区发生变化。 实时区域ID是“欧洲/柏林”或“澳大利亚/达尔文”。

c.getTimeInMillis()返回自1970年1月1日UTC以来的毫秒数,并且无论Calendar实例中使用哪个时区,都将返回相同的值。

如果您创建带有时区的日历并需要访问时间字段,则应直接访问以下字段:

int h = c.get(Calendar.HOUR_OF_DAY);
int m = c.get(Calendar.MINUTE);
int s = c.get(Calendar.SECOND);

使用时区静态方法。

TimeZone default = TimeZone.getDefault();

TimeZone.setDefault(TimeZone.getTimeZone("GMT+3"));
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(System.currentTimeMillis()));
Date date = cal.getTime(); // converted date time
System.out.println(date.toString());

// Set Back to System Default
TimeZone.setDefault(default);

示例代码以获取不同时区的时间

public class GetZoneDateTime {

public static void main(String[] args) throws Exception {
    String reqTzId = "Asia/Singapore";

    LocalDateTime now = LocalDateTime.now();
    System.out.println("Local Now: " + now + " TimeZone: " + TimeZone.getDefault());

    ZoneId zoneId = ZoneId.of(reqTzId);
    System.out.println("Req TimeZone : " + zoneId);

    LocalDateTime localNow = LocalDateTime.now(zoneId);
    System.out.println("tzLocalDateTime: " + localNow);

    ZonedDateTime zoneNow = ZonedDateTime.now(zoneId);
    System.out.println("tzZonedDateTime: " + zoneNow);
}

}

java.时间

2014 年 3 月, 现代日期时间 API取代了旧日期时间 API,从那时起强烈建议切换到java.time ,现代日期时间 API。

使用java.time的解决方案,现代日期时间 API:首先要了解的是timezonetimezone offset之间的区别。

时区由 ID 标识,通常采用地区/城市的形式,例如欧洲/伦敦。在这里您可以查看 tz 数据库时区列表。 java.time API 提供ZonedDateTime来表示带时区的日期时间。

时区偏移量告诉我们一个地方的时间与 UTC 的偏移量,例如 2011-12-03T10:15:30+01:00 告诉我们这个日期时间偏移了01:00小时从 UTC 即我们需要减去01:00小时以获得 UTC 的等效日期时间。 java.time API 提供了OffsetDateTime来表示带有时区偏移的日期时间。

一些时区遵守DST ,即 America/New_York 在冬季观察到-05:00时的偏移,而在夏季观察到-04:00时。 在这里你可以检查一个插图。

当我们创建具有固定偏移值的OffsetDateTime时, ZonedDateTime自动反映适用的偏移量。 因此,您问题中提到的GMTGMT+3不是时区,它们代表时区偏移。 一种更好更现代的写法分别是Z+03:00

演示:

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

class Main {
    public static void main(String[] args) {
        ZoneId zone = ZoneId.of("America/New_York");

        // Current date-time in America/New_York
        System.out.println(ZonedDateTime.now(zone));

        // A sample winter date-time in America/New_York
        System.out.println(ZonedDateTime.of(LocalDate.of(2023, 01, 14), LocalTime.of(10, 20, 30), zone));

        // A sample summer date-time in America/New_York
        System.out.println(ZonedDateTime.of(LocalDate.of(2023, 06, 14), LocalTime.of(10, 20, 30), zone));

        // Current OffsetDateTime with an offset of 00:00 hours (UTC time)
        System.out.println(OffsetDateTime.now(ZoneOffset.UTC));

        // Current OffsetDateTime with an offset of 05:30 hours
        OffsetDateTime odt = OffsetDateTime.now(ZoneOffset.of("+05:30"));
        System.out.println(odt);
        // The same OffsetDateTime converted to UTC time (will be 05:30 less)
        System.out.println(odt.withOffsetSameInstant(ZoneOffset.UTC));
    }
}

样本运行中的 Output:

2023-01-14T12:40:04.348474-05:00[America/New_York]
2023-01-14T10:20:30-05:00[America/New_York]
2023-06-14T10:20:30-04:00[America/New_York]
2023-01-14T17:40:04.352982Z
2023-01-14T23:10:04.353969+05:30
2023-01-14T17:40:04.353969Z

在线演示

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM