How can I create a Java 8 LocalDate from a long Epoch time in Milliseconds?
Solution 1
If you have the milliseconds since the Epoch and want to convert them to a local date using the current local timezone, you can use
LocalDate date =
Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();
but keep in mind that even the system’s default time zone may change, thus the same long
value may produce different result in subsequent runs, even on the same machine.
Further, keep in mind that LocalDate
, unlike java.util.Date
, really represents a date, not a date and time.
Otherwise, you may use a LocalDateTime
:
LocalDateTime date =
LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault());
Solution 2
You can start with Instant.ofEpochMilli(long):
LocalDate date =
Instant.ofEpochMilli(startDateLong)
.atZone(ZoneId.systemDefault())
.toLocalDate();
Solution 3
I think I have a better answer.
new Timestamp(longEpochTime).toLocalDateTime();
Solution 4
Timezones and stuff aside, a very simple alternative to new Date(startDateLong)
could be LocalDate.ofEpochDay(startDateLong / 86400000L)
Solution 5
A simple version based on @Michael Piefel answer:
LocalDate myDate = LocalDate.ofEpochDay(Duration.ofMillis(epochMillis).toDays());
Related videos on Youtube
Vihung
Basic b*tch Java Web Applications Developer - Spring Boot, AWS, Angular, Bootstrap. Mac and iPhone user. Highly opinionated about Design/User Experience/Usability.
Updated on March 11, 2022Comments
-
Vihung about 2 years
I have an external API that returns me dates as
long
s, represented as milliseconds since the beginning of the Epoch.With the old style Java API, I would simply construct a
Date
from it withDate myDate = new Date(startDateLong)
What is the equivalent in Java 8's
LocalDate
/LocalDateTime
classes?I am interested in converting the point in time represented by the
long
to aLocalDate
in my current local timezone.-
Jon Skeet over 8 yearsWell you have to start by working out what time zone you care about. A "milliseconds since epoch" value gives you an instant in time... that could refer to different dates in different time zones. Bear in mind that
java.util.Date
was never really a date in the way thatLocalDate
is - it was an instant in time as well. -
hotzst over 8 yearsCheck this question: stackoverflow.com/questions/21242110/…, which covers the conversion of
java.util.Date
intoLocalDate
-
kevinarpe about 7 yearsNote: This Q&A is also valuable for those trying to convert
File.lastModified()
(epoch millis) toLocalDate(Time)
. -
Georgios Syngouroglou over 3 yearsDoes this answer your question? How to get milliseconds from LocalDateTime in Java 8
-
Mark Rotteveel over 3 years@GeorgeSiggouroglou That questions asks the opposite of this question, so it is not a duplicate.
-
Georgios Syngouroglou over 3 years@MarkRotteveel you are correct, I hurried, I removed the vote to close.
-
-
Basil Bourque over 8 years+1 for being explicit about time zone. If omitted, the JVM’s current default time zone is implicitly applied in determining the date. For any given moment the date varies around the world by time zone as a new day dawns earlier in the east.
-
Meno Hochschild over 8 years+1 from me for more detailed explanation. By the way, even a non-system zone can change (by tzupdater-tool or by jdk-change) and hence produce different results before and after.
-
Holger over 8 years@Meno Hochschild: I wasn’t focusing on hardcoded timezones but rather comparing with timezones specified by the user, read from a configuration file or environment variables, where the programmer naturally assumes that the may change. Hardcoded timezones are indeed much like the system default; the programmer is tempted into thinking they were never changing…
-
BAERUS almost 7 yearsI think you should at least explain what the 86400000L stands for.
-
Michael Piefel almost 7 yearsI thought it was very easy to spot that it’s the number of milliseconds in a day.
-
BAERUS almost 7 yearsFor some it is, and I figured that only that would make sense, but without recalculation how many ms a day really has, I wouldn't be sure. Just speaking for myself, I don't know this number so well that I automatically know what it stands for.
-
Michael Piefel almost 7 yearsNote also that the accepted answer really is the best answer, it just looks overwhelming. My simple hack just my be enough in many case. It’s a pity that
java.time
does not includeDateTimeConstants
as Joda did. -
Vadzim about 6 years
java.util.concurrent.TimeUnit.MILLISECONDS.toDays(startDateLong)
-
Demigod almost 6 yearsCan I use
LocalDateTime.ofEpochSecond()
with, for examplemilliseconds / 1000
? -
Holger almost 6 years@Demigod you can, when you think specifying a
ZoneOffset
is better than specifying aZoneId
(you can not useZoneId.systemDefault()
anymore, or at least not without converting it for a particularInstant
, but when you have anInstant
, why not useLocalDateTime.ofInstant
…). -
Demigod almost 6 years@holger, I have a long (millis). Why ZoneId.systemDefault() cannot be used?
-
Holger almost 6 years@Demigod
LocalDateTime.ofEpochSecond(…)
requires an actualZoneOffset
, butZoneId.systemDefault()
returns aZoneId
. AZoneId
can map to different offsets, depending on the point of time you’re referring to. That’s whatLocalDateTime.ofInstant
does for you, converting the specifiedZoneId
according to the providedInstant
. -
Mihai Morcov over 5 yearsI came hoping to find a more readable solution than this, what a downgrade from the old java.util approach....
-
Holger over 5 years@MihaiMorcov it’s exactly the problem of the “old java.util approach” that it didn’t handle the semantic difference between a local data-time and a long value representing an instant.
-
Stepan Yakovenko over 5 yearsnew Timestamp(ts).toLocalDateTime().toLocalDate()
-
PlexQ over 5 yearsEpoch is defined as UTC and should be therefore be timezone independent, so the ZoneId should always be UTC.
-
PlexQ over 5 yearsI mean - if you don't mind importing javal.sql.Timestamp, which, given Java's monolithic nature I suppose is fine because it's just all part of the JVM... but feels a bit smelly, but I still like it better as it recognized epoch is fundamentally in UTC.
-
Holger over 5 years@PlexQ The specified timezone is not relevant for the Epoch, which indeed is timezone independent, but for the semantics of the resulting
LocalDate
orLocalDateTime
. You can specify any timezone you want, as long as it is consistent with the subsequent use of these result objects. Think of what happens when you deal with multiple objects created by different methods. The typical use cases for local date or datetimes incorporate the system default timezone, e.g.LocalDateTime.now()
≈LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault())
… -
fjjiaboming about 5 yearsSome ZoneID miss nanosecond and millisecond.
-
Holger about 5 years@fjjiaboming there are no nanoseconds in the epochmillis in the first place. For any other loss of precision, name an actual example.
-
Ole V.V. over 4 yearsThe
Timestamp
class is poorly designed and long outdated. Your code will use the JVM’s time zone setting, but since this setting can be changed by another part of your program or another program running in the same JVM, we cannot be quite sure what it is. -
Ruslan over 4 yearsIt's always better to be explicit about which timezone is used. Using the old java.sql.Timestamp has the drawback of having the system timezone applied implicitly which usually causes confusion among developers.
-
Ketan R over 4 yearsThis does not really relate much to the asked question
-
M. Prokhorov over 4 years@KetanR, I disagree. The question is "how to obtain a
LocalDate
fromepoch-millis
", and I show how, usingjava.sql.Date
for shorthand. This approach makes sense in code that's already dealing with JDBC in some capacity, and it works just fine. If you still not convinced, explain how is it not related to initial question. -
Ketan R over 4 yearsIf you read the question, it says "external API that returns me dates as longs" and you are explaining how this conversion can be done if you are receiving long date from SQL. Your answer does explain a very specific case of the date conversion but its not really relevant to question that has been ask ed.Your explanation could be a valid answer to some other related quesiton though.
-
M. Prokhorov over 4 years@KetanR, if one receives long date from SQL, I'd advise to change his schema so he no longer receives dates in such form. However, if one receives dates as millis-timestamps from elsewhere (the external API), and immediately uses these dates to make JDBC queries, then
java.sql.Date
approach is among the shortest available, code-wise, and I'd say it's not all that useful to go thoughInstant
with all the intermediate temporal objects when the end result is the same. -
Ketan R over 4 yearsAs i have already said and is evident from your latest explanation, your answer is correct but not for the question at hand Question says: "I am interested in converting the point in time represented by the long to a LocalDate in my current local timezone. " your answer tells: "receive dates as millis-timestamps, and immediately use these dates to make JDBC queries". I dont understand what is not clear here ?
-
Pryftan almost 4 years@MihaiMorcov Agreed. What a nightmare. I am converting some really old code and I wanted a simple way to use the long value of a file last mod date and I have to do all this? A real shame.
-
Holger almost 4 years@Pryftan “to use the long value of a file last mod date” is a very unspecific task. Are you sure you actually need a
LocalDate
? Maybe whatever you actually want to do with the long value, can be done with theInstant
created viaInstant.ofEpochMilli(longValue)
too. -
Holger about 2 years@PlexQ Java is not monolithic anymore. To use
java.sql.Timestamp
when using modules, you have to declare a dependency to the modulejava.sql
, which will in turn introduce dependencies tojava.xml
andjava.logging
. -
PlexQ about 2 years@Holger True, though I haven't seen anyone building on anything above Java 11 in the wild yet.
-
Holger about 2 years@PlexQ well, the modularization has been introduced in Java 9.