2017-09-14 53 views
0

在我的一个Web应用程序中,我必须安排一个事件。 我的服务器,客户端和数据库位于不同的时区。 客户端将安排一个事件,服务器必须执行该事件。保存和检索从客户端到数据库的时间

我该怎么做?

从客户

目前,我发送事件的时间以毫秒为单位自纪元:(带的getTime()在javascript日期的方法)

在服务器我将其转换为使用Java日期对象,并存储这作为数据库中的日期类型值。

在数据库中,存储的值比我给客户端的日期晚了一天。 这是为什么?我如何将它存储在服务器时间?

+0

由于您的问题是关于调度*,请参阅链接的最佳做法中的第6项。 (UTC不一定是调度的最佳方法) –

回答

3

您的问题与其他许多问题相同。所以我会简短。

有两种方法来代表三个品种的现代化枣,时间值:

  • 存储和交换日期时间UTC如果实际一刻已经过去(金制成,收到发票,担任法庭文件,货物到达等),或者如果将来你知道你想要在时间线上的特定时刻,无论政客是否重新定义时区,例如更改Daylight Saving Time (DST)。对于Java,使用Instant类。在SQL中使用TIMESTAMP WITH TIME ZONE
  • 存储和交换日期时间值,而不带/调度未来事件远远不够了,在未来的政治家可以更改时区规则(明年牙医,面试在两个月后,方公告等等偏移)。世界各地的政客都表现出喜欢用我们的钟表摆弄,常常几乎没有什么警告,有时只有几个星期的事先通知。对于Java,使用LocalDateTime类。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE。为了提供时间表,使用ZonedDateTime类,通过Instant::atZone方法,使用Java生成瞬态数据。
  • 存储和交换日期时间值,而不区/非特定事件,如圣诞节的开始或者说:“在德里,杜塞尔多夫,&底特律,我们所有的工厂将关闭进行为期半天的偏移今年10月30日中午“,我们指的是当地时间的每个中午,而不是同时的中午。对于Java,使用LocalDateTime类。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE

作为一个程序员和系统管理员,学会思考在UTC和24小时的时间。在工作中忘记你自己的教区时区。在办公室保持第二个时钟设置为UTC。

您如何知道用户的预期/所需时区?最终唯一确定的方法是问她/他。

当序列化为文本时,请使用标准ISO 8601格式。

避免可怕的旧日期时间类,如java.util.Datejava.sql.Date等,这些现在已经成为传统,被业界领先的优秀java.time类所取代。

Instant代表UTC中时间轴上的一个时刻。

Instant instant = Instant.ofEpochMilli(millis) ; 

,以呈现给用户,调整UTC到他们期望/希望的时区。想象一下,就像internationalization一样,在那里存储对某个键的引用,然后为了演示,使用检索到的键来查找本地化的文本值。

切勿使用3-4个字符的伪时区。 True time zones有一个continent/region名称,如Asia/KolkataPacific/Auckland

ZoneId z = ZoneId.of("America/Montreal") ; 
ZonedDateTime zdt = instant.atZone(z) ; 

注意,数据库在他们处理的日期,时间变化广泛。 SQL标准几乎没有涉及到这个问题。研究文档并进行实验以确保您了解其行为。同上您的JDBC驱动程序。提示:对date-time typesfunctions有一些最好的支持。

随着JDBC 4.2和后,用经由java.time对象数据库交换数据,通过调用:

  • PreparedStatement::setObject
  • ResultSet::getObject

实施例代码

myPStmt.setObject.(… , myInstant) ; 

...和...

Instant instant = myResultSet.getObject(… , Instant.class) ; 
+1

对不起,但没有。 *调度*,UTC不一定是最好的方法。从那里查看最佳做法和相关答案。 –

+2

@MattJohnson真的。我修改了我的答案,增加了一对子弹来处理每个案例。 –

+0

更好。谢谢! :)另请参阅:https://twitter.com/mj1856/status/903682303833944064 –

1

当你存储时间时,你最好的选择是将它存储到任何时间的任何地方(或者如果你喜欢unix时间的话),然后在前端反序列化它。这意味着你可以放心,你坚持了正确的时间,然后你可以在前端进行转换。在不知道具体情况的情况下,我怀疑你在Java中创建的日期对象是导致分流,然后将错误的日期值存储在数据库中。

+0

对不起,但没有。对于调度*,unix时间不一定是最好的方法。从那里查看最佳做法和相关答案。 –

相关问题