Java中的TimeZone问题

时间:2009-11-28 14:57:19

标签: java timezone

我正在尝试使用TimeZone GMT实例化GregorianCalendar,但每当我调用getTime()方法时,它都会给我时间本地TimeZone。这是我的代码:

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
System.out.println(cal.getTime());

我得到的输出是:

Sat Nov 28 19:55:49 PKT 2009

请帮忙!

3 个答案:

答案 0 :(得分:9)

我不确定这是否能回答你的问题,但这是在GMT中“现在”获得的一种方式。

import java.text.*
import java.util.* 

Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(formatter.format(date));

有关不同的模式,请参阅Javadoc on SimpleDateFormat。此外,您可能需要考虑Joda Time,因为它远远优于日期和时间。

答案 1 :(得分:6)

问题不在于GregorianCalendar,而在于Date,用于格式化toString println的日期/时间。

如果你想控制日期格式,你需要实例化你自己的DateFormat - 我总是使用SimpleDateFormat,因为我对我希望日期看起来很挑剔。

如果您对格式化日期的方式不感兴趣,还可以使用getInstance...的{​​{1}}工厂方法之一。

您可以DateFormat明确setTimeZone(当然也包括DateFormat)。

答案 2 :(得分:1)

tl; dr

Instant.now().toString()

2020-03-08T00:21:48.647951Z

java.util.Date::toString撒谎

您对GregorianCalendar::getTime的呼叫将返回java.util.Date。如您所见,使用此方法和类命名时,这些类的设计不正确。

然后,您隐式调用Date::toString以生成表示该对象内的值的文本。该值实际上以UTC为单位,仅是自1970年UTC的第一时刻的纪元参考以来的毫秒数。不幸的是,该方法在生成文本时会动态应用JVM当前的默认时区。这会造成该区域包含在对象中的错觉。

令人困惑?是。 从不使用这些旧式日期时间类的众多原因之一。请改用 java.time 类。

java.time

其他答案是正确的,但现在已过时。可怕的DateCalendarGregorianCalendarSimpleDateFormat类在几年前被JSR 310中定义的现代 java.time 类所取代。

要获取当前的UTC时间,请使用Instant。根据定义, java.time 中的基本构建基类始终采用UTC。

Instant instant = Instant.now() ;

通过调用toString生成ISO 8601格式的标准字符串。

String output = instant.toString() ;

请参阅此code run live at IdeOne.com

2020-03-08T00:21:48.647951Z

要在生成字符串时更灵活地设置格式,请使用OffsetDateTime类。搜索堆栈溢出以了解DateTimeFormatter

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;