是否有一种合理的方法可以按天分组长UTC日期?
我会用86400修改它们,但这不会考虑闰秒。
有没有人有任何其他想法,我正在使用java,所以我可以将它们解析为Date Objects,但我有点担心使用日期类的性能开销。
还有比比较Date对象的年月和日部分更有效的方法吗?
答案 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)
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.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/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的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
List
或Set
ZonedDateTime
作为值。使用现代lambda语法,您可以使用Streams进行映射。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。