Java中将毫秒转换为GMT日期

4

我需要将毫秒转换为GMT日期(在Android应用程序中),例如:

1372916493000

当我使用以下代码进行转换时:

Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.setTimeInMillis(millis);
Date date = cal.getTime();

结果是07:41 07/04/2013。当我只使用以下内容时,结果是相同的:

Date date = new Date(millis);

很遗憾,结果看起来不正确,它看起来像是我的当地时间。我尝试使用这个服务将相同的数字转换,结果是05:41 07/04/2013,我相信这是正确的。所以我有两个小时的差异。有人有任何建议/提示,我的转换出了什么问题吗?


所以,明确一下,您希望将时间戳作为字符串打印,并使用GMT时区? - Duncan Jones
请查看此答案:如何将本地日期转换为GMT? - Ahiel
你有考虑到夏令时吗? - Roger Rapid
请参见此处:https://dev59.com/iXVC5IYBdhLWcg3woStW - Tala
您提供的毫秒数表示您所在的家庭时区还是GMT时区? - dumbfingers
1
请注意,像java.util.Datejava.util.Calendarjava.text.SimpleDateFormat这样的老旧日期时间类现在已经过时,被java.time类所取代。大部分java.time功能已经移植到Java 6和Java 7中,在ThreeTen-Backport项目中实现。还有一个专门为早期Android版本适配的ThreeTenABP项目。请参阅如何使用ThreeTenABP... - Basil Bourque
5个回答

14
如果结果看起来不正确,这意味着 System.out.println(date) 因为 Date.toString 把日期转换成当地时区的字符串表示。要在 GMT 中查看结果,您可以使用以下代码:
SimpleDateFormat df = new SimpleDateFormat("hh:ss MM/dd/yyyy");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String result = df.format(millis);

这段代码对我不起作用。显示了非法参数异常。 - Jay Vyas

2

tl;dr

Instant.ofEpochMilli( 1_372_916_493_000L )         // Moment on timeline in UTC.

2013年7月4日05:41:33 Z
...和...
Instant.ofEpochMilli( 1_372_916_493_000L )          // Moment on timeline in UTC.
       .atZone( ZoneId.of( "Europe/Berlin" ) )  // Same moment, different wall-clock time, as used by people in this region of Germany.

日期时间类已经过时,现在应该使用java.time类。

java.time

如果您有从UTC时间1970年1月1日的第一刻开始计算的毫秒数,那么请将其解析为InstantInstant类表示UTC上时间线上的一个瞬间,分辨率为纳秒(小数点后最多九位数字)。
Instant instant = Instant.ofEpochMilli( 1_372_916_493_000L ) ;

翻译如下:
instant.toString(): 2013-07-04T05:41:33Z
通过应用时区(ZoneId),可以从特定区域的挂钟时间的角度看到同一时刻,得到一个ZonedDateTime。
ZoneId z = ZoneId.of( "Europe/Berlin" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString():2013年7月4日07:41:33+02:00[欧洲/柏林]

关于java.time

java.time框架内置于Java 8及以后版本中。这些类替代了旧的传统日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time项目现处于维护模式,建议迁移到java.time类。

要了解更多,请查看Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是JSR 310
从哪里获取java.time类?

2

在转换时,你似乎混淆了家庭时区和UTC时区。

假设你现在在伦敦(目前伦敦比格林威治时间提前1小时),而毫秒数是你所在家庭时区的时间(在这种情况下是伦敦)。

因此,你可能应该:

Calendar cal = Calendar.getInstance();
// Via this, you're setting the timezone for the time you're planning to do the conversion
cal.setTimeZone(TimeZone.getTimeZone("Europe/London"));
cal.setTimeInMillis(1372916493000L);
// The date is in your home timezone (London, in this case)
Date date = cal.getTime();


TimeZone destTz = TimeZone.getTimeZone("GMT");
// Best practice is to set Locale in case of messing up the date display
SimpleDateFormat destFormat = new SimpleDateFormat("HH:mm MM/dd/yyyy", Locale.US);
destFormat.setTimeZone(destTz);
// Then we do the conversion to convert the date you provided in milliseconds to the GMT timezone
String convertResult = destFormat.parse(date);

请告诉我是否正确理解了您的观点?

谢谢


1
尝试这个。
public class Test{
    public static void main(String[] args) throws IOException {
        Test test=new Test();
        Date fromDate = Calendar.getInstance().getTime();
        System.out.println("UTC Time - "+fromDate);
        System.out.println("GMT Time - "+test.cvtToGmt(fromDate));
    }
    private  Date cvtToGmt( 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;
        }
}

测试结果
UTC时间- 2012年5月15日16:24:14 IST
GMT时间- 2012年5月15日10:54:14 IST


0

Date date = cal.getTime();

通过此代码返回创建的日期

public final Date getTime() {
    return new Date(getTimeInMillis());
}

getTimeInMillis() 返回毫秒数而不带有任何时区信息。

我建议查看这里,了解如何使用 Java 处理日历时区 how-to-handle-calendar-timezones-using-java


但是毫秒级时间是基于GMT还是设备/桌面所在的时区生成的呢? - Satyam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接