Discrepancy when converting ancient dates between java.util.Date and java.time.Instant











up vote
4
down vote

favorite












I have legacy code that uses java.util.Date creating an ancient date (30 Nov 0002). I'm trying to update what code I can, but that's necessitating converting between Date and LocalDate, etc. I can't completely get rid of the use of Date or the ancient date choice.



I'm finding what appears to be an error when converting back and forth between Date and Instant with this ancient date, and was hoping someone could explain what is going on.



Here's a sample:



    Date date = new Date();
Instant instant = date.toInstant();
System.out.println("Current:");
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Date:");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("MST"));
cal.set(2, Calendar.NOVEMBER, 30, 0, 0, 0);
date = cal.getTime();
instant = date.toInstant();
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Instant:");
instant = Instant.parse("0002-11-30T00:00:00Z");
date = Date.from(instant);
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);


Which prints the following:



Current:
Date: Tue Sep 18 12:34:27 MST 2018
Instant: 2018-09-18T19:34:27.177Z
Date epoch: 1537299267177
Instant epoch: 1537299267000

Ancient from Date:
Date: Thu Nov 30 00:00:00 MST 2
Instant: 0002-11-28T07:00:00.247Z
Date epoch: -62075437199753
Instant epoch: -62075437200000

Ancient from Instant:
Date: Fri Dec 01 17:00:00 MST 2
Instant: 0002-11-30T00:00:00Z
Date epoch: -62075289600000
Instant epoch: -62075289600000


So if I create an Instant at 30 Nov 2, then convert to a Date, the Date is 1 Dec 2. If I start with a Date at 30 Nov 2, the Instant is 28 Nov 2. I'm aware that neither Date nor Instant store timezone information, but why are the epochs so different based on whether I started with a Date vs. an Instant? Is there anyway I can work around that? I need to be able to start with either a Date or an Instant, and end up with the same epoch value. It would also be nice to know why the default toString() shows such different dates given the same epoch.










share|improve this question




















  • 1




    You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
    – teppic
    Sep 18 at 20:22










  • The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
    – Ole V.V.
    Sep 18 at 20:27










  • @teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
    – Jeremy
    Sep 18 at 20:37










  • @OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
    – Jeremy
    Sep 18 at 20:37















up vote
4
down vote

favorite












I have legacy code that uses java.util.Date creating an ancient date (30 Nov 0002). I'm trying to update what code I can, but that's necessitating converting between Date and LocalDate, etc. I can't completely get rid of the use of Date or the ancient date choice.



I'm finding what appears to be an error when converting back and forth between Date and Instant with this ancient date, and was hoping someone could explain what is going on.



Here's a sample:



    Date date = new Date();
Instant instant = date.toInstant();
System.out.println("Current:");
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Date:");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("MST"));
cal.set(2, Calendar.NOVEMBER, 30, 0, 0, 0);
date = cal.getTime();
instant = date.toInstant();
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Instant:");
instant = Instant.parse("0002-11-30T00:00:00Z");
date = Date.from(instant);
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);


Which prints the following:



Current:
Date: Tue Sep 18 12:34:27 MST 2018
Instant: 2018-09-18T19:34:27.177Z
Date epoch: 1537299267177
Instant epoch: 1537299267000

Ancient from Date:
Date: Thu Nov 30 00:00:00 MST 2
Instant: 0002-11-28T07:00:00.247Z
Date epoch: -62075437199753
Instant epoch: -62075437200000

Ancient from Instant:
Date: Fri Dec 01 17:00:00 MST 2
Instant: 0002-11-30T00:00:00Z
Date epoch: -62075289600000
Instant epoch: -62075289600000


So if I create an Instant at 30 Nov 2, then convert to a Date, the Date is 1 Dec 2. If I start with a Date at 30 Nov 2, the Instant is 28 Nov 2. I'm aware that neither Date nor Instant store timezone information, but why are the epochs so different based on whether I started with a Date vs. an Instant? Is there anyway I can work around that? I need to be able to start with either a Date or an Instant, and end up with the same epoch value. It would also be nice to know why the default toString() shows such different dates given the same epoch.










share|improve this question




















  • 1




    You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
    – teppic
    Sep 18 at 20:22










  • The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
    – Ole V.V.
    Sep 18 at 20:27










  • @teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
    – Jeremy
    Sep 18 at 20:37










  • @OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
    – Jeremy
    Sep 18 at 20:37













up vote
4
down vote

favorite









up vote
4
down vote

favorite











I have legacy code that uses java.util.Date creating an ancient date (30 Nov 0002). I'm trying to update what code I can, but that's necessitating converting between Date and LocalDate, etc. I can't completely get rid of the use of Date or the ancient date choice.



I'm finding what appears to be an error when converting back and forth between Date and Instant with this ancient date, and was hoping someone could explain what is going on.



Here's a sample:



    Date date = new Date();
Instant instant = date.toInstant();
System.out.println("Current:");
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Date:");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("MST"));
cal.set(2, Calendar.NOVEMBER, 30, 0, 0, 0);
date = cal.getTime();
instant = date.toInstant();
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Instant:");
instant = Instant.parse("0002-11-30T00:00:00Z");
date = Date.from(instant);
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);


Which prints the following:



Current:
Date: Tue Sep 18 12:34:27 MST 2018
Instant: 2018-09-18T19:34:27.177Z
Date epoch: 1537299267177
Instant epoch: 1537299267000

Ancient from Date:
Date: Thu Nov 30 00:00:00 MST 2
Instant: 0002-11-28T07:00:00.247Z
Date epoch: -62075437199753
Instant epoch: -62075437200000

Ancient from Instant:
Date: Fri Dec 01 17:00:00 MST 2
Instant: 0002-11-30T00:00:00Z
Date epoch: -62075289600000
Instant epoch: -62075289600000


So if I create an Instant at 30 Nov 2, then convert to a Date, the Date is 1 Dec 2. If I start with a Date at 30 Nov 2, the Instant is 28 Nov 2. I'm aware that neither Date nor Instant store timezone information, but why are the epochs so different based on whether I started with a Date vs. an Instant? Is there anyway I can work around that? I need to be able to start with either a Date or an Instant, and end up with the same epoch value. It would also be nice to know why the default toString() shows such different dates given the same epoch.










share|improve this question















I have legacy code that uses java.util.Date creating an ancient date (30 Nov 0002). I'm trying to update what code I can, but that's necessitating converting between Date and LocalDate, etc. I can't completely get rid of the use of Date or the ancient date choice.



I'm finding what appears to be an error when converting back and forth between Date and Instant with this ancient date, and was hoping someone could explain what is going on.



Here's a sample:



    Date date = new Date();
Instant instant = date.toInstant();
System.out.println("Current:");
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Date:");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("MST"));
cal.set(2, Calendar.NOVEMBER, 30, 0, 0, 0);
date = cal.getTime();
instant = date.toInstant();
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);

System.out.println("nAncient from Instant:");
instant = Instant.parse("0002-11-30T00:00:00Z");
date = Date.from(instant);
System.out.println("Date: "+date);
System.out.println("Instant: "+instant);
System.out.println("Date epoch: "+date.getTime());
System.out.println("Instant epoch: "+instant.getEpochSecond()*1000);


Which prints the following:



Current:
Date: Tue Sep 18 12:34:27 MST 2018
Instant: 2018-09-18T19:34:27.177Z
Date epoch: 1537299267177
Instant epoch: 1537299267000

Ancient from Date:
Date: Thu Nov 30 00:00:00 MST 2
Instant: 0002-11-28T07:00:00.247Z
Date epoch: -62075437199753
Instant epoch: -62075437200000

Ancient from Instant:
Date: Fri Dec 01 17:00:00 MST 2
Instant: 0002-11-30T00:00:00Z
Date epoch: -62075289600000
Instant epoch: -62075289600000


So if I create an Instant at 30 Nov 2, then convert to a Date, the Date is 1 Dec 2. If I start with a Date at 30 Nov 2, the Instant is 28 Nov 2. I'm aware that neither Date nor Instant store timezone information, but why are the epochs so different based on whether I started with a Date vs. an Instant? Is there anyway I can work around that? I need to be able to start with either a Date or an Instant, and end up with the same epoch value. It would also be nice to know why the default toString() shows such different dates given the same epoch.







java date java-8






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 18 at 21:32









Stefan Zobel

2,44021828




2,44021828










asked Sep 18 at 19:47









Jeremy

6203818




6203818








  • 1




    You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
    – teppic
    Sep 18 at 20:22










  • The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
    – Ole V.V.
    Sep 18 at 20:27










  • @teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
    – Jeremy
    Sep 18 at 20:37










  • @OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
    – Jeremy
    Sep 18 at 20:37














  • 1




    You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
    – teppic
    Sep 18 at 20:22










  • The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
    – Ole V.V.
    Sep 18 at 20:27










  • @teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
    – Jeremy
    Sep 18 at 20:37










  • @OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
    – Jeremy
    Sep 18 at 20:37








1




1




You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
– teppic
Sep 18 at 20:22




You've got a rounding error. Don't use instant.getEpochSecond()*1000, use instant.toEpochMilli().
– teppic
Sep 18 at 20:22












The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
– Ole V.V.
Sep 18 at 20:27




The two frameworks don’t agree 100 % about details as leap years this far back in history. So you will need to make your requirements clear. If you have a Date a certain large number of days before the epoch, do you require an Instant the same number of days before the epoch? Or if you got a date of 30 Nov 2, do you require an Instant on 30 Nov 2? It’s not the same, sorry.
– Ole V.V.
Sep 18 at 20:27












@teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
– Jeremy
Sep 18 at 20:37




@teppic, thanks, I didn't notice that method there. For the purposes of the question, I didn't think the millisecond value mattered, although I can see how that muddies the example.
– Jeremy
Sep 18 at 20:37












@OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
– Jeremy
Sep 18 at 20:37




@OleV.V. The code I'm dealing with is using a magic date (let this be a lesson to you, kids), so I would like to have an instant and date go to the same 30 Nov 2 date, although I think I could make either of those options work. The trick is sometimes I'm starting with an Instant, and sometimes I'm starting with a Date. From your comment I take it that it's the leap years that's giving me grief...
– Jeremy
Sep 18 at 20:37












1 Answer
1






active

oldest

votes

















up vote
7
down vote



accepted










The discrepancy resides in how the implementations of Date and Instant interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.



The GregorianCalendar implementation has a special note:




Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.




Well, yes, technically speaking. But for this issue, we don't quite encounter this.



cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);


This yields a date, as expected, of October 4, 1582.



cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);


This yields a date, of October 15, 1582.



WHAT MAGIC IS THIS, BATMAN?



Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.




However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),




From Wikipedia on 1582



When we examine October 4, 1582, the following happens:




Date: 1582-Oct-04 00:00:00



Instant: 1582-10-14T00:00:00Z




There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.




The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).




SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.



Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.



If you are displaying historical event dates, you will be better off using a Date or JulianCalendar DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52393619%2fdiscrepancy-when-converting-ancient-dates-between-java-util-date-and-java-time-i%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote



    accepted










    The discrepancy resides in how the implementations of Date and Instant interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.



    The GregorianCalendar implementation has a special note:




    Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.




    Well, yes, technically speaking. But for this issue, we don't quite encounter this.



    cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);


    This yields a date, as expected, of October 4, 1582.



    cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);


    This yields a date, of October 15, 1582.



    WHAT MAGIC IS THIS, BATMAN?



    Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.




    However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),




    From Wikipedia on 1582



    When we examine October 4, 1582, the following happens:




    Date: 1582-Oct-04 00:00:00



    Instant: 1582-10-14T00:00:00Z




    There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.




    The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).




    SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.



    Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.



    If you are displaying historical event dates, you will be better off using a Date or JulianCalendar DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.






    share|improve this answer



























      up vote
      7
      down vote



      accepted










      The discrepancy resides in how the implementations of Date and Instant interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.



      The GregorianCalendar implementation has a special note:




      Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.




      Well, yes, technically speaking. But for this issue, we don't quite encounter this.



      cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);


      This yields a date, as expected, of October 4, 1582.



      cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);


      This yields a date, of October 15, 1582.



      WHAT MAGIC IS THIS, BATMAN?



      Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.




      However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),




      From Wikipedia on 1582



      When we examine October 4, 1582, the following happens:




      Date: 1582-Oct-04 00:00:00



      Instant: 1582-10-14T00:00:00Z




      There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.




      The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).




      SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.



      Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.



      If you are displaying historical event dates, you will be better off using a Date or JulianCalendar DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.






      share|improve this answer

























        up vote
        7
        down vote



        accepted







        up vote
        7
        down vote



        accepted






        The discrepancy resides in how the implementations of Date and Instant interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.



        The GregorianCalendar implementation has a special note:




        Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.




        Well, yes, technically speaking. But for this issue, we don't quite encounter this.



        cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);


        This yields a date, as expected, of October 4, 1582.



        cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);


        This yields a date, of October 15, 1582.



        WHAT MAGIC IS THIS, BATMAN?



        Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.




        However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),




        From Wikipedia on 1582



        When we examine October 4, 1582, the following happens:




        Date: 1582-Oct-04 00:00:00



        Instant: 1582-10-14T00:00:00Z




        There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.




        The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).




        SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.



        Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.



        If you are displaying historical event dates, you will be better off using a Date or JulianCalendar DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.






        share|improve this answer














        The discrepancy resides in how the implementations of Date and Instant interact with each other in relation to their implementations, with Date using Gregorian/Julian calendars and Instant using ISO standard for Date, which follow a modified Gregorian calendar prior to the Julian calendar switchover.



        The GregorianCalendar implementation has a special note:




        Before the Gregorian cutover, GregorianCalendar implements the Julian calendar. The only difference between the Gregorian and the Julian calendar is the leap year rule. The Julian calendar specifies leap years every four years, whereas the Gregorian calendar omits century years which are not divisible by 400.




        Well, yes, technically speaking. But for this issue, we don't quite encounter this.



        cal.set(1582, Calendar.OCTOBER, 4, 0, 0, 0);


        This yields a date, as expected, of October 4, 1582.



        cal.set(1582, Calendar.OCTOBER, 5, 0, 0, 0);


        This yields a date, of October 15, 1582.



        WHAT MAGIC IS THIS, BATMAN?



        Well, this isn't a coding error, it's actually an implementation of GregorianCalendar.




        However, this year saw the beginning of the Gregorian Calendar switch, when the Papal bull known as Inter gravissimas introduced the Gregorian calendar, adopted by Spain, Portugal, the Polish–Lithuanian Commonwealth and most of present-day Italy from the start. In these countries, the year continued as normal until Thursday, October 4. However, the next day became Friday, October 15 (like a common year starting on Friday),




        From Wikipedia on 1582



        When we examine October 4, 1582, the following happens:




        Date: 1582-Oct-04 00:00:00



        Instant: 1582-10-14T00:00:00Z




        There is a 10-day gap here, and the reason the instant exists on a "technically non-existent date" is accounted for by the definition of ISO instant dates.




        The standard states that every date must be consecutive, so usage of the Julian calendar would be contrary to the standard (because at the switchover date, the dates would not be consecutive).




        SO, whereas October 14, 1582 never existed in reality, it exists in ISO time by definition, but occurs on the real world's October 4, 1582 according to Julian Calendar.



        Due to what I assume are additional leap year drifts from the first paragraph, where Julian centuries 1500, 1400, 1300, 1100, 1000, 900, 700, 600, 500, 300, 200, 100 have extra leap days not accounted for in the Gregorian calendar, we slowly shift back from a +10 to a -1 offset. This can be verified by adjusting the year in +100 increments.



        If you are displaying historical event dates, you will be better off using a Date or JulianCalendar DateFormatter to display the correct correct historical date, as it actually occurred in history. Printing out the ISO time for historical periods may appear nonsensical or inaccurate, but storing the time in this format is still valid.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 20 at 14:32

























        answered Sep 18 at 21:02









        Compass

        4,55442338




        4,55442338






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52393619%2fdiscrepancy-when-converting-ancient-dates-between-java-util-date-and-java-time-i%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin