127

如何从orLong的实例中提取纪元值?我尝试了以下方法,但它给了我其他结果:LocalDateTimeLocalDate

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本地 datetime的值"04.02.2014 19:51:01"。我的时区是Europe/OsloUTC+1 夏令时。

4

6 回答 6

179

LocalDateLocalDateTime不包含有关时区时间偏移的信息,如果没有这些信息,自纪元以来的秒数将是模棱两可的。但是,这些对象有几种方法可以通过传递ZoneId实例将它们转换为带有时区的日期/时间对象。

本地日期

LocalDate date = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = date.atStartOfDay(zoneId).toEpochSecond();

本地日期时间

LocalDateTime time = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = time.atZone(zoneId).toEpochSecond();
于 2014-04-10T15:36:42.110 回答
33

'Millis since unix epoch' 代表一个瞬间,所以你应该使用 Instant 类:

private long toEpochMilli(LocalDateTime localDateTime)
{
  return localDateTime.atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();
}
于 2016-11-21T11:20:19.787 回答
11

您需要的转换需要与 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();
于 2014-04-11T14:38:39.980 回答
2

查看此方法以查看支持哪些字段。你会发现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 字段,因为 aLocalDateTime不能引用任何绝对(全局)时间戳。但有用的是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 = 自 1970-01-01T00:00:00 以来的 1391543461 秒(注意,没有时区)然后您可以减去时区偏移量(如果以毫秒为单位,请注意可能乘以 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();
于 2014-04-10T14:09:32.750 回答
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

于 2018-04-13T03:34:19.017 回答
0

这是不使用时区的一种方法:

LocalDateTime now = LocalDateTime.now();
long epoch = (now.getLong(ChronoField.EPOCH_DAY) * 86400000) + now.getLong(ChronoField.MILLI_OF_DAY);
于 2019-11-13T15:16:13.093 回答