Java 将时间或日期类型的信息持久保存到数据库中的正确方法是什么?

Java 将时间或日期类型的信息持久保存到数据库中的正确方法是什么?,java,postgresql,date,time,persist,Java,Postgresql,Date,Time,Persist,在数据库中保存基于日期或时间的数据的正确方法是什么? java到postgresql(或其他数据库)的正确“字段映射”是什么 该数据应以utc格式存储,无时区 ->时间戳和基于日期的东西在这里失败,它们将添加当前时区() ->其他的选择是什么 我应该使用“普通历元/整数”列和其他时区列吗?但是我不能使用数据库为我提供的所有功能等 我可以使用hibernate和一些jodatime魔法,但在我当前的堆栈中,我没有使用hibernate 可能的解决办法: 1) 。更改UCT中的计算机/java时区-

在数据库中保存基于日期或时间的数据的正确方法是什么? java到postgresql(或其他数据库)的正确“字段映射”是什么

该数据应以utc格式存储,无时区

->时间戳和基于日期的东西在这里失败,它们将添加当前时区()

->其他的选择是什么

我应该使用“普通历元/整数”列和其他时区列吗?但是我不能使用数据库为我提供的所有功能等

我可以使用hibernate和一些jodatime魔法,但在我当前的堆栈中,我没有使用hibernate

可能的解决办法:

1) 。更改UCT中的计算机/java时区->java将(例如export TZ=“GMT”或-Duser.timezone=UCT)

2) 。在日期/时间字段/类型->工作中使用历元/整数值/长数值,但现在我不能使用内置数据库函数

3) 。是否将Jodatime与自定义hibernate数据类型一起使用


4) 。使用Java8新的时间和日期API?

正如您所说,最好将日期存储为数据库中的UTC。在oracle中,可以使用日期或时间戳数据类型。然后,您可以使用java层以本地时间向用户显示日期,并使用java.sql.timestamp列。Joda基本上内置于最新版本的java中,因此对于任何转换等都可以使用它。另一种方法是在oracle中存储带有时区的时间戳,或者在sql和存储过程中使用oracle日期函数来根据需要转换日期。我们采用前者,但这可能取决于您的团队(db人员vs java人员)和您的受众——用户群中可能存在许多不同的时区,或者DST转换的计时是否会破坏您的应用程序


如果你能描述你所关心的特定情况,我相信有人会帮你。在UTC中存储数据至少可以确保数据是可靠的,但可能需要在表示层进行多次转换。

没有一种正确的方法,但我认为您应该将时间存储为较长的unix时间戳,将单个日期存储为历元日。Java8有很好的函数来处理它们。避免将自己锁定在jodatime和hibernate中只是为了管理日期

数据库提供给您的功能是什么意思? 只要从程序中调用了整数,就可以使用整数执行SQL选择


如果您需要大量手动使用数据库(非编程),那么您可能希望使用人类可读的日期。

在大多数情况下,在处理多个时区或希望将所有时间戳保存为UTC时,最好使用Postgres数据类型(缩写为带时区的时间戳)

不要让这个名字误导你,时区实际上并没有被保存。但是(与
时间戳[无时区]
)相反,将文本输入的时区作为修饰符考虑,以计算实际UTC时间戳值,并保存该值。
在输出时,值的文本表示形式将根据当前时区设置进行格式化:时间戳将移动,并将相应的时区修改器附加到它

请注意,没有附加时区的时间戳将根据会话的当前时区设置进行解释。如果您想输入一个不考虑当前时区的文字UTC值,它必须是:

'2014-08-21 16:39:09+0'::timestamptz
不是:

相关答案中的详细说明:


java中的日期没有时区。只有将其格式化为字符串(或转换为java.util.Calendar)后,它才具有时区。日期只是一个很长的时间(从epoch开始的毫秒,1970年1月1日,00:00:00 GMT)的薄包装。如果您将日期保存/持久化到数据库中,它将转换为时间+时区。Postgres不支持无时区的时间戳。你试过了吗?我认为在这种情况下,当您将其读入
java.sql.Timestamp
(但我不完全确定)这是一个java问题,数据库中没有任何错误:)是的,java 8中有很好的函数等,但java的早期版本如何?如果你想使用任何数据库服务器,你就必须像我使用android和sqlite一样长时间使用。如果您想将db timestamp的某些功能与时区一起使用,将为您做大量工作。我们目前使用joda作为Java 7中的库,但在oracle中,如果您在持久化的瞬间使用例如时间戳,它将自动添加时区偏移量,这是不一样的。pasuna-请将时间戳与时间戳与时区进行比较,时间戳通常包含服务器返回的UTC值,例如从DUAL中选择SYSTIMESTAMP,例如,我说的是java类,不是数据库字段类型:这是正确的,但是如果您的底层数据结构没有单独存储时区,那么您可能很难在多个区域之间轻松地显示它
'2014-08-21 16:39:09'::timestamptz  -- would assume current time zone