Home > Software engineering >  Converting LocalDateTime to Instant give different values
Converting LocalDateTime to Instant give different values

Time:01-24

I am trying to use LocalDateTime to manipulate dates in my application but I have noticed that getting epoch seconds from it returns different values from what I expected

val now1 = Instant.now().epochSecond - 60
val now2 = Instant.now().minusSeconds(60).epochSecond
val now3 = LocalDateTime.now().minusSeconds(60).toEpochSecond(ZoneOffset.UTC)
val now4 = System.currentTimeMillis() / 1000 - 60

Output

Now1 = 1674501451
Now2 = 1674501451
Now3 = 1674512251
Now4 = 1674501451

Notice how Now3 has a different value. What is happening?

CodePudding user response:

You need to use LocalTime#now(ZoneId zone) with ZoneOffset.UTC in order to get the local time at UTC; otherwise, the system picks up the local time of system's timezone.

Demo:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;

class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        var now1 = TimeUnit.SECONDS.convert(now.toEpochMilli(), TimeUnit.MILLISECONDS) - 60;
        var now2 = TimeUnit.SECONDS.convert(now.minusSeconds(60).toEpochMilli(), TimeUnit.MILLISECONDS);
        var now3 = LocalDateTime.now(ZoneOffset.UTC).minusSeconds(60).toEpochSecond(ZoneOffset.UTC);
        var now4 = System.currentTimeMillis() / 1000 - 60;
        System.out.println(now1);
        System.out.println(now2);
        System.out.println(now3);
        System.out.println(now4);
    }
}

Output from a sample run:

1674506413
1674506413
1674506413
1674506413

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.

CodePudding user response:

tl;dr

  • Your JVM’s current default time zone is three hours ahead of UTC. Thus your result.
  • Related