如何从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
我想要的只是本地日期时间1391539861
的值"04.02.2014 19:51:01"
。
我的时区为Europe/Oslo
UTC + 1,夏令时。
答案 0 :(得分:109)
课程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();
答案 1 :(得分:19)
&#39; Millis自从unix epoch&#39;代表一个瞬间,所以你应该使用Instant类:
private long toEpochMilli(LocalDateTime localDateTime)
{
return localDateTime.atZone(ZoneId.systemDefault())
.toInstant().toEpochMilli();
}
答案 2 :(得分:8)
您需要的转换需要UTC / Greewich或时区的偏移量。
如果您有偏移量,LocalDateTime
上有long epochSec = localDateTime.toEpochSecond(zoneOffset);
来执行此任务:
ZoneId
如果您只有ZoneOffset
,那么您可以从ZoneId
获取ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);
:
ZonedDateTime
但您可以通过long epochSec = ldt.atZone(zoneId).toEpochSecond();
更简单地找到转换:
{{1}}
答案 3 :(得分:1)
查看this method以查看支持哪些字段。你会找到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
字段INSTANT_SECONDS当然是不受支持的,因为LocalDateTime
不能引用任何绝对(全局)时间戳。但有用的是字段EPOCH_DAY,它计算自1970-01-01以来经过的天数。类似的想法对于LocalDate
类型有效(支持的字段更少)。
如果您打算获取不存在的millis-since-unix-epoch字段,您还需要时区来从本地类型转换为全局类型。这种转换可以更加简单,请参阅其他SO-posts。
回到您的问题和代码中的数字:
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秒自1970-01-01T00:00:00(注意,没有时区) 然后你可以减去时区偏移量(注意可能的乘法乘以1000,如果以毫秒为单位)。
在给定时区信息后更新:
local time = 1391543461 secs
offset = 3600 secs (Europe/Oslo, winter time in february)
utc = 1391543461 - 3600 = 1391539861
作为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();
答案 4 :(得分:0)
从 人类可读日期转换为纪元 :
long epoch = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;
从 纪元转换为人类可读日期 :
String date = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").format(new java.util.Date (epoch*1000));
对于其他语言转换器: https://www.epochconverter.com
答案 5 :(得分:0)
这是不占用时间的一种方式:
LocalDateTime now = LocalDateTime.now();
long epoch = (now.getLong(ChronoField.EPOCH_DAY) * 86400000) + now.getLong(ChronoField.MILLI_OF_DAY);