Ratatosk
Ratatosk

Reputation: 91

How to use DateTime and Unix time in Java?

I'm making an application for Android in Android Studio with Java. I'm working with dates and times. I'm trying to produce a Unix timestamp from a custom given point in time. As an example, the following piece of code

LocalDateTime aDateTime = LocalDateTime.of(2021, 4, 30, 8, 30);
ZoneId zoneId = ZoneId.systemDefault();
int x = Math.toIntExact(aDateTime.atZone(zoneId).toEpochSecond());

produces a Unix timestamp 1619760600. However, when I enter this into any online converter, it produces a time of 04/30/2021 @ 5:30am (UTC). This is off by 3 hours from the original inserted time which is the exact amount in hours that my timezone differs from UTC00:00.

The problem seems to be my inability to understand timezones in Java. So my question is, how do I factor in the timezone correctly so that a correct UnixTimeStamp is produced?

Upvotes: 2

Views: 574

Answers (3)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79620

Do it as follows:

import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        LocalDateTime aDateTime = LocalDateTime.of(2021, 4, 30, 8, 30);
        ZoneId zoneIdUTC = ZoneId.of("UTC");
        ZoneId myZoneId = ZoneId.systemDefault();
        LocalDateTime bDateTime = aDateTime.atZone(zoneIdUTC).withZoneSameInstant(myZoneId).toLocalDateTime();
        System.out.println(bDateTime.atZone(myZoneId).toEpochSecond());
    }
}

Output:

1619771400

Try it at https://www.unixtimestamp.com/index.php

Upvotes: 0

Joni
Joni

Reputation: 111399

You already have the right timestamp.

Timestamps represent instants of time. Timezones matter only when you want to display a timestamp in a user's local time. In your case, 04/30/2021 @ 5:30am (UTC) is the same instant of time as 8:30am in your local time. See if the online tool you found can display the timestamp in your local time in addition to UTC.

You should stop using int for the timestamp though and use long instead https://en.m.wikipedia.org/wiki/Year_2038_problem

If you expected to create a timestamp for 8:30 UTC instead of 8:30 local time, just use the UTC timezone when creating zoned datetime:

LocalDateTime aDateTime = LocalDateTime.of(2021, 4, 30, 8, 30);
ZoneId zoneId = ZoneOffset.UTC;
long x = aDateTime.atZone(zoneId).toEpochSecond();

Upvotes: 2

miguelarc
miguelarc

Reputation: 800

You can take advantage of java.time API (assuming you are using Java 8). Here is an example, taking the info you have provided:

LocalDateTime localDateTime = LocalDateTime.of(2021, 4, 30, 8, 30);
ZonedDateTime zdt = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
long millis = zdt.toInstant().toEpochMilli();

You can find more info here. Hope it helps

Upvotes: 0

Related Questions