用Java获取GMT时间

时间:2011-03-08 17:28:21

标签: java date gmt

在Java中,我想获得格林尼治标准时间的当前时间。

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

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

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

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

11 个答案:

答案 0 :(得分:32)

在获得日期时你在后端做了正确的事情,但是没有任何迹象表明你没有按照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的时区。

答案 1 :(得分:18)

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

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

更新: 从Java 8,9,10及更多版本开始,Java应该有更好的替代方案。感谢您对@humanity的评论

答案 2 :(得分:6)

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

像这样:

ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );

答案 3 :(得分:5)

TL;博士

Instant.now()

java.time

建议您使用Java 8及更高版本中内置的java.time框架时,Answer by Damilola是正确的。但是,如果您只想要UTC而不是任何特定的时区,那么该答案会使用ZonedDateTime类,这是一种过度杀伤力。

麻烦的旧日期时间类现在已经遗留下来,取而代之的是java.time类。

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

简单代码:

Instant instant = Instant.now() ;
  

instant.toString():2016-11-29T23:18:14.604Z

您可以将Instant视为可以添加时区(ZoneID)的构建基块,以获得ZonedDateTime

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 4 :(得分:3)

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

long millis = System.currentTimeMillis();

您也可以

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

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

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

答案 5 :(得分:2)

在尝试了很多方法后,我发现,为了在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();

这很好用。 :)

答案 6 :(得分:1)

你不能

首先,您要问不可能的事情。没有老式的Date对象,因为不能具有时区或GMT偏移量。

  

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

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

您可以使用java.time

不过,您不应使用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。

链接

答案 7 :(得分:0)

这非常简单直接。

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

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

答案 8 :(得分: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;
}

答案 9 :(得分:0)

在Java 8之后,您可能需要获取如下格式的时间:

DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));

答案 10 :(得分: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

我的系统位于格林尼治标准时间+8,所以diffInMillis = 28800000 = 8 * 60 * 60 * 1000

相关问题