【问题标题】:Best way to store time in java, in format of HH:MM在 java 中存储时间的最佳方式,格式为 HH:MM
【发布时间】:2013-11-01 18:45:56
【问题描述】:

在进行研究后,我找不到应该用于变量的方法或数据类型,以便以 HH:MM 格式存储时间,我确实找到了从“14”之类的字符串中获取此信息的方法:15:10",但我认为这不是最好的方法,因为我需要增加或减少时间。我尝试将其作为double 执行此操作,但遇到了以下问题,当您有时间像 05.45 存储并添加 0.15(或 15 分钟)时,结果是 05.60 与 HH:MM 格式一样你会期望它是 06.00。

我查看了 java 文档,现在仍然是,但似乎找不到任何方法来实现这一点,我最接近的是 date 格式,如 dd/mm/yyyy hh:mm:ss

【问题讨论】:

  • 为什么要将它们存储为HH:MM 格式?为什么不将它们存储在 long 值中,然后在需要时将其转换为您喜欢的格式?
  • 你存放在哪里?
  • @Laf 我现在确定我正在编写的程序只需要使用 HH:MM 格式,这对我来说只是一个有趣的项目来学习 java ;)
  • @tieTYT 在一个名为 time 的变量中,当我创建一个对象时,它从一个“t”参数中获取它。
  • 我会将日期存储在他们的long 表示中,正如@Sebastiaan 所建议的那样。从长远来看,以任何自定义格式存储它们会给您带来更多麻烦。

标签: java time types


【解决方案1】:

使用Joda Time。与标准 java 日期相比,它提供了更好的日期/时间操作操作。如果要使用内部 JDK 类,请使用java.util.Date

【讨论】:

  • 我是 Java 新手,想先学习所有标准,然后再深入研究新事物;)
  • 我编辑了我的答案以包含对标准 Date 类的引用。
  • 是的,这就是我尝试过的,但它给了我很多比我需​​要的更多,因为我正在寻找一种 HH:MM 格式,我知道这听起来很奇怪,但这就是我需要它的方式那一刻。
  • 两者之间没有太多的东西。如果要将日期表示为带有内部日期类的字符串,请使用 Date 和 DateFormat 进行解析。
  • 在这种情况下,我如何处理减法和加法,例如问题中的示例。
【解决方案2】:

从 Java 8 开始,您可以对日期和时间使用新的 API,包括 Instant、ZonedDateTime 和 LocalDateTime。这消除了对第三方库 Joda 时间的使用。它还使计算更加容易和正确。下面的建议有点过时,但仍有一些优点。

————

您绝对不应该做的是以您自己的自定义格式存储它们。存储表示 Unix Epoch 的 Long 值。

日期时间对计算机来说只不过是一个数字。此数字表示自 1970-01-01 00:00:00 UTC 以来的秒数(或毫秒)。解释为什么普遍选择此日期超出了此答案的范围,但您可以通过搜索 Unix Epoch 或阅读 http://en.wikipedia.org/wiki/Unix_time 来找到它。

这也意味着 DateTime 本身没有存储时区信息。在推理日期和时间时,记住这一点很重要。对于诸如比较 DateTime 对象之类的事情,不涉及本地化或时区。只有在格式化时间(这意味着使其对人类可读)或者对于诸如获取一天的开始之类的操作时,时区才会发挥作用。

这也是为什么您不应该将时间(如 20:11:15)存储为类似字符串的格式,因为如果没有时区信息,此信息将毫无意义。我将在这里举一个例子:考虑时钟向后移动 1 小时的时刻,例如远离夏令时的时刻。它只是发生在很多国家。你的字符串 02:30 代表什么?第一个还是第二个?

减法之类的计算就像对数字做同样的事情一样简单。例如:Date newDate = new Date(date1.getTime() - date2.getTime());。或者想在日期上增加一个小时? Date newDate = new Date(oldDate.getTime() + 1000 * 60 * 60);

如果您需要更复杂的东西,那么使用 Joda 时间将是一个好主意,正如已经建议的那样。但是,即使使用本机库也完全有可能做到这一点。

如果有一个资源教会了我很多关于日期/时间的知识,那就是http://www.odi.ch/prog/design/datetime.php

【讨论】:

  • 问题是,日期我不能(或者至少我不知道如何)处理时间的加法和减法,因此它可以正确处理,请参阅我在问题中提到的示例。
  • 减法就像从一个数字中减去一个数字一样简单。例如:date1.getTime() - date2.getTime()
【解决方案3】:

Java 有java.sql.Time 格式来处理时间值。只需导入它并创建变量。

import java.sql.Time;

//now we can make time variables
Time myTime;

刚刚在https://db.apache.org/derby/docs/10.4/ref/rrefsqlj21908.html看到它

【讨论】:

    【解决方案4】:

    适合您的情况的答案取决于您想做什么。

    • 您是否使用 RDBMS 作为持久性引擎?
    • 如果是这样,您是否已经在使用旧数据格式,或者您是否正在从头开始构建数据库?
    • 您只是存储这些数据,还是进行大量的日期算术和/或优先级计算?
    • 您是在一个时区还是需要跨多个时区处理时间瞬间?

    所有这些都很重要,并且会影响您决定如何表示您的时间和日期。

    如果您的需求需要大量的日期运算(例如,确定日期之间的天数)或根据时间戳进行排序,那么请考虑使用浮点日期格式。使用数字格式的时间戳的优点是进行日期算术和比较/排序操作变得微不足道;你只做简单的算术。另一个优点是浮点数和长整数是原始数据类型。它们不需要序列化,它们已经非常轻量级,使用它们所需的一切都不需要外部依赖。

    使用数字格式作为时间戳的主要缺点是它们对人类不友好。您需要将它们转换为字符串格式或从字符串格式转换以允许用户进行交互。通常,这是值得的努力。见:How do I use Julian Day Numbers with the Java Calendar API?

    我建议您考虑将时间戳存储为儒略日数字 (JDN) 或修改的儒略日数字 (MJD)。两者都将使用 8 字节浮点数以毫秒精度表示日期和时间。这两种显示格式的转换算法是高度标准化的。它们赋予使用数字日期的所有优点。此外,它们仅针对 GMT/UTC 定义,这意味着您的时间戳已经开箱即用地跨时区通用(只要您正确本地化)。

    【讨论】:

      【解决方案5】:

      如果您不想要完整的date 对象,最好将其存储在字符串中,但我个人仍然推荐date,因为它还包含许多方便的方法,可以派上用场。您可以从 date 对象中获取整个时间,而忽略其余部分。

      【讨论】:

      • Date 主要是一个简单的包装器,用于表示为 UTC 长的时间戳。直接使用longs比Dates有一定的优势。
      • true,但由于它是一个简单的包装器,它不会降低性能,但它确实为您添加了可能有帮助的功能 - 但可以肯定的是,如果他不需要任何这些,“长”即使不是更好也一样好
      • 不使用Dates 的一个重要原因是它们是可变的,因此很复杂并且不是线程安全的。 'long' 是不可变的,并且始终是线程安全的。
      • 你说得完全正确,我想把它放长一点是更好的选择。
      【解决方案6】:

      就“存储”日期而言,您应该使用long。这就是系统如何看待它以及如何执行所有计算。是的,正如某些人指出的那样,您最终将需要创建一个 String 以便人类可以阅读它,但是人们遇到麻烦的地方是当他们开始考虑格式方面的日期时。格式是为了可读性,而不是为了计算。 java.util.Datejava.util.Calendar 充满了问题(Effective Java,Bloch,et. al. 对此有很多话要说),但如果您需要,它们仍然是常态方便的日期操作。

      【讨论】:

      • 实际上,Effective Java 对 Java 日历 API 几乎没有什么可说的。 Date 类被用作一个应该被设为不可变但不是的类的示例,并且在讨论如何安全地发布可变对象时使用了几个Dates。关于 Calendar 对象唯一提到的是它们“创建起来特别昂贵”。事实上,如果只需要将数字时间戳本地化到特定时区,Java 日历 API 就非常适合这项任务。
      猜你喜欢
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 2020-10-25
      • 2012-07-15
      • 1970-01-01
      • 2013-12-26
      • 2014-07-28
      • 2015-08-31
      相关资源
      最近更新 更多