Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.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 根据用户时区转换存储在中心时间的服务器日期时间戳_Java_Mysql_Datetime_Plsql_Java 8 - Fatal编程技术网

Java 根据用户时区转换存储在中心时间的服务器日期时间戳

Java 根据用户时区转换存储在中心时间的服务器日期时间戳,java,mysql,datetime,plsql,java-8,Java,Mysql,Datetime,Plsql,Java 8,带有时间戳的日期插入/保存到数据库中,数据类型为中心时间(CT)中的datetime,与时区无关。当我访问东部时区中的应用程序并从我的时区(东部时间(ET))检索这些日期时,我希望这些日期以东部时区而不是中部时间呈现。例如,如果在中央时间数据库中存储的日期是2018-11-19 13:08:44,则如果我从东部连接,则需要将其返回为2018-11-19 14:08:44;如果我从山区时区连接,则需要将其返回为2018-11-19 12:08:44。我有一个JavaBean,我需要将检索到的日期转

带有时间戳的日期插入/保存到数据库中,数据类型为中心时间(CT)中的datetime,与时区无关。当我访问东部时区中的应用程序并从我的时区(东部时间(ET))检索这些日期时,我希望这些日期以东部时区而不是中部时间呈现。例如,如果在中央时间数据库中存储的日期是2018-11-19 13:08:44,则如果我从东部连接,则需要将其返回为2018-11-19 14:08:44;如果我从山区时区连接,则需要将其返回为2018-11-19 12:08:44。我有一个JavaBean,我需要将检索到的日期转换为我的时区,并在csv文件中显示该日期。我如何做到这一点?Java是服务器端语言。非常感谢。

您没有提供足够的详细信息来为您提供准确的帮助。但这里有一些一般的指导方针

列的数据类型 要记录时刻,您的数据库表列必须使用类似于SQL标准带时区的时间戳的类型定义。MySQL中的等价物似乎是

当心那些具有反时限功能的工具,这些工具动态地将默认时区应用于从数据库中提取的值。这造成了存储值具有特定时区的错觉。MySQL 8中肯定不是这种情况,
TIMESTAMP
始终存储在UTC中

不要使用不带时区的时间戳类型,因为它只记录一天中的日期和时间,而不记录时区上下文或UTC偏移量。MySQL中的等价物似乎是

UTC是你的朋友 通常,最好通过UTC跟踪时刻,也就是说,与UTC的偏移量为零小时分秒。您应该学会将UTC视为一个真实时间,所有其他区域和偏移都只是变化。所有程序员和系统管理员都应该在UTC中进行日志记录、调试、数据存储和数据交换。仅根据业务逻辑或向用户演示的需要应用时区

插入/保存到数据库中,数据类型为中心时间(CT)中的datetime,与时区无关

我不知道那是什么意思

如果要跟踪时间轴上的时刻、特定点,必须具有时区或与UTC的偏移量。正如我所建议的,强烈建议使用UTC本身

在java.time中,
Instant
类表示UTC中的一个时刻,总是UTC

Instant instant = Instant.now() ;  // Capture current moment in UTC.
奇怪的是,JDBC 4.2标准不需要支持两个最常用的java.time类:
Instant
ZonedDateTime
。第三类是“时刻”
OffsetDateTime
。没关系,我们可以很容易地转换。使用常量指定零的偏移量

或者跳过
即时

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
发送到数据库

myPreparedStatement.setObject( … , odt ) ;
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
从数据库中检索

myPreparedStatement.setObject( … , odt ) ;
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
请注意,所有这些代码仅在UTC中工作。没有涉及时区,只是零小时分秒的偏移量

时区 中部时间(CT)…东部时间(ET)

这些不是时区。这些是伪区域,通常在媒体中使用,但永远不会在编程中使用

大陆/地区
的格式指定,例如
美国/蒙特利尔
非洲/卡萨布兰卡
,或
太平洋/奥克兰
。切勿使用2-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

ZoneId
虽然
ZoneOffset
仅用于偏移量(小时分秒数),但该类用于时区(特定地区的人们使用的偏移量的过去、现在和未来变化的历史记录)

ZoneDateTime
我们可以将
ZoneId
应用于
Instant
OffsetDateTime
以通过该地区的人们使用的挂钟时间(offset)查看该时刻

ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; 
正文 要以标准ISO 8601格式创建表示java.time对象值的字符串,只需调用
toString

要以其他自定义格式生成文本,甚至自动本地化,请参见
DateTimeFormatter
DateTimeFormatterBuilder
类。搜索堆栈溢出,因为这已经被讨论过很多次了

重构 你在问题中提到了“日期时间”。如果你的意思是你的专栏实际上是
DATETIME
类型,那么你的手上就乱七八糟了。您应该重构数据库以使用适当的类型

对于重构,从该列中提取值,作为Java类型进行检索。此类用于日期和时间,但缺少区域或偏移的上下文。因此,该值不是一个时刻,也不是时间线上的一个点

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;  // Retrieving value from a MySQL 8 column of type `DATETIME`. 
您声称知道这些值的预期时区,但未记录。记住,你只是在猜测。您无法确定原始分区/偏移是什么,因为该值已被丢弃

但是,如果您确定要使用的分区,请指定为
ZoneId
。所谓“中央时间(CT)”,我假设你指的是一个时区,比如美国/芝加哥

ZoneId zChicago = ZoneId.of( "America/Chicago" ) ;
将此
ZoneId
对象应用于每个检索到的
LocalDateTime
对象

ZonedDateTime zdt = ldt.atZone( zChicago ) ;
根据JDBC 4.2规范所需的支持,将我们的
ZonedDateTime
转换为
OffsetDateTime
。(您的JDBC驱动程序可以选择支持
ZonedDateTime
,因此,如果您愿意,可以尝试这样做。)

在类型为
TIMESTAMP
的新列中发送到数据库,就像最初设计数据库时应该做的那样

myPreparedStatement.setObject( … , odt ) ;
请注意,我们发送的
OffsetDateTime
对象不是UTC格式。该对象将携带芝加哥地区在该位置使用的偏移量
myPreparedStatement.setObject( … , odt ) ;