How to get milliseconds from LocalDateTime in Java

2019-01-10 03:47发布

问题:

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();

回答1:

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();


回答2:

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

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



回答3:

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!



回答4:

Since Java 8 you can use

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

which gives you the same results as

final long currentTimeJava1 = System.currentTimeMillis();


回答5:

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



回答6:

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.



回答7:

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);

Thanks!