Scala 中两个纪元日之间的天数
Number of days between two epoch days in scala
我有两个纪元时间戳,我想找出这两个时间戳之间的天数。
这是我现在拥有的:
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
我从这里的两个纪元日期开始
tl;博士
ChronoUnit.DAYS.between( … , … )
详情
这已在 Stack Overflow 上多次介绍。在这里简单介绍一下……
对于日期时间值,使用日期时间对象。仅使用 java.time 类,避免麻烦的遗留日期时间 类(日期、日历等)。
您是指日期差异还是 24 小时时间块差异?
我会在这里选择日期。
首先,将似乎是从纪元参考日期 1970-01-01T00:00:00Z 开始的整秒数转换为 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-01
和2017-08-02
)而忽略时间( hour/minute/second),则差异可以为零或 1,具体取决于您所在的时区。
如果只考虑 UTC 日期(2017-08-01
和 2017-08-02
),则相差 1 天。
但是,如果您在 America/Los_Angeles
时区采用相同的 UTC 日期,您将得到:
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 for that (for JDK <= 7 you can use the ThreeTen Backport - 下面的代码适用于两者。唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes 和方法 names 相同)。
代码与 基本相同,因为它与新的 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
class:
// 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/Kolkata
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 IST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.
获取可用时区列表(并选择最适合您的系统的时区)
您还可以将系统的默认时区与 ZoneId.systemDefault()
一起使用,但这可以在不通知的情况下更改,即使在运行时也是如此,因此最好明确使用特定的时区。
我有两个纪元时间戳,我想找出这两个时间戳之间的天数。
这是我现在拥有的:
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
我从这里的两个纪元日期开始
tl;博士
ChronoUnit.DAYS.between( … , … )
详情
这已在 Stack Overflow 上多次介绍。在这里简单介绍一下……
对于日期时间值,使用日期时间对象。仅使用 java.time 类,避免麻烦的遗留日期时间 类(日期、日历等)。
您是指日期差异还是 24 小时时间块差异?
我会在这里选择日期。
首先,将似乎是从纪元参考日期 1970-01-01T00:00:00Z 开始的整秒数转换为 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-01
和2017-08-02
)而忽略时间( hour/minute/second),则差异可以为零或 1,具体取决于您所在的时区。
如果只考虑 UTC 日期(2017-08-01
和 2017-08-02
),则相差 1 天。
但是,如果您在 America/Los_Angeles
时区采用相同的 UTC 日期,您将得到:
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 for that (for JDK <= 7 you can use the ThreeTen Backport - 下面的代码适用于两者。唯一的区别是包名称(在 Java 8 中是 java.time
,在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp
),但是 classes 和方法 names 相同)。
代码与
首先,您根据纪元值创建 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
class:
// 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/Kolkata
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 IST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.
您还可以将系统的默认时区与 ZoneId.systemDefault()
一起使用,但这可以在不通知的情况下更改,即使在运行时也是如此,因此最好明确使用特定的时区。