我正在寻找一种标准的SQL方法,以确保独立于数据库而在UTC中具有带有时间戳的列,或作为具有时区信息的时间戳。在DB列中存储时间戳UTC的UTC示例:
印度当地时间21:00 / 9pm作为当地时间戳“ 2014-01-01 21:00:00.000”
印度当地时间05:00 / 5am作为当地时间戳“ 2014-01-01 05:00:00.000”
以UTC方式,应用程序必须应对时区划分
现在我真的不知道是否可能,带有上述值的时间戳和时区
但是有时区信息吗?
或如何获取此时间戳的时区信息?
希望有人可以帮助我摆脱困境?是否存在关于时区问题和存储数据以供国际应用的良好实践?
要存储时刻(时间轴上的一点),请定义SQL标准类型的数据库列TIMESTAMP WITH TIME ZONE。
TIMESTAMP WITH TIME ZONE
在UTC中存储一会儿。
Instant instant = Instant.now() ; // Capture the current moment in UTC. myPreparedStatement.setObject( 鈥� , instant ) ;
在UTC中检索片刻。
Instant instant = myResultSet.getObject( 鈥� , Instant.class ) ;
从UTC调整为时区。相同的时刻,不同的挂钟时间。
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; // Specify time zone in proper `Continent/Region` name, never the ambiguous non-standard 3-4 letter pseudo-zone such as `IST` or `PST`. ZonedDateTime zdt = instant.atZone( z ) ;
从时区调整为UTC。相同的时刻,不同的挂钟时间。
Instant instant = zdt.toInstant() ;
严重的数据库不会将日期时间值存储为字符串。不要将数据库或Java库生成的字符串 表示形式 与日期时间值本身混淆。
最佳实践是对数据库和其他存储以及大部分业务逻辑使用UTC。仅在用户期望的时间显示在当地时区。
有关标准日期时间类型,请参见Wikipedia 。即使您不使用Postgres,也请查阅有关日期时间数据类型的出色文档。但是我确实推荐Postgres,原因有很多,包括对日期时间的出色支持。
TIMESTAMPZ
这位Postgres专家提出了简单而明智的建议:始终将TIMESTAMP与TIME ZONE一起使用
该数据类型的 名称用词不当 ,引起了很多混乱。 不 存储时区信息。这意味着要遵守输入数据指示的时区,并将存储的值调整为UTC。认为TIMESTAMP WITH TIME ZONE是TIMESTAMP WITH RESPECT FOR TIME ZONE。大声地重读此段落三遍,然后阅读以上链接,并做一些实验以确保您理解。
TIMESTAMP WITH RESPECT FOR TIME ZONE
您可能还需要单独存储原始时区信息。不适用于您的业务逻辑,而用作调试的日志信息。
对于Java,请确保避免使用java.util.Date和.Calendar类。他们出了名的麻烦。在Java 8中,新的java.time软件包已将它们替换。使用该软件包和/或启发了java.time的Joda-Time 2.4库。
并且在Java中,始终指定所需的时区。如果省略,您将隐式使用JVM的当前默认时区。该隐式默认值意味着您的结果将随时间和空间而变化。这是日期时间工作中许多麻烦的根本原因。如果要使用UTC,请在Joda- Time中使用常量DateTimeZone.UTC。
DateTimeZone.UTC
忽略时区不会使您的生活更轻松。
这个标准是非常有用和明智的。学习出色的Wikipedia页面。应该是String表示形式的首选。