Georgios Syngouroglou
Georgios Syngouroglou

Reputation: 20004

How to get milliseconds from LocalDateTime in Java 8

I am wondering if there is a way to get current milliseconds since 1-1-1970 (epoch) using the new LocalDate, LocalTime or LocalDateTime classes of Java 8.

The known way is below:

long currentMilliseconds = new Date().getTime();

or

long currentMilliseconds = System.currentTimeMillis();

Upvotes: 440

Views: 633403

Answers (15)

BenjyTec
BenjyTec

Reputation: 10972

In case of LocalDate, you can use the toEpochDay() method. It returns the number of days since 01/01/1970. That number then can be easily converted to milliseconds:

long dateInMillis = TimeUnit.DAYS.toMillis(myLocalDate.toEpochDay());

In case of LocalDateTime, you can use the toEpochSecond() method. It returns the number of seconds since 01/01/1970. That number then can be converted to milliseconds, too:

long dateTimeInMillis = TimeUnit.SECONDS.toMillis(myLocalDateTime.toEpochSecond());

Upvotes: 6

AgilePro
AgilePro

Reputation: 5614

Simplest conversion:

Instant.from(localDateTime).toEpochMilli()

SORRY this does not work and gies the following error:

"Unsupported field: InstantSeconds",
"  java.base/java.time.LocalDate.get0(LocalDate.java:708)",
"  java.base/java.time.LocalDate.getLong(LocalDate.java:687)",
"  java.base/java.time.LocalDateTime.getLong(LocalDateTime.java:720)",
"  java.base/java.time.Instant.from(Instant.java:373)",
"  com.capitalone.rupol.ruleengine.util.LocalDateSerializer.serialize(LocalDateSerializer.java:25)",
"Unable to obtain Instant from TemporalAccessor: 2024-02-03T00:00 of type java.time.LocalDateTime",
"  java.base/java.time.Instant.from(Instant.java:378)",
"  com.capitalone.rupol.ruleengine.util.LocalDateSerializer.serialize(LocalDateSerializer.java:25)",
"  com.capitalone.rupol.ruleengine.util.LocalDateSerializer.serialize(LocalDateSerializer.java:11)",
"  com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeOptionalFields(MapSerializer.java:869)",
"  com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:760)",

The LocalDateTime does not carry a time zone. The Instant does not carry a time zone. Strangely, many of the other conversions require specifying a time zone that you don't need. This avoids using a time zone offset at any step, and converts internally from millis to millis.

It is strange that the LocalDateTime does not offer a conversion to Instant, since both LocalDateTime and Instant do not involve any representation of a time zone, but this factory method does the job.

Upvotes: 0

JianrongChen
JianrongChen

Reputation: 206

I think this is more simpler:

ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());
Assert.assertEquals(System.currentTimeMillis(), zdt.toInstant().toEpochMilli());

get the millis like System.currentTimeMillis() (from UTC).

Upvotes: 6

Marina DU
Marina DU

Reputation: 111

For LocalDateTime I do it this way:

LocalDateTime.of(2021,3,18,7,17,24,341000000)
    .toInstant(OffsetDateTime.now().getOffset())
    .toEpochMilli()

Upvotes: 5

ognjenkl
ognjenkl

Reputation: 1477

Date and time as String to Long (millis):

String dateTimeString = "2020-12-12T14:34:18.000Z";

DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);

LocalDateTime localDateTime = LocalDateTime
        .parse(dateTimeString, formatter);

Long dateTimeMillis = localDateTime
        .atZone(ZoneId.systemDefault())
        .toInstant()
        .toEpochMilli();

Upvotes: 4

Md. Kamruzzaman
Md. Kamruzzaman

Reputation: 1905

You can try this:

long diff = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli();

Upvotes: 14

brian
brian

Reputation: 10989

What I do so I don't specify a time zone is,

System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("ctm " + System.currentTimeMillis());

gives

ldt 1424812121078 
ctm 1424812121281

As you can see the numbers are the same except for a small execution time.

Just in case you don't like System.currentTimeMillis, use Instant.now().toEpochMilli()

Upvotes: 150

maxxyme
maxxyme

Reputation: 2344

Why didn't anyone mentioned the method LocalDateTime.toEpochSecond():

LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);

This seems way shorter that many suggested answers above...

Upvotes: 7

Nalam
Nalam

Reputation: 314

You can use java.sql.Timestamp also to get milliseconds.

LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);

Upvotes: 15

Mohamed.Abdo
Mohamed.Abdo

Reputation: 2200

  default LocalDateTime getDateFromLong(long timestamp) {
    try {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
    } catch (DateTimeException tdException) {
      //  throw new 
    }
}

default Long getLongFromDateTime(LocalDateTime dateTime) {
    return dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli();
}

Upvotes: 2

Marteng
Marteng

Reputation: 1305

Since Java 8 you can call java.time.Instant.toEpochMilli().

For example the call

final long currentTimeJava8 = Instant.now().toEpochMilli();

gives you the same results as

final long currentTimeJava1 = System.currentTimeMillis();

Upvotes: 26

JeeBee
JeeBee

Reputation: 17556

If you have a Java 8 Clock, then you can use clock.millis() (although it recommends you use clock.instant() to get a Java 8 Instant, as it's more accurate).

Why would you use a Java 8 clock? So in your DI framework you can create a Clock bean:

@Bean
public Clock getClock() {
    return Clock.systemUTC();
}

and then in your tests you can easily Mock it:

@MockBean private Clock clock;

or you can have a different bean:

@Bean
public Clock getClock() {
    return Clock.fixed(instant, zone);
}

which helps with tests that assert dates and times immeasurably.

Upvotes: 4

Dani
Dani

Reputation: 4131

To avoid ZoneId you can do:

LocalDateTime date = LocalDateTime.of(1970, 1, 1, 0, 0);

System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());

Getting 0 as value, that's right!

Upvotes: 23

Anubian Noob
Anubian Noob

Reputation: 13596

To get the current time in milliseconds (since the epoch), use System.currentTimeMillis().

Upvotes: 14

Stuart Marks
Stuart Marks

Reputation: 132610

I'm not entirely sure what you mean by "current milliseconds" but I'll assume it's the number of milliseconds since the "epoch," namely midnight, January 1, 1970 UTC.

If you want to find the number of milliseconds since the epoch right now, then use System.currentTimeMillis() as Anubian Noob has pointed out. If so, there's no reason to use any of the new java.time APIs to do this.

However, maybe you already have a LocalDateTime or similar object from somewhere and you want to convert it to milliseconds since the epoch. It's not possible to do that directly, since the LocalDateTime family of objects has no notion of what time zone they're in. Thus time zone information needs to be supplied to find the time relative to the epoch, which is in UTC.

Suppose you have a LocalDateTime like this:

LocalDateTime ldt = LocalDateTime.of(2014, 5, 29, 18, 41, 16);

You need to apply the time zone information, giving a ZonedDateTime. I'm in the same time zone as Los Angeles, so I'd do something like this:

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));

Of course, this makes assumptions about the time zone. And there are edge cases that can occur, for example, if the local time happens to name a time near the Daylight Saving Time (Summer Time) transition. Let's set these aside, but you should be aware that these cases exist.

Anyway, if you can get a valid ZonedDateTime, you can convert this to the number of milliseconds since the epoch, like so:

long millis = zdt.toInstant().toEpochMilli();

Upvotes: 465

Related Questions