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:
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.
Look at this method to see which fields are supported. You will find for 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_DAY which counts the elapsed days since 1970-01-01. Similar thoughts are valid for the type LocalDate
(with even less supported fields).
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.
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).
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:
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();
'Millis since unix epoch' represents an instant, so you should use the Instant class:
private long toEpochMilli(LocalDateTime localDateTime)
{
return localDateTime.atZone(ZoneId.systemDefault())
.toInstant().toEpochMilli();
}
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
The conversion you need requires the offset from UTC/Greewich, or a time-zone.
If you have an offset, there is a dedicated method on LocalDateTime
for this task:
long epochSec = localDateTime.toEpochSecond(zoneOffset);
If you only have a ZoneId
then you can obtain the ZoneOffset
from the ZoneId
:
ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);
But you may find conversion via ZonedDateTime
simpler:
long epochSec = ldt.atZone(zoneId).toEpochSecond();
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);
Source: Stackoverflow.com