Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java和MySQL中的时间戳和时区转换_Java_Mysql_Timestamp - Fatal编程技术网

Java和MySQL中的时间戳和时区转换

Java和MySQL中的时间戳和时区转换,java,mysql,timestamp,Java,Mysql,Timestamp,我正在开发一个Java应用程序,在一个与我所在时区不同的服务器上使用MySQL数据库,我正在尝试在数据库上使用DATETIME还是时间戳 在阅读了诸如和之类的问题后,我认为时间戳对我来说更合适,因为它将值转换为UTC进行存储,并返回到当前时区进行检索 此外,正如用户Jesper在thread中解释的那样,java.util.Date对象在内部只是一个UTC时间戳(即自历元起的毫秒数),当您执行toString()时,它将根据当前时区显示 对我来说,这看起来是一个很好的做法:将日期时间存储为UTC

我正在开发一个Java应用程序,在一个与我所在时区不同的服务器上使用MySQL数据库,我正在尝试在数据库上使用DATETIME还是时间戳

在阅读了诸如和之类的问题后,我认为时间戳对我来说更合适,因为它将值转换为UTC进行存储,并返回到当前时区进行检索

此外,正如用户Jesper在thread中解释的那样,java.util.Date对象在内部只是一个UTC时间戳(即自历元起的毫秒数),当您执行toString()时,它将根据当前时区显示

对我来说,这看起来是一个很好的做法:将日期时间存储为UTC时间戳,然后根据当前时区显示它们

我本来打算这样做的,但后来我从准备好的声明中发现了这一点,我感到非常困惑:

void setTimestamp(int参数索引, 时间戳x, 日历(校准) 抛出SQLException

将指定参数设置为给定的java.sql.Timestamp值, 使用给定的日历对象。驱动程序使用日历对象 构造SQL时间戳值,然后驱动程序将其发送到 数据库。使用日历对象,驱动程序可以计算 考虑自定义时区的时间戳。如果没有日历对象 指定时,驱动程序使用默认时区,即 运行应用程序的虚拟机

在此之前,我认为按照惯例,时间戳总是使用UTC。究竟为什么有人想要一个本地化的时间戳而不是它的本地化表示?这对每个人来说不是都很困惑吗

这些转换是如何工作的?如果Java获取UTC时间戳并将其转换为任意时区,它如何告诉MySQL它位于哪个时区


MySQL不会假设这个时间戳是UTC格式的,然后检索到一个不正确的本地化值吗?

您的问题正好是一个我认为这些天非常严重的问题。DB(通过SQL)和服务器端本身(通过Java等编程语言)都提供了处理日期和时间的方法概要。我认为现状是高度非标准化的,有点混乱(个人观点:)

我的回答是片面的,但我会解释原因

没错,Java的日期(和日历)将时间存储为自Unix纪元以来的毫秒(这很好)。它不仅在Java中发生,在其他编程语言中也会发生。在我看来,完美的计时体系结构自然而然地由此产生:Unix时代是1970年1月1日UTC午夜。因此,如果您选择自Unix纪元以来以毫秒为单位存储时间,则有很多好处:

  • 架构清晰:服务器端使用UTC,客户端通过其本地时区显示时间
  • 数据库简单性:存储的是数字(毫秒),而不是复杂的数据结构(如DateTimes)
  • 编程效率:在大多数编程语言中,当构建日期/时间对象时,它能够从Epoch开始以毫秒为单位(正如您所说,它允许自动转换到客户端时区)
我发现使用这种方法时,代码和体系结构更简单、更灵活。我不再试图理解日期时间(或时间戳)之类的东西,只在我必须修复遗留代码时才处理它们。

日期时间处理是一团混乱 本文的第一段非常有见地和正确:Java中的日期-时间处理非常混乱。我所知道的所有其他语言和开发环境也是如此。日期时间工作是困难和棘手的,特别是容易出错和令人沮丧的,因为我们直觉地认为它是日期时间。但“直觉”并不能解决数据类型、数据库、序列化、本地化、跨时区调整以及计算机编程附带的所有其他手续

不幸的是,计算机行业基本上忽视了日期时间工作这一问题。正如Unicode由于明显的需求而花了太长时间才发明出来一样,业界也在解决日期时间处理问题上迈出了第一步

别指望从一开始就计数 但我不同意它的结论。从大纪元开始计算并不是最好的解决方案。使用count-since-epoch本质上是混乱的、容易出错的和不兼容的

  • 人类无法读取
    长的
    数字并将其解码为日期时间。因此,验证数据和调试变得复杂,至少可以这么说
  • 你会用什么“计数”?被和被使用的?数据库、MySQL和其他数据库使用的?Java 8中的新用户使用了什么
  • 你会用哪一种?1970年初的UTC标准是常见的,但远不是单一的。几乎已经被各种计算机系统使用
我们创建数字数据类型来进行数学运算,而不是使用位。我们创建字符串类来处理文本处理的细节,而不是简单的八位字节。因此,我们也应该创建数据类型和类来处理日期时间值

早期的Java团队(以及IBM及其之前的团队)尝试使用Java.util.Date和Java.util.Calendar及相关类。不幸的是,这种尝试是不够的。虽然日期时间本质上是令人困惑的,但这些类却增加了更多的困惑

乔达时间 据我所知,该项目是第一个以彻底、胜任和成功的方式按时完成的项目。即便如此,约达时代的创造者们也并不完全满意。他们接着用Java8创建了,并用扩展了这项工作。Joda Time和java.Time有着相似的概念,但各有不同,它们都有一些优点

数据库问题 具体来说,java.util.Date和.Calendar类缺少仅日期的值,而不包含时间-
String sql = "SELECT now();";
…
java.sql.Timestamp now = myResultSet.getTimestamp( 1 );
DateTime dateTimeUtc = new DateTime( now , DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeUtc.withZone( DateTimeZone.forID( "America/Montreal" ) );
myPreparedStatement.setObject( … , Instant.now() ) ;
Instant instant = myResultSet.getObject( … , Instant.class ) ;
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;