为什么Java 8 java.time类缺少getMillis()方法?


64

Java 8在java.time包中提供了一个用于日期和时间的全新库,这对于以前必须使用JodaTime或使其成为自己的日期处理助手方法而感到烦恼的人来说,是一件非常受欢迎的事情。该程序包中的许多类都表示时间戳,并具有一些辅助方法,例如getHour()从时间戳获取小时,从时间戳getMinute()获取分钟,从时间戳getNano()获取nano等。

我注意到他们没有一种方法getMillis()来获取时间戳的毫秒数。相反,必须调用method get(ChronoField.MILLI_OF_SECOND)。在我看来,这似乎是图书馆中的矛盾之处。有谁知道为什么缺少这种方法,或者由于Java 8仍在开发中,是否有可能稍后再添加呢?

https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html

此处定义的类代表主要的日期时间概念,包括瞬间,持续时间,日期,时间,时区和时间段。它们基于ISO日历系统,这是遵循通用格里高利规则的事实世界日历。所有的类都是不可变的并且是线程安全的。

每个日期时间实例均由API方便提供的字段组成。对于较低级别的字段访问,请参考java.time.temporal软件包。每个类都支持打印和解析各种日期和时间。请参阅java.time.format软件包以获取自定义选项...

此类示例:https :
//docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html

ISO-8601日历系统中没有时区的日期时间,例如2007-12-03T10:15:30。

LocalDateTime是一个不变的日期时间对象,代表一个日期时间,通常被视为年-月-日-时-分-秒。也可以访问其他日期和时间字段,例如,一年中的某天,一周中的某天和一周中的某周。时间以纳秒精度表示。例如,值“ 2nd October 2007 at 13:45.30.123456789”可以存储在LocalDateTime...中


似乎他们想使用多态性来解析一堆都称为的方法get(),而不是给它们单独的唯一名称。如果您不满意,请编写一个继承原始类的类,然后将您自己的getMillis()方法放在新类中。
罗伯特·哈维

@RobertHarvey java.time包中的大多数类都是不可变的,不能进行扩展。
assylias 2014年

2
@RobertHarvey对我来说,问题不是我该如何解决。这只是一个奇怪的矛盾,我想知道是否对此有一个有趣的解释。
Tarmo 2014年

我的想法是某些架构/ OS无法可靠地支持毫秒。换句话说,系统时间不能以毫秒为单位,而只能以毫秒或分秒为单位。
Marco Marco

stackoverflow.com/a/23945792/40064上的方式通过做Instant
维姆Deblauwe

Answers:


63

JSR-310基于纳秒,而不是毫秒。因此,最小的明智方法集基于小时,分钟,秒和纳秒。拥有十亿分之一秒的决定是该项目的最初决定之一,我坚信这一决定是正确的。

添加毫微秒的方法将与纳秒的方法重叠是一种非显而易见的方法。用户将不得不考虑例如纳米场是纳秒级还是毫微米级。添加一个令人迷惑的附加方法是不可取的,因此省略了该方法。如所指出的,替代方案get(MILLI_OF_SECOND)是可用的。

FWIW,我反对getMillis()将来添加该方法。


1
对于这个问题,我已经得到了很好的答案,但是您的回答是我最喜欢的,因为它很简短,但是仍然很有意义,确实使我相信这种方法的必要性。谢谢。
Tarmo 2014年

12
@ s3ib如果您查看应答者的个人资料,您还会注意到他是您要查询 API 的规范负责人。这使它成为权威的答案:)
gna14年

因此,必须要做的instant.getEpochSecond * 1000 + instant.getNano / 1000000是能够与遗留的Java API,Javascript等进行通信的样板?
nilskp 2014年

10
没有,在这种情况下,你可以使用instant.toEpochMilli()download.java.net/jdk8/docs/api/java/time/...
JodaStephen

20

在加入openJDK之前,Threeten在github上,在此之前在sourceforge上。那时,jsr-310的规范负责人Stephen Colebourne进行了一项调查,您仍然可以在sourceforge网站上找到该调查。

The fourth question on the survey covered the method names for LocalTime:
1) getHourOfDay(), getMinuteOfHour(), getSecondOfMinute(), getNanoOfSecond()
2) getHour(), getMinute(), getSecond(), getNanoOfSecond()
3) getHour(), getMinute(), getSecond(), getNano()
4) another idea

只有6.23%的人选择了答案4,其中大约15%的人要求getMillis(),即不到总选票的1%。

这可能就是为什么一开始就没有的原因,getMillis而我在openjdk邮件列表中找不到任何相关内容,因此此事之后显然没有讨论。


3
我认为,给人们几个选择,即使他们的理想选择是“其他”,也更有可能选择其中一个。我可能是错的。
Allon Guralnek 2014年

2
@AllonGuralnek肯定是的-但是,毫秒组件在Date API中非常重要,因为自该时期以来,所有内容都基于许多毫秒。在新的API中,与IMO的相关性较低。在大多数使用情况下,您需要第二精度或最高精度(nanos)。我可能是错的。
assylias 2014年

1
这似乎是在询问方法的命名,而不是应该存在哪些方法。
svick

1
是的,对不起,我不清楚:我的意思是调查中的问题,即该问题与该问题没有直接关系。
svick

15

代表明确的UTC时间的类(即Instant,OffsetDateTime,ZonedDateTime)具有两个帮助程序方法,用于访问Java纪元的绝对偏移量,即在java.util.Date中称为“毫秒时间”的方法,您可以使用达到毫秒

long getEpochSecond()
int getNano()

1000L*getEpochSecond() + getNano() / 1000000L;

在jsr 310邮件列表long getEpochMillis()中讨论了为什么选择了它而不是选择它的一些原因,为方便起见,我提取了其中的一些原因:

假设毫秒精度不够是合理的。但是,任何大于纳秒精度的东西似乎都是过分的

...

为了实现这一点,我的首选选项是64位长秒(有符号)+ 32位int纳秒(无符号)。

...

我更喜欢将拆分设置为第二级,因为这是科学中SI的官方时间单位,也是最普遍认可的标准。

由于无法处理level秒,因此在天数级拆分对于即时而言是有问题的。以毫秒为单位进行拆分,同时与Java的其余部分更好地集成,这看起来确实很奇怪。另外,它会在支持的范围内丢失。

按照提议,在第二秒分裂会产生超过2900亿年的纳秒范围。虽然没有人应该在时间范围内使用该精度,但我建议它比阻止它更容易支持。在天数级上拆分对于瞬间来说是有问题的,因为它无法处理leap秒

我感觉到另一个原因是有意使从java.util.Date转换为JSR310类变得困难,希望开发人员将尝试理解各种选项之间的差异,而不仅仅是盲目地(错误地)使用新类。

关于LocalDateTime类为什么没有这些方法的原因-它们可能在那里不存在,因为LocalDateTime在确定您所在的区域或UTC偏移量之前,它不依赖于UTC时间轴,此时您将拥有一个OffsetDateTimeZonedDateTime(两者都有所需的方法)。

另外,您可以定义自己的LOCAL_EPOCH常量to 1970-01-01T00:00:00,然后执行a MILLIS.between(LOCAL_EPOCH, localTime)以获取某种持续时间(以毫秒为单位)。但是,该值将不会与System.currentTimeMilliseconds()或返回的任何值兼容java.util.Date.getTime(),除非您将本地时间定义为UTC时间。但是在这种情况下,您最好直接使用Instant或将OffsetDateTime与ZoneOffset.UTC一起使用。


4
它们不可能在那里存在,因为LocalDateTime没有与UTC时间轴联系在一起 ” => LocalDateTime当然可以具有一种getMillis基本上可以返回的方法getNanos()/1e6-它不是即时的事实并不能阻止它具有毫秒的事实零件。
assylias 2014年

2
我感觉到另一个原因是有意使从java.util.Date转换为JSR310类变得困难。 ”与较旧的Java API,Javascript等进行通信时,这种疏忽确实是一件麻烦事。
nilskp 2014年

在顶部您的代码段是不正确-你需要用1000乘以getEpochSecond
铁皮人

@nilskp他们是两回事。问题getMillis()以getMillis-of-second的形式询问;您所说的是“时代以来的千里眼”。如公认的答案所述,前者不存在。后者已经可以作为Instant.toEpochMillis()。因此,对于a LocalDateTime,您将去:ldt.toInstant(offset).toEpochMillis()
SusanW
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.