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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:49:10  来源:igfitidea点击:

How to extract epoch from LocalDate and LocalDateTime?

javatimejava-8epochjava-time

提问by

How do I extract the epoch value to Longfrom instances of LocalDateTimeor LocalDate? I've tried the following, but it gives me other results:

如何LongLocalDateTime或 的实例中提取纪元值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 1391539861for the local datetime "04.02.2014 19:51:01". My timezone is Europe/OsloUTC+1 with daylight saving time.

我想要的只是1391539861本地 datetime的值"04.02.2014 19:51:01"。我的时区是Europe/OsloUTC+1 夏令时。

采纳答案by nosid

The classes LocalDateand LocalDateTimedo 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 ZoneIdinstance.

LocalDateLocalDateTime不包含有关时区时间偏移的信息,如果没有此信息,则自纪元以来的秒数将不明确。但是,这些对象有多种方法可以通过传递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 LocalDateTimecannot 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 LocalDateTimefor this task:

如果你有一个偏移,有一个专门的方法LocalDateTime此任务:

long epochSec = localDateTime.toEpochSecond(zoneOffset);

If you only have a ZoneIdthen you can obtain the ZoneOffsetfrom the ZoneId:

如果您只有一个,ZoneId那么您可以ZoneOffset从以下位置获取ZoneId

ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);

But you may find conversion via ZonedDateTimesimpler:

但是您可能会发现通过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);