斯卡拉两个纪元日之间的天数

斯卡拉两个纪元日之间的天数

问题描述:

我有两个纪元时间戳,我试图找到两个时间戳之间的天数。斯卡拉两个纪元日之间的天数

这是我现在有:

dateFrom = inputEntry.getValue(inputFields(0).get).asInstanceOf[String].toLong 
dateTo =inputEntry.getValue(inputFields(1).get).asInstanceOf[String].toLong 

例子:

dateFrom dateTo  result 
1501583232 1501641000 1 
1501583232 1501986600 5 

我开始与这里有两个划时代日期

+2

可能的重复[获取天数,星期和月份,因为Epoch在Java](https://stackoverflow.com/questions/6158053/get-the-number-of-days-weeks-and-数月以来在java中的时代) –

+0

这不是重复的。这个问题从纪元秒数开始。 –

+0

这是真的,但它很容易通过从时间减去这两天的日期来计算两个日期之间的天数 –

TL;博士

ChronoUnit.DAYS.between(… , …) 

详细

Stack Overflow已经涵盖了很多次。所以在这里简单地...

对于日期时间值,使用日期时间对象。只使用java.time类,避免了麻烦的遗留日期 - 时间类(日期,日历等)。

您的意思是日期的差异或24小时的时间差异?

我会在这里约会。

首先,将自1970-01-01T00:00:00的时代参考日期以来的整秒数翻译为时间轴中UTC的点。

注意数字文字末尾的L以表示long而不是int。

Instant instant = Instant.ofEpochSecond(1_501_583_232L) ; 

指定您想考虑日期的时区。

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

转换为仅供日期使用。

LocalDate ld = zdt.toLocalDate() ; 

获取差异。

long days = ChronoUnit.DAYS.between(ld , ld2) ; 

要得到你想要的结果,你必须定义你将如何计算差异。

以你的第一示例(1501583232和1501641000之间的差值应为1天):

历元1501583232和1501641000是因为1970-01-01T00:00Z的秒数,因此它们是等效于以下UTC日期:

1501583232: 2017-08-01T10:27:12Z 
1501641000: 2017-08-02T02:30:00Z 

请注意,他们之间的差异是16小时2分48秒(如此,不到一天)。如果你在几天内获得差异,技术上它将为零。

但是如果你考虑日期(2017-08-012017-08-02)和忽略时间(小时/分/秒),则差值可以是0或1,这取决于你的时区。

如果您只考虑UTC日期(2017-08-012017-08-02),则差异为1天。

但如果你采取同样的UTC在America/Los_Angeles时区上面的日期,你会得到:

1501583232: 2017-08-01T03:27:12-07:00 
1501641000: 2017-08-01T19:30-07:00 

现在差​​为零天,如果你只考虑日期(均为2017-08-01)不管,或日期和时间(以小时计算的差值将是16日,小于一天)。所以,你必须定义你将如何计算差异(只考虑日期,或者同时考虑日期和时间,以及将使用什么时区)。


在你的情况,似乎你只考虑日期,而忽略了时间,但目前还不清楚它使用的是什么时区。无论如何,您可以使用JDK的8 new java.time API(对于JDK < = 7,您可以使用ThreeTen Backport - 下面的代码适用于两者。唯一的区别是软件包名称(在Java 8中为java.time和ThreeTen Backport(或Android的ThreeTenABP )是org.threeten.bp),但类别和方法名称是相同的)。

该代码基本上与@BasilBourque's answer相同,因为它对新API非常直接(我只是想添加上面的见解)。

首先,从时代价值创造Instant的:

Instant instant1 = Instant.ofEpochSecond(1501583232L); 
Instant instant2 = Instant.ofEpochSecond(1501641000L); 

如果你想考虑的日期和时间的差异,你可以使用:

ChronoUnit.DAYS.between(instant1, instant2); 

结果将是零。

如果你想只考虑UTC日期(而忽略时间),只是做:

// convert to UTC and get just the date (day/month/year) 
LocalDate d1 = instant1.atZone(ZoneOffset.UTC).toLocalDate(); 
LocalDate d2 = instant2.atZone(ZoneOffset.UTC).toLocalDate(); 
long days = ChronoUnit.DAYS.between(d1, d2); 

的结果为1

要转换到不同的时区(而不是UTC),使用ZoneId类:

// use a specific timezone 
ZoneId zone = ZoneId.of("Asia/Kolkata"); 
// convert the Instant to a timezone and get only the date 
LocalDate d1 = instant1.atZone(zone).toLocalDate(); 
LocalDate d2 = instant2.atZone(zone).toLocalDate(); 
long days = ChronoUnit.DAYS.between(d1, d2); 

在这种情况下,差为1,但正如我上面所说的,不同的时区可以产生不同的效果(可以是零或1 - 例如,将上面的代码更改为ZoneId.of("America/Los_Angeles"),结果为零)。


注意,API使用IANA timezones names(总是在格式Region/City,像Asia/KolkataEurope/Berlin)。 避免使用3字母缩写(如CSTIST),因为它们是ambiguous and not standard

通过调用ZoneId.getAvailableZoneIds(),您可以获得可用时区列表(并选择最适合您的系统的时区)。

您也可以使用系统的默认时区ZoneId.systemDefault(),但即使在运行时也可以在不通知的情况下对其进行更改,因此最好使用特定的时区。