Java 如何从 LocalDate 和 LocalDateTime 中提取纪元?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22990067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract epoch from LocalDate and LocalDateTime?
提问by
How do I extract the epoch value to Long
from instances of LocalDateTime
or LocalDate
? I've tried
the following, but it gives me other results:
如何Long
从LocalDateTime
或 的实例中提取纪元值LocalDate
?我尝试了以下方法,但它给了我其他结果:
LocalDateTime time = LocalDateTime.parse("04.02.2014 19:51:01", DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
System.out.println(time.getLong(ChronoField.SECOND_OF_DAY)); // gives 71461
System.out.println(time.getLong(ChronoField.EPOCH_DAY)); // gives 16105
What I want is simply the value 1391539861
for the local datetime "04.02.2014 19:51:01"
.
My timezone is Europe/Oslo
UTC+1 with daylight saving time.
我想要的只是1391539861
本地 datetime的值"04.02.2014 19:51:01"
。我的时区是Europe/Oslo
UTC+1 夏令时。
采纳答案by nosid
The classes LocalDate
and LocalDateTime
do not contain information about the timezoneor time offset, and seconds since epoch would be ambigious without this information. However, the objects have several methods to convert them into date/time objects with timezones by passing a ZoneId
instance.
类LocalDate
和LocalDateTime
不包含有关时区或时间偏移的信息,如果没有此信息,则自纪元以来的秒数将不明确。但是,这些对象有多种方法可以通过传递ZoneId
实例将它们转换为带时区的日期/时间对象。
LocalDate
本地日期
LocalDate date = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = date.atStartOfDay(zoneId).toEpochSecond();
LocalDateTime
本地日期时间
LocalDateTime time = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = time.atZone(zoneId).toEpochSecond();
回答by Meno Hochschild
Look at this methodto see which fields are supported. You will find for LocalDateTime
:
查看此方法以查看支持哪些字段。你会发现LocalDateTime
:
?NANO_OF_SECOND
?NANO_OF_DAY
?MICRO_OF_SECOND
?MICRO_OF_DAY
?MILLI_OF_SECOND
?MILLI_OF_DAY
?SECOND_OF_MINUTE
?SECOND_OF_DAY
?MINUTE_OF_HOUR
?MINUTE_OF_DAY
?HOUR_OF_AMPM
?CLOCK_HOUR_OF_AMPM
?HOUR_OF_DAY
?CLOCK_HOUR_OF_DAY
?AMPM_OF_DAY
?DAY_OF_WEEK
?ALIGNED_DAY_OF_WEEK_IN_MONTH
?ALIGNED_DAY_OF_WEEK_IN_YEAR
?DAY_OF_MONTH
?DAY_OF_YEAR
?EPOCH_DAY
?ALIGNED_WEEK_OF_MONTH
?ALIGNED_WEEK_OF_YEAR
?MONTH_OF_YEAR
?PROLEPTIC_MONTH
?YEAR_OF_ERA
?YEAR
?ERA
The field INSTANT_SECONDS is - of course - not supported because a LocalDateTime
cannot refer to any absolute (global) timestamp. But what is helpful is the field EPOCH_DAYwhich counts the elapsed days since 1970-01-01. Similar thoughts are valid for the type LocalDate
(with even less supported fields).
INSTANT_SECONDS 字段 - 当然 - 不受支持,因为 aLocalDateTime
不能引用任何绝对(全局)时间戳。但有用的是字段EPOCH_DAY,它计算自 1970-01-01 以来经过的天数。类似的想法适用于该类型LocalDate
(支持更少的字段)。
If you intend to get the non-existing millis-since-unix-epoch field you also need the timezone for converting from a local to a global type. This conversion can be done much simpler, see other SO-posts.
如果您打算获取不存在的millis-since-unix-epoch 字段,您还需要将时区从本地类型转换为全局类型。这种转换可以更简单地完成,请参阅其他SO-posts。
Coming back to your question and the numbers in your code:
回到你的问题和代码中的数字:
The result 1605 is correct
=> (2014 - 1970) * 365 + 11 (leap days) + 31 (in january 2014) + 3 (in february 2014)
The result 71461 is also correct => 19 * 3600 + 51 * 60 + 1
16105L * 86400 + 71461 = 1391543461 seconds since 1970-01-01T00:00:00 (attention, no timezone) Then you can subtract the timezone offset (watch out for possible multiplication by 1000 if in milliseconds).
16105L * 86400 + 71461 = 1391543461 秒自 1970-01-01T00:00:00(注意,无时区)然后你可以减去时区偏移(注意可能乘以 1000,如果以毫秒为单位)。
UPDATE after given timezone info:
给定时区信息后更新:
local time = 1391543461 secs
offset = 3600 secs (Europe/Oslo, winter time in february)
utc = 1391543461 - 3600 = 1391539861
As JSR-310-code with two equivalent approaches:
作为具有两种等效方法的 JSR-310 代码:
long secondsSinceUnixEpoch1 =
LocalDateTime.of(2014, 2, 4, 19, 51, 1).atZone(ZoneId.of("Europe/Oslo")).toEpochSecond();
long secondsSinceUnixEpoch2 =
LocalDate
.of(2014, 2, 4)
.atTime(19, 51, 1)
.atZone(ZoneId.of("Europe/Oslo"))
.toEpochSecond();
回答by JodaStephen
The conversion you need requires the offset from UTC/Greewich, or a time-zone.
您需要的转换需要与 UTC/Greewich 或时区的偏移量。
If you have an offset, there is a dedicated methodon LocalDateTime
for this task:
如果你有一个偏移,有一个专门的方法在LocalDateTime
此任务:
long epochSec = localDateTime.toEpochSecond(zoneOffset);
If you only have a ZoneId
then you can obtain the ZoneOffset
from the ZoneId
:
如果您只有一个,ZoneId
那么您可以ZoneOffset
从以下位置获取ZoneId
:
ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);
But you may find conversion via ZonedDateTime
simpler:
但是您可能会发现通过ZonedDateTime
更简单的转换:
long epochSec = ldt.atZone(zoneId).toEpochSecond();
回答by Werner Harnisch
'Millis since unix epoch' represents an instant, so you should use the Instant class:
'Millis since unix epoch' 代表一个瞬间,所以你应该使用 Instant 类:
private long toEpochMilli(LocalDateTime localDateTime)
{
return localDateTime.atZone(ZoneId.systemDefault())
.toInstant().toEpochMilli();
}
回答by michmich
Convert from human readable date to epoch:
从人类可读日期转换为纪元:
long epoch = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;
Convert from epoch to human readable date:
从纪元转换为人类可读的日期:
String date = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").format(new java.util.Date (epoch*1000));
For other language converter: https://www.epochconverter.com
其他语言转换器:https: //www.epochconverter.com
回答by aled evans
This is one way without using time a zone:
这是一种不使用时区的方法:
LocalDateTime now = LocalDateTime.now();
long epoch = (now.getLong(ChronoField.EPOCH_DAY) * 86400000) + now.getLong(ChronoField.MILLI_OF_DAY);