110

无论机器上设置的时区如何,我都需要将任何与时间相关的操作强制为 GMT/UTC。在代码中有什么方便的方法吗?

为了澄清,我使用数据库服务器时间进行所有操作,但它根据本地时区格式化。

谢谢!

4

13 回答 13

137

OP 回答了这个问题以更改正在运行的 JVM 的单个实例的默认时区,设置user.timezone系统属性:

java -Duser.timezone=GMT ... <main-class>

如果在从数据库中检索 Date/Time/Timestamp 对象时需要设置特定的时区,请使用获取对象的方法ResultSet的第二种形式:getXXXCalendar

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
ResultSet rs = ...;
while (rs.next()) {
    Date dateValue = rs.getDate("DateColumn", tzCal);
    // Other fields and calculations
}

或者,在 PreparedStatement 中设置日期:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
PreparedStatement ps = conn.createPreparedStatement("update ...");
ps.setDate("DateColumn", dateValue, tzCal);
// Other assignments
ps.executeUpdate();

这些将确保当数据库列不保留时区信息时,存储在数据库中的值是一致的。

java.util.Datejava.sql.Date以 UTC 格式存储实际时间(毫秒)。要在输出到另一个时区时将它们格式化,请使用SimpleDateFormat. 您还可以使用 Calendar 对象将时区与值关联:

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>");
//...
Date dateValue = rs.getDate("DateColumn");
Calendar calValue = Calendar.getInstance(tz);
calValue.setTime(dateValue);

有用的参考

https://docs.oracle.com/javase/9​​/troubleshoot/time-zone-settings-jre.htm#JSTGD377

https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html

于 2010-04-13T09:54:04.987 回答
25

另外,如果您可以通过这种方式设置 JVM 时区

System.setProperty("user.timezone", "EST");

-Duser.timezone=GMT在 JVM 参数中。

于 2013-02-13T16:27:33.610 回答
15

您可以使用TimeZone.setDefault()更改时区:

TimeZone.setDefault(TimeZone.getTimeZone("GMT"))
于 2012-12-13T10:48:39.837 回答
13

我必须为 Windows 2003 Server 设置 JVM 时区,因为它总是为 new Date() 返回 GMT;

-Duser.timezone=America/Los_Angeles

或您的适当时区。事实证明,查找时区列表也有点挑战性......

这是两个列表;

http://wrapper.tanukisoftware.com/doc/english/prop-timezone.html

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Frzatz%2F51%2Fadmin%2Freftz.htm

于 2011-02-19T19:23:42.443 回答
9
于 2020-01-27T23:34:19.350 回答
8

对我来说,只需快速 SimpleDateFormat,

  private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd");
  private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd");
  static {
      GMT.setTimeZone(TimeZone.getTimeZone("GMT"));
    SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney"));
  }

然后用不同的时区格式化日期。

于 2013-04-23T10:41:55.390 回答
6

我会以原始形式(长时间戳或 java 的日期)从数据库中检索时间,然后使用 SimpleDateFormat 对其进行格式化,或使用 Calendar 对其进行操作。在这两种情况下,您都应该在使用对象之前设置对象的时区。

SimpleDateFormat.setTimeZone(..)Calendar.setTimeZone(..)了解详情

于 2010-04-13T08:40:32.107 回答
5

使用系统属性:

-Duser.timezone=UTC
于 2019-04-09T07:04:25.340 回答
1

创建一对客户端/服务器,以便执行后,客户端服务器发送正确的时间和日期。然后,客户端在下午 GMT 时询问服务器,服务器发回正确的答案。

于 2013-05-19T15:31:29.637 回答
1

在 MySQL 中执行此行以重置您的时区:

SET @@global.time_zone = '+00:00';
于 2020-07-20T17:51:48.157 回答
0

希望下面的代码对您有所帮助。

    DateFormat formatDate = new SimpleDateFormat(ISO_DATE_TIME_PATTERN);
    formatDate.setTimeZone(TimeZone.getTimeZone("UTC")); 
    formatDate.parse(dateString);
于 2020-10-09T16:57:16.710 回答
-1

哇。我知道这是一个古老的线程,但我只能说不要在任何用户级代码中调用 TimeZone.setDefault()。这总是为整个 JVM 设置时区,而且几乎总是一个非常糟糕的主意。学习使用 joda.time 库或 Java 8 中与 joda.time 库非常相似的新 DateTime 类。

于 2016-08-02T00:24:05.667 回答
-6

如果您只想使用 intiger 获取 GMT 时间: var currentTime = new Date(); var currentYear ='2010' var currentMonth = 10; var currentDay ='30' var currentHours ='20' var currentMinutes ='20' var currentSeconds ='00' var currentMilliseconds ='00'

currentTime.setFullYear(currentYear);
currentTime.setMonth((currentMonth-1)); //0is January
currentTime.setDate(currentDay);  
currentTime.setHours(currentHours);
currentTime.setMinutes(currentMinutes);
currentTime.setSeconds(currentSeconds);
currentTime.setMilliseconds(currentMilliseconds);

var currentTimezone = currentTime.getTimezoneOffset();
currentTimezone = (currentTimezone/60) * -1;
var gmt ="";
if (currentTimezone !== 0) {
  gmt += currentTimezone > 0 ? ' +' : ' ';
  gmt += currentTimezone;
}
alert(gmt)
于 2014-09-10T10:52:13.887 回答