【问题标题】:Using TIMESTAMP (?) for date-time durations with Java and MySQL将 TIMESTAMP (?) 用于 Java 和 MySQL 的日期时间持续时间
【发布时间】:2016-05-29 17:59:13
【问题描述】:

此时我正在使用 MySQL 数据库的 Java 应用程序中定义我的数据。我需要的一种数据是日期/时间段。我需要在日期时间存储添加量。

否则我打算使用 Java LocalDateTime 和 MySQL 的 TIMESTAMP 数据类型来存储日期/时间。我计划使用Java Timestamp 函数转换LocalDateTime

我可以在 MySQL TIMESTAMP 中存储句点吗?它将如何处理“1 天 3 小时 6 分钟”作为TIMESTAMP(不处于一个时代)?如果没有,我正在使用的 Java 方法有什么效果? TIA。

详情编辑添加: 这是供本地使用的,每个发行版在一个时区。 PC 上的 Java 应用程序是通过我的 Java GUI 捕获和查看LocalDateTime 的地方,所需的粒度不会小于几分钟。然后,它们以TIMESTAMP 的形式存储在数据库中。

周期将存储在数据库中的“班次模板”表中,作为一个班次循环中每个班次相对于模板零点的开始和结束时间段。通过循环处理这些班次模板记录,我将计算从给定的开始日期时间到提前几个月的所有“班次”记录(在 Java 中)。

使用示例: 此示例模板将定义 12 小时轮班,白天和黑夜,8 天,4 名工作人员,每个工作 4 天,然后 4 天休息(此模板表中有 16 条记录)。所有值都是调用者零点的附加值。每个预设模板记录包含:

  • 班次加额
  • 班次开始的时间-日期添加量
  • 班次结束的时间-日期添加量
  • 班次的工作人员标识符

网格模板(记录)
(时间段显示为 DD:hh:mm)
班次 01: 00:00:00 – 00:12:00,机组 A
班次 02:00:12:00 – 01:00:00,机组 B
班次 03:01:00:00 – 01:12:00,机组 A

班次 09: 04:00:00 – 04:12:00,机组 C
10 班:04:12:00 – 05:00:00,机组 D
…(直到 16 班)

接下来是我想从上述模板记录集中生成的班次记录,以 06/01/2016 06:00 为例,开始日期时间(或零点),带有:

  • 班次号码
  • 班次开始日期时间
  • 班次结束日期时间
  • 班次的船员标识符

Shift(记录)
(日期时间显示为 MM/DD/YYYY hh:mm)
班次 01:06/01/2016 06:00 – 06/01/2016 18:00,机组 A
班次 02:06/01/2016 18:00 – 06/02/2016 06:00,机组 B
班次 03:06/02/2016 06:00 – 06/02/2016 18:00,机组 A

班次 09:06/05/2016 06:00 – 06/05/2016 18:00,机组 C
10 班:2016 年 6 月 5 日 18:00 – 2016 年 6 月 6 日 06:00,船员 D

17 班:06/09/2016 06:00 – 06/09/2016 18:00,机组 A
班次 18:06/09/2016 18:00 – 06/10/2016 06:00,机组 B

班次 25:2016 年 6 月 13 日 06:00 – 2016 年 6 月 13 日 18:00,船员 C
26 班:2016 年 6 月 13 日 18:00 – 2016 年 6 月 14 日 06:00,船员 D

从“偏移”到“句号”从头到尾进行了编辑,并进行了一些澄清

【问题讨论】:

  • 对我来说,将时间偏移存储为整数似乎是最直观的。然后该值将对应于分钟/秒/毫秒的数量(取决于您需要的粒度)。如果您需要以其他时间单位表示偏移量,则转换是简单的算术。
  • @MickMnemonic Java 代码将定义粒度。你将如何从 Java 中获取/放置整数?
  • 如果不了解您的应用程序,很难回答,但是通过TimeUnit 枚举在 Java 中进行转换很简单。
  • @MickMnemonic 如果您编写了一个使用LocalDateTimeTimeUnitint 相互转换的简单示例,其中只保留几分钟,我很乐意接受作为答案。
  • 你能打开领域模型和用例吗?您是否将时间戳或时间偏移作为输入,即在将数据存储到数据库之前需要计算什么?

标签: java mysql date


【解决方案1】:

“偏移”是错误的术语

在日期时间工作中,术语“偏移”通常是指从 UTC 偏移。偏移量是 UTC 线前方(东)或后方(西)的小时、分钟和秒数。时区是一组规则,用于处理对偏移量的调整,以处理诸如夏令时 (DST) 之类的异常情况。

您需要的术语是“经过”来跟踪某些开始和停止时刻之间发生的时间量。

间隔

要跟踪从开始和停止的原始两个时刻,可以 (a) 创建自己的区间类,存储一对 InstantZonedDateTime 对象,或者 (b) 在 @ 中使用 Interval 类扩展 java.time 类的 987654322@ 项目(310 是 the JSR defining java.time 的编号)。

持续时间

要跟踪未附加到时间线的时间跨度,请使用 Duration 类。请参阅Oracle Tutorial on Period and Duration。持续时间跟踪总秒数加上以纳秒为单位的几分之一秒。

Instant start = Instant.now();
Thread.sleep( 5000 ); // Milliseconds of sleep.
Instant stop = Instant.now();

Duration duration = Duration.between( start , stop );

java.time 类默认使用ISO 8601 标准格式来解析和生成字符串作为其日期时间值的文本表示。在一段时间内,该标准使用 P1DT3H6M 之类的格式表示“1 天 3 小时 6 分钟”。 P 标记开始(句点),T 将天与小时-分钟-秒分开。您可以存储这些字符串,因为它们可以由 java.time 轻松处理。但他们当然不会自然而然地排序。

如果您需要对持续时间的长度进行排序或查询,我建议在数据库中写入一个整数来表示持续时间的总分钟数(您声明的粒度)。您可以致电Duration::toMinutes() 获取该总数。

由于您关心特定日期和特定时间跨度,您不应该使用Local… 类型。 Local… 类型专门丢失时区信息。如果没有时区信息,您将无法处理夏令时 (DST) 和其他异常情况。对于Local… 类型,假设所有的日子都是24 小时,这在不同时区的现实生活中是不正确的。而是在 Java 中使用 ZonedDateTime 类型,以及接近 SQL 标准的 TIMESTAMP WITH TIME ZONE 的数据库类型

问题的其余部分让我无法理解,因为您谈论“移位模板”和“零点”而让我迷失了方向。但我的直觉告诉我,由于不了解处理日期时间数据的有效方法,您工作太辛苦了。日期时间处理棘手的。我建议做更多的研究,比如在 Stack Overflow 上搜索和阅读“java date”相关的问题。

【讨论】:

  • 感谢您抽出宝贵的时间,巴兹尔。我已经将“偏移”重新编辑为“期间”,并针对您所说的进行了一些其他澄清。这是真的 - 我必须了解更多,PeriodDuration 看起来像是我需要关注的地方。之后,就是我如何在数据库中存储/检索这些时期。
  • @MarkMeyers 更多关于术语的信息……虽然“偏移”通常以一致的方式使用,但其他日期时间术语却不是。特别是“期间”、“持续时间”、“间隔”和其他时间跨度术语没有普遍同意的用法。矛盾使用的一个例子:ISO 8601 规范显然称为“持续时间”的格式以P 开头,我假设它来自单词period。在 java.time 中,Period 类用于年-月-日,而Duration 用于日-小时-分钟-秒。我曾经读过一篇尝试正式指定日期时间术语的文章,但没有找到后续行动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 2021-12-21
  • 2020-07-15
相关资源
最近更新 更多