0

I have two localDate to convert: 2022-11-02 and 0001-01-01

I am using the same method:

Date.from(myLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant())

LocatDate 2022-11-02 is fine with result 2022-11-02T04:00:00.000+00.00

However 0001-01-01 will be 0001-01-03T05:17:32.000+00.00

Is that because 0001-01-01 is not a valid date? How can I convert it to 0001-01-01T04:00:00.000+00.00?

feiyechen
  • 101
  • 1
  • 5
  • Does this answer your question? [Minimum date in Java](https://stackoverflow.com/questions/3838242/minimum-date-in-java) – OldProgrammer Dec 28 '22 at 21:27
  • 1
    You should tell us the result of calling `ZoneId.systemDefault`. – Basil Bourque Dec 28 '22 at 22:16
  • 2
    Time zones are a modern invention. I don’t see any logic or purpose in projecting a time zone across millennia. – Basil Bourque Dec 28 '22 at 22:18
  • 3
    You should probably rethink the way you've designed your program. It seems very odd that you want to convert things to `Date` when you're using the `java.time` classes. It seems even odder that your program somehow wants to care about what time of day it is, on 1 January 1 CE. This suggests to me that you're probably using either `Date` or `LocalDate` for something that it was never intended to be used for. So, what actual problem are you trying to solve here? Perhaps converting `LocalDate` to `Date` doesn't need to be part of the solution. – Dawood ibn Kareem Dec 28 '22 at 22:53
  • It is the difference between the Julian calendar that `Date` uses and the proleptic Gregorian calendar he `LocalDate` uses. 0001-01-01 is a valid date in both, but not the same date. Plus, as others said, the time zone offset. It seems that it was once -05:17:32 for your default time zone.If this is the case, why don’t you want it?? – Ole V.V. Dec 29 '22 at 06:01
  • Which result would you want if run in a time zone that uses summer time (DST)? Where the UTC offset for November 2 may even be different from year to year depending on when the summer time transition happens? – Ole V.V. Dec 29 '22 at 06:06
  • Related: [Java: How to get the timestamp of '1000-01-01 00:00:00' in UTC?](https://stackoverflow.com/questions/57992234/java-how-to-get-the-timestamp-of-1000-01-01-000000-in-utc) – Ole V.V. Dec 29 '22 at 11:08

1 Answers1

2

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API.

From your question, I concluded that your time-zone offset is -04:00. You can apply the fixed offset to achieve what you want.

Demo:

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.stream.Stream;

class Main {
    public static void main(String[] args) {
        Stream.of("2022-11-02", "0001-01-01")
                .map(LocalDate::parse)
                .map(date -> date.atStartOfDay())
                .map(ldt -> ldt.atOffset(ZoneOffset.of("-04:00")))
                .map(odt -> odt.withOffsetSameInstant(ZoneOffset.UTC))
                .map(OffsetDateTime::toInstant)
                .forEach(System.out::println);
    }
}

Output:

2022-11-02T04:00:00Z
0001-01-01T04:00:00Z

For the formatted output, you can use DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx") as shown below:

class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx", Locale.ENGLISH);
        Stream.of("2022-11-02", "0001-01-01")
                .map(LocalDate::parse)
                .map(date -> date.atStartOfDay())
                .map(ldt -> ldt.atOffset(ZoneOffset.of("-04:00")))
                .map(odt -> odt.withOffsetSameInstant(ZoneOffset.UTC))
                .map(odt -> odt.format(formatter))
                .forEach(System.out::println);
    }
}

Output:

2022-11-02T04:00:00.000+00:00
0001-01-01T04:00:00.000+00:00

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

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110