在我的一个网络应用程序中,我必须安排一个活动。 我的服务器,客户端和数据库位于不同的时区。 客户端将安排一个事件,服务器必须执行该事件。
我该怎么做?
目前来自客户端,我发送自epoch以来的事件时间(以毫秒为单位):(在javascript中使用Date的getTime()方法)
在服务器中,我使用Java将其转换为日期对象,并将其作为日期类型值存储在数据库中。
在数据库中,存储的值比我从客户端提供的那天晚了一天。 为什么会那样?如何将其存储在服务器中?
答案 0 :(得分:3)
你的许多其他问题都是重复的。所以我会简短。
有两种方法可以表示三种日期时间值:
TIMESTAMP WITH TIME ZONE
。Instant
类。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE
。要提供计划,请使用ZonedDateTime
类通过LocalDateTime
方法在Java中生成临时数据。Instant::atZone
类。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE
。 作为程序员和系统管理员,学会在UTC和24小时内思考。在工作期间忘掉你自己的狭隘时区。在办公室中将第二个时钟设置为UTC。
您如何知道用户的预期/期望时区?最终唯一可靠的方法是问她/他。
序列化为文本时,请使用标准LocalDateTime
格式。
避免可怕的旧日期时间类,例如java.util.Date
和java.sql.Date
等。这些现在已成为传统,取而代之的是业界领先的java.time类。
Instant instant = Instant.ofEpochMilli( millis ) ;
要向用户演示,请将UTC调整为他们期望/期望的时区。您可以将其视为UTC,其中存储对键的引用,然后使用检索到的键来查找本地化的文本值。
切勿使用3-4个字符的伪时区。 internationalization有一个continent/region
名称,例如Asia/Kolkata
和Pacific/Auckland
。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
请注意,数据库在处理日期时间时会广泛地广泛。 SQL标准几乎没有触及这个主题。研究文档并进行实验,以确保您了解它的行为。同样适用于您的JDBC驱动程序。提示:True time zones对Postgres和date-time types提供了一些最佳支持。
使用functions及更高版本,通过调用:
,通过java.time对象与数据库交换数据PreparedStatement::setObject
ResultSet::getObject
示例代码
myPStmt.setObject.( … , myInstant ) ;
...和...
Instant instant = myResultSet.getObject( … , Instant.class ) ;
答案 1 :(得分:1)
当您存储时间时,您最好的选择是在纪元时间(或者如果您愿意的话,使用unix时间)将其存储在任何地方,并在前端对其进行反序列化。这意味着您可以确信您已经持续了正确的时间,然后您可以在前端进行转换。在不知道细节的情况下,我怀疑您在Java中创建的日期对象导致了移位,然后您将错误的日期值存储在数据库中。