使用 Java 在 PostgreSQL 中存储时间的最推荐方法是什么?

2023-11-29

我在 PostgreSQL 数据库中存储两个日期。第一个是网页的访问数据,第二个日期是网页的最后修改日期(这是一个长整型)。

我有些怀疑存储这些值的最佳策略是什么。

我只需要日/月/年和小时:秒,这仅用于统计建议。

那么,有些疑问:

  • 最好存储尽可能长的时间并在恢复信息时进行转换,还是以上述数据格式存储?
  • 最好在软件上设置访问日期还是在数据库中插入?
  • 在Java中,最好的类是如何处理日期的?

在 IMO 中,任何在 PostgreSQL 中存储日期和时间数据的策略都应该依赖于这两点:

  • 你的解决方案应该never取决于服务器或客户端时区设置。
  • 目前,PostgreSQL(与大多数数据库一样)没有数据类型来存储full带时区的日期和时间。因此,您需要在Instant or a LocalDateTime数据类型。

我的食谱如下。


如果你想记录身体instant当特定事件发生时,(一个真实的“时间戳" ,通常是一些创建/修改/删除事件),然后使用:

  • Java: Instant(Java 8 或 Jodatime)。
  • JDBC: java.sql.Timestamp
  • PostgreSQL:TIMESTAMP WITH TIMEZONE (TIMESTAMPTZ)

(不要让 PostgreSQL 特有的数据类型WITH TIMEZONE/WITHOUT TIMEZONE让您感到困惑:它们实际上都没有存储时区)

一些样板代码:以下假设ps is a PreparedStatement, rs a ResultSet and tzUTC是一个静态的Calendar对象对应于UTC时区。

public static final Calendar tzUTC = Calendar.getInstance(TimeZone.getTimeZone("UTC"));  

Write Instant到数据库TIMESTAMPTZ:

Instant instant = ...;
Timestamp ts = instant != null ? Timestamp.from(instant) : null;
ps.setTimestamp(col, ts, tzUTC);   // column is TIMESTAMPTZ!

Read Instant来自数据库TIMESTAMPTZ:

Timestamp ts = rs.getTimestamp(col,tzUTC); // column is TIMESTAMPTZ
Instant inst = ts !=null ? ts.toInstant() : null;

如果您的 PG 类型是,这可以安全地工作TIMESTAMPTZ(在这种情况下,calendarUTC对该代码没有影响;但始终建议不要依赖默认时区)。 “安全”意味着结果将不依赖于服务器或数据库时区或时区信息:该操作是完全可逆的,无论时区设置发生什么,您总是会得到与 Java 端最初相同的“即时时间”。


如果您正在处理的不是时间戳(物理时间线上的瞬间)“民用”本地日期时间(即字段的集合{year-month-day hour:min:sec(:msecs)}),你会使用:

  • Java: LocalDateTime(Java 8 或 Jodatime)。
  • JDBC: java.sql.Timestamp
  • PostgreSQL:TIMESTAMP WITHOUT TIMEZONE (TIMESTAMP)

Read LocalDateTime来自数据库TIMESTAMP:

Timestamp ts = rs.getTimestamp(col, tzUTC); //
LocalDateTime localDt = null;
if( ts != null ) 
    localDt =  LocalDateTime.ofInstant(Instant.ofEpochMilli(ts.getTime()), ZoneOffset.UTC);

Write LocalDateTime到数据库TIMESTAMP:

  Timestamp ts = null;
  if( localDt != null)    
      ts = new Timestamp(localDt.toInstant(ZoneOffset.UTC).toEpochMilli()), tzUTC);
  ps.setTimestamp(colNum,ts, tzUTC); 

再次强调,这个策略是安全的,你可以安然入睡:如果你储存了2011-10-30 23:59:30,您将始终检索这些精确字段(小时 = 23,分钟 = 59 ...等),无论如何 - 即使明天您的 Postgresql 服务器(或客户端)的时区发生变化,或者您的 JVM 或操作系统时区,或者如果您所在的国家/地区修改了 DST 规则等。


添加:如果您想要(这似乎是一个自然的要求)存储完整的日期时间规范(aZonedDatetime:时间戳和时区,其中隐含地还包括完整的民用日期时间信息 - 加上时区)...那么我有坏消息给你:PostgreSQL没有这样的数据类型(据我所知,其他数据库也没有) 。您必须设计自己的存储,也许在一对字段中:可以是上述两种类型(高度冗余,但对于检索和计算来说很有效),或者其中一个加上时间偏移量(您丢失了时区信息,一些计算变成困难,有些不可能),或者其中之一加上时区(作为字符串;某些计算可能非常昂贵)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Java 在 PostgreSQL 中存储时间的最推荐方法是什么? 的相关文章

随机推荐

  • 如何在jquery中使用多个“属性等于”选择器?

    如果您想选择一个具有 1 个等于某个值的属性的 jquery 元素 很简单 element attribute1 true hide 但是如果你想选择一个具有 2 个相同属性的元素怎么办 element attribute1 true at
  • 如何以编程方式计算上下文切换?

    在Windows下 有没有办法以编程方式计算同一进程的上下文切换 最好的事情是每当线程切换时都会调用回调 有一个性能计数器这对你有用 您所要做的就是读取它的值 您可以找到有关如何交互式执行此操作的说明here 但也可以使用其 API 来使用
  • Woocommerce 自定义产品类别下拉问题

    我正在为店面主题开发一个儿童主题 我使用产品类别小部件作为标题下的下拉菜单 这完全符合我的需求 尽管我需要相同的 如果可能 下拉菜单显示在每个类别页面上 而不仅仅是主页上 我正在定制这段代码这几乎做到了 WooCommerce Extra
  • 年和年代有什么区别?

    The DateTimeFormatter类文档定义单独的符号u年度和y时代年份 https docs oracle com javase 8 docs api java time format DateTimeFormatter html
  • 拖动手势时将矩形限制为屏幕边缘

    我刚刚开始使用 SwiftUI 我希望找到最好的方法来解决在拖动手势期间将该矩形保持在屏幕边界内的问题 现在它会离开边缘 直到到达正方形的中间 我想是因为我正在使用 CGPoint 我尝试做一些数学来限制矩形 它只在左侧成功 但这似乎是一种
  • Gremlin 日期过滤方法

    有没有办法查询 titan gremlin 的日期 例如查找过去 X 天内的所有结果 任何帮助将非常感激 最好的方法是简单地将日期存储为 Long 值 并可能在边缘中的此类字段上建立索引 以便您可以利用limit interval等 请参阅
  • 将范围导出为图像

    一段时间以来 我和我的同事一直在使用各种方法来创建模板来轻松制作志愿者职位空缺表格 理想情况下 该项目的负责人只需输入详细信息 职位空缺表格就会自动生成 此时 我已经自动完成了表单 但我们仍然需要复制范围并将其手动粘贴到绘图中以将其另存为图
  • 我可以向 JSON-LD 中的给定 @type 添加自定义属性吗?

    我正在开发一个网站 允许用户探索大量唱片 所有数据当前都存储在一个 JSON 文件中 我将其转换为 JSON LD 以便使其具有语义并可供搜索引擎抓取 Schema org 有一个标准类型音乐专辑 它没有我为每个专辑存储 并呈现给用户 的某
  • C# - 国际设置的 Excel 数字格式问题

    我正在尝试使用 c 3 5 写入 Excel 2003 电子表格 但是我无法让它在不同的国家 地区设置中正常运行 国家 地区设置为英语或德语 这两个设置有不同的小数和千位设置 除非用户更改了 选项 屏幕的 国际 设置中的小数点和千位分隔符
  • 下拉列表项的工具提示

    我有一个下拉列表 我想为下拉列表项添加工具提示 我尝试使用以下代码 但它不起作用 for int d 0 d
  • JQUERY 通过参数 ID 获取元素

    只是想知道 jquery 的等效语法是什么 var elm id my id var elm document getElementById elm id thanks 我想你正在寻找的是 var elm id my id var elm
  • Eclipse CDT clean 在 Windows 上失败:尝试运行 rm -rf

    我在 Windows 7 上使用带有 CDT 的 Juno 当我尝试使用 MinGW 提供的内部构建器或 make 清理项目时 Eclipse 运行 X 命令 射频 并且清理操作失败 从控制台使用外部构建器 mingw32 make 进行日
  • Hive/Hadoop 中的唯一密钥生成

    从大数据 Hive 表中选择一组记录时 需要为每条记录创建唯一的键 在顺序操作模式下 通过调用像 max id 这样的东西很容易生成唯一的 id 由于 hive 并行运行任务 我们如何在不影响 hadoop 性能的情况下生成唯一键作为选择查
  • 需要处理来自非活动(.java)类的点击

    我有一个主要的 Activity 类 其中包含大量代码 数据 所以我想让它简短易读 所以我想创建一个 java 文件来根据要求处理一些功能 喜欢 Button b Button findviewById R id b1 b setOnCli
  • Android 应用程序 CPU 使用率高

    我正在编写一个应用程序 该应用程序必须在较长时间内执行高 CPU 使用率的操作 该操作像服务一样启动 但是android系统因为CPU使用率高而杀死了该应用程序 那么我该怎么做才能减少CPU使用率呢 并使系统不停止我的服务 服务 impor
  • 登录不应该是 GraphQL 中的查询吗?

    In the tutorial在 GraphQL 身份验证上 login is a Mutation type Mutation post url String description String Link signup email St
  • Android 双向滚动

    这更多的是一个大众答案而不是一个问题 我只是不知道如何发布它 版主如果你能告诉我是否有这样的事情 这个问题被问死了 然后我需要做类似的事情 所以我解决了这个问题 这篇文章的答案是如何在android中创建3x3双向滚动视图 下面是如何创建双
  • 如何将 data.frame 列从 Factor 转换为数字 [重复]

    这个问题在这里已经有答案了 我有一个data frame谁的班级栏是Factor 我想将其转换为数字 以便我可以使用相关矩阵 gt str breast data frame 699 obs of 10 variables class Fa
  • 此 linq 代码中的多个 orderby

    如何添加第二个商品来订购 我也想按 goalScored 元素排序 var theteams from teams in xdoc Descendants team orderby int teams Element points desc
  • 使用 Java 在 PostgreSQL 中存储时间的最推荐方法是什么?

    我在 PostgreSQL 数据库中存储两个日期 第一个是网页的访问数据 第二个日期是网页的最后修改日期 这是一个长整型 我有些怀疑存储这些值的最佳策略是什么 我只需要日 月 年和小时 秒 这仅用于统计建议 那么 有些疑问 最好存储尽可能长