时区中立申请

时间:2016-03-02 11:25:10

标签: java postgresql datetime timezone


我们运行了基于JAVA和J2EE产品的应用程序,并将postgres作为数据库服务器,在设计架构师出错时将所有日期和时间列存储在本地时区IST中。现在,应用程序用户要求在本地区域显示所有时间。来自伦敦的用户希望应用程序以GMT显示所有日期和时间。
是否有任何最适合此处的解决方案或方法,只需最少的更改。另外我认为使用 Java时间或JODA时间对我来说无济于事,因为我有更多的工作要做。
1)考虑将所有现有的日期和时间转换为UTC(简单,可行,更好地实施)
2)我将如何处理显示部分,因为在搜索屏幕中我们允许用户不仅选择日期而且选择查找所有匹配交易的时间,此处的时间假定为用户的本地时间。

1 个答案:

答案 0 :(得分:0)

背景

在Postgres中TIMESTAMPTIMESTAMP WITH TIMEZONE的存储方式相同 - 自Postgres纪元(2000-01-01)以来的秒数。主要区别在于Postgres在保存时间戳值时所做的事情,例如2004-10-19 10:23:54+02

  • 没有TZ,+02就被剥夺了
  • 使用TZ执行-02校正以使其成为UTC

现在有趣的是JDBC驱动程序加载值:

  • 没有TZ,存储的值被用户(JVM / OS)TZ
  • 移动
  • 使用TZ,该值被视为UTC

在这两种情况下,您最终都会使用用户默认TZ的java.sql.Timestamp对象。

时区

没有TZ的时间戳非常有限。如果有两个系统连接到数据库,两个系统都有不同的TZ,它们将以不同的方式解释时间戳。

您可以tell JDBC在通过ResultSet#getTimestamp(String, Calendar)阅读时间戳时应该使用哪种TZ。摘自JavaDoc:

  

如果基础数据库不存储时区信息,则此方法使用给定的日历为时间戳构造适当的毫秒值。

一旦你有时间戳(在没有TZ的情况下),你现在可以可靠地使用Joda-Time。 Joda-Time提供各种内置格式化程序,您也可以定义自己的格式化程序。但是,对于编写日志或报告,最佳选择可能是ISO 8601格式。该格式恰好是Joda-Time和java.time使用的默认格式。

示例代码

java.sql.Timestamp timestamp = resultSet.getTimestamp(i);

DateTime dateTimeUtc = new DateTime( DateTimeZone.UTC ); // Defaults to now, this moment.

// Convert as needed for presentation to user in local time zone.
DateTimeZone timeZone = DateTimeZone.forID("Europe/Paris");
DateTime dateTimeZoned = dateTimeUtc.toDateTime( timeZone );