按天分组长UTC日期

时间:2009-03-24 12:46:43

标签: java utc

是否有一种合理的方法可以按天分组长UTC日期?

我会用86400修改它们,但这不会考虑闰秒。

有没有人有任何其他想法,我正在使用java,所以我可以将它们解析为Date Objects,但我有点担心使用日期类的性能开销。

还有比比较Date对象的年月和日部分更有效的方法吗?

3 个答案:

答案 0 :(得分:3)

您的源数据肯定是否包含闰秒开头?有些API可以,有些则没有 - 例如Joda Time(我建议使用内置的日期/时间API)doesn't use leap seconds。 Java“日期和时间”API“有时”可以 - 它们支持60和61作为“秒分钟”的值,但支持取决于操作系统(见下文)。如果你有一些好的样本值,我会先检查一下,如果我是你。显然,分裂比其他任何事情都简单。

如果您需要创建Date个对象(或Joda中的DateTime),我会先做基准测试,然后再做其他事情。你可能会发现性能实际上是完全足够的。浪费时间优化可以为您的数据提供的东西毫无意义。当然,您需要确定需要支持的数据大小,以及首先需要多快的数据:)

即使是java.util.Date对闰秒的支持也有点不确定。来自the docs

  

虽然Date类是打算的   反映协调的世界时   (UTC),它可能不会这样做,   取决于主机环境   Java虚拟机。几乎所有的   现代操作系统假设1   天= 24×60×60 = 86400秒   所有情况。然而,在UTC中,大约一次   每隔一两年就有一个额外的   第二,称为“闰秒”。该   闰秒总是被添加为   当天的最后一秒,并一直在   12月31日或6月30日。例如,   1995年的最后一分钟是   61秒,感谢添加   闰秒。大多数电脑时钟都是   不够准确无法做到   反映了闰秒的区别。

关于Java和闰秒的混乱有一个rather good blog post,您可能也想阅读它。

答案 1 :(得分:3)

  

我会用86400修改它们,但这不会考虑闰秒......

我很确定这样会好的。 Date的API文档实际上不应该包含任何关于闰秒的内容,因为事实是它模拟了一个标准的Unix时间标记,它的值不包含闰秒。 它的作用是通过在闰秒开始时将股票代码值设置为1秒来持续持续两秒钟的第59秒(如上一篇文章中的链接所述)。

因此,您可以假设从Date.getTime()获得的值仅由86400秒组成。如果你真的需要知道特定的日是否有闰秒,互联网上有几个表(自1972年以来只有23-24个,之前的计算机日期很少将它们带入帐户无论如何)。

HIH

温斯顿

答案 2 :(得分:0)

TL;博士

Instant.ofEpochSecond( 1_493_367_302L )            // Convert a count of whole seconds from epoch of 1970 into a date-time value in UTC.
       .atZone( ZoneId.of( "Pacific/Auckland" ) )  // Adjust into the time zone as a context for determining a date.
       .toLocalDate()                              // Extract a date-only value by which we can sort/collect/organize our date-time values.

时区

java.util.Date类表示UTC时间轴上的时刻。因此,要求它提供一个日期,这将使您的日期在UTC中有意义。同一时刻可能是魁北克早些时候的日期,也可能是新西兰奥克兰的日期。

时区对于确定日期至关重要,而您的问题忽略了此问题。

使用java.time

java.util.Date类是麻烦的旧日期时间类的一部分,这些类现在是遗留的,取而代之的是java.time类。

至于闰秒,正如其他Answers建议的那样,大多数来自时代的计数计算闰秒。所以验证您的来源。

如果您从1970-01-01T00:00:00的纪元开始计算整秒,则使用静态方法创建Instant对象。

Instant instant = Instant.ofEpochSecond( 1_493_367_302L ) ;
  

instant.toString():2017-04-28T08:15:02Z

指定时区以创建我们可以确定日期的上下文。对于任何特定时刻,日期因地区而异。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ); 
ZonedDateTime zdt = instant.atZone( z );
  

zdt.toString():2017-04-28T01:15:02-07:00 [America / Los_Angeles]

使用这些ZonedDateDate个对象,您可以按日期进行比较。您可以提取LocalDate对象。 LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate ld = zdt.toLocalDate();
  

ld.toString():2017-04-28

因此,您可以将Map作为关键字LocalDate ListSet ZonedDateTime作为值。使用现代lambda语法,您可以使用Streams进行映射。

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore