java zoneddatetime toEpochSecond without converting to local time

5.1k views Asked by At

I have a dataset that is in EST time without any daylight saving. Each datetime is read from string and a zonedDatetime is created using

ZonedDateTime java.time.ZonedDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone)

with a ZoneId.of("America/New_York");

I need to convert these to an epoch second but the built in toEpochSecond method converts to my local time which is BST with day light saving. As a result the timestamps are four to five hours off depending on time of year. Is there a way to get a unix timestamp that does not take into account any local time so the timestamp matches the datetime in the original string?

2

There are 2 answers

2
DigitShifter On BEST ANSWER

To convert ZonedDateTime to Unix epoch time stamp

Convert first to java.time.Instant and then set zone offset to UTC, before converting it to epoch seconds, see below:

zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();

Note: The variable zonedDateTime is of type java.time.ZonedDateTime and can be in any time zone before converting it to "Unix epoch time stamp" in seconds.

0
Arvind Kumar Avinash On

I need to convert these to an epoch second but the built in toEpochSecond method converts to my local time which is BST with day light saving. As a result the timestamps are four to five hours off depending on time of year.

You must be doing something fundamentally wrong. Check the output of the following code and you will find that there is no difference.

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Formatter ignoring nanoseconds
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                        .appendPattern("uuuu-MM-dd'T'HH:mm:ssXXX")
                                        .optionalStart()
                                        .appendLiteral('[')
                                        .parseCaseSensitive()
                                        .appendZoneRegionId()
                                        .appendLiteral(']')
                                        .toFormatter(Locale.ENGLISH);

        // The given time-zone
        ZoneId zone = ZoneId.of("America/New_York");

        ZonedDateTime zdtNow = ZonedDateTime.now(zone);
        System.out.println(zdtNow.format(formatter));

        // Epoch seconds from ZonedDateTime
        long epochSecond = zdtNow.toEpochSecond();
        System.out.println(epochSecond);

        // ZonedDateTime from epoch seconds
        ZonedDateTime zdtFromEpochSeconds = Instant.ofEpochSecond(epochSecond).atZone(zone);
        System.out.println(zdtFromEpochSeconds.format(formatter));
    }
}

Output:

2020-09-28T17:31:23-04:00[America/New_York]
1601328683
2020-09-28T17:31:23-04:00[America/New_York]