34

在 Java 中,我想在 GMT 中获取当前时间。

我尝试了这样的各种选项:

Date date = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
date1 = calendar.getTime();

但是日期总是在我当地的时区解释。

我做错了什么,如何将 java Date 转换为 GMT?

4

12 回答 12

43

您在获取日期时在后端做了正确的事情,但没有任何迹象表明您没有采用 GMT 时间并根据您机器的当前语言环境对其进行格式化。

final Date currentTime = new Date();

final SimpleDateFormat sdf =
        new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");

// Give it to me in GMT time.
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + sdf.format(currentTime));

关键是使用你自己的 DateFormat,而不是系统提供的。这样,您可以将 DateFormat 的时区设置为您想要的,而不是将其设置为 Locale 的时区。

于 2011-03-08T17:34:59.570 回答
20

我想知道为什么没有人这样做:

Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));
Date date = time.getTime();

更新:由于 Java 8、9、10 及更高版本,Java 应该支持更好的替代方案。感谢您的评论@humanity

于 2013-11-28T09:16:11.067 回答
10

根据我的经验,Java 中捆绑的 Calendar 和 Date 类可能会产生不理想的效果。如果您不介意升级到 Java 8,请考虑使用ZonedDateTime

像这样:

ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );
于 2014-08-18T12:41:33.267 回答
9
于 2016-02-05T07:57:50.370 回答
3

要获得格林威治标准时间的毫秒时间,您只需要

long millis = System.currentTimeMillis();

你也可以做

long millis = new Date().getTime();

long millis = 
    Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis();

但这些都是进行相同呼叫的低效方式。

于 2012-10-23T10:13:56.710 回答
3

在尝试了很多方法后,我发现,要获得 GMT 的毫秒时间,您需要创建两个单独SimpleDateFormat的对象,一个用于在 GMT 中格式化,另一个用于解析。

这是代码:

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 format.setTimeZone(TimeZone.getTimeZone("UTC"));
 Date date = new Date();
 SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Date dateTime= dateParser.parse(format.format(date));
 long gmtMilliSeconds = dateTime.getTime();

这工作正常。:)

于 2015-07-10T11:16:30.150 回答
2

java.time您可以使用 Java 8包来实现它

在 Java 中获取当前 GMT 时间:

ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println("Print current time in GMT: "+zonedDateTime); // 2021-08-30T03:58:05.815942377Z

将 java.util.Date 转换为 GMT

// use a formatter
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss O");

Date date = new Date(); //; java.util.Date object
Instant instant = date.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneOffset.UTC);
System.out.println("java.util.Date to GMT: "+customFormatter.format(zonedDateTime)); // 08/30/2021 03:58:05 GMT

参考

于 2021-08-30T04:06:35.820 回答
1

你不能

首先,你在问不可能的事。一个老式的Date对象没有,因为不能有时区或 GMT 偏移量。

但是日期总是在我当地的时区解释。

我想你已经打印了Date或做了其他隐含地调用它的toString方法。我相信这是Date在您的时区中解释的唯一时间。更准确地说是在您的 JVM 的当前默认时区。另一方面,这是不可避免的。Date.toString() 确实以这种方式运行,它获取 JVM 的时区设置并使用它来呈现要返回的字符串。

你可以用 java.time

但是,您不应该使用 a Date。该课程设计不佳,幸运的是早已过时。此外,java.time(替代它的现代 Java 日期和时间 API)有一两个用于日期和时间的类,它们与 GMT 或 UTC偏移。我现在认为 GMT 和 UTC 是同义词,严格来说它们不是。

    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
    System.out.println("Time now in UTC (GMT) is " + now);

当我刚才运行这个片段时,输出是:

现在 UTC (GMT) 的时间是 2019-06-17T11:51:38.246188Z

输出的尾随Z表示 UTC。

链接

于 2019-06-17T11:53:55.490 回答
0

在 java 8 之后,您可能希望获得如下格式化时间:

DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));
于 2019-05-01T15:59:28.860 回答
0

这非常简单直接。

Date date = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
date = cal.getTime();

现在日期将包含当前的 GMT 时间。

于 2016-02-05T05:52:29.227 回答
0

以下代码将获得日期减去时区偏移量:

protected Date toGmt0(ZonedDateTime time) {
    ZonedDateTime gmt0 = time.minusSeconds(time.getOffset().getTotalSeconds());
    return Date.from(gmt0.toInstant());
}

@Test
public void test() {

    ZonedDateTime now = ZonedDateTime.now();
    Date dateAtSystemZone = Date.from(now.toInstant());
    Date dateAtGmt0 = toGmt0(now);

    SimpleDateFormat sdfWithoutZone = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    SimpleDateFormat sdfWithZoneGmt0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ITALIAN);
    sdfWithZoneGmt0.setTimeZone(TimeZone.getTimeZone("GMT"));

    System.out.println(""
            + "\ndateAtSystemZone          = " + dateAtSystemZone
            + "\ndateAtGmt0                = " + dateAtGmt0
            + "\ndiffInMillis              = " + (dateAtSystemZone.getTime() - dateAtGmt0.getTime())
            + "\n"
            + "\ndateWithSystemZone.format = " + sdfWithoutZone.format(dateAtSystemZone)
            + "\ndateAtGmt0.format         = " + sdfWithoutZone.format(dateAtGmt0)
            + "\n"
            + "\ndateFormatWithGmt0        = " + sdfWithZoneGmt0.format(dateAtSystemZone)
    );

输出 :

dateAtSystemZone          = Thu Apr 23 14:03:36 CST 2020
dateAtGmt0                = Thu Apr 23 06:03:36 CST 2020
diffInMillis              = 28800000

dateWithSystemZone.format = 2020-04-23 14:03:36.140
dateAtGmt0.format         = 2020-04-23 06:03:36.140

dateFormatWithGmt0        = 2020-04-23 06:03:36.140

我的系统是GMT+8,所以diffInMillis = 28800000 = 8 * 60 * 60 * 1000。</p>

于 2020-04-21T15:42:00.607 回答
0

以下有用的 Utils 方法可用于管理具有 DST 节省的 GMT 时间:

public static Date convertToGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() - tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() - tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}

public static Date convertFromGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() + tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() + tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}
于 2016-11-29T13:20:03.077 回答