NTP rollover-safe design with ESP8266 (Curiosity)

What's the most polite way to tell a manager "shut up and let me work"?

Opposite of "Squeaky wheel gets the grease"

Why does a helium balloon rise?

Show sparse matrices like chessboards

Asking bank to reduce APR instead of increasing credit limit

Rotated Position of Integers

Could the Missouri River be running while Lake Michigan was frozen several meters deep?

Working in the USA for living expenses only; allowed on VWP?

Short story written from alien perspective with this line: "It's too bright to look at, so they don't"

Why is Colorado so different politically from nearby states?

Comma Code - Ch. 4 Automate the Boring Stuff

Does it cost a spell slot to cast a spell from a Ring of Spell Storing?

Did thousands of women die every year due to illegal abortions before Roe v. Wade?

What is a simple, physical situation where complex numbers emerge naturally?

NTP rollover-safe design with ESP8266 (Curiosity)

Initialize an array of doubles at compile time

Responsibility for visa checking

How can I make 20-200 ohm variable resistor look like a 20-240 ohm resistor?

Credit card offering 0.5 miles for every cent rounded up. Too good to be true?

How can Iron Man's suit withstand this?

Unconventional Opposites

Do marked cards or loaded dice have any mechanical benefit?

What happens if you do emergency landing on a US base in middle of the ocean?

Hygienic footwear for prehensile feet?



NTP rollover-safe design with ESP8266 (Curiosity)














2















The Arduino NTP implementation is rather naive in some respects. It basically just grabs the time in seconds from the raw packet, and then converts it to Unix time via subtraction. How would it be possible to create an implementation that is safe from at least this next NTP rollover (due in 2036)? I'd rather not design something that might suddenly fail in strange ways in a decade or two when I have forgotten why it might do so (but it's not horribly important if it's not easily fixed).



If it can make it to 2100, I'd have larger problems (the RTC would crap itself), so just this rollover is fine.



The existing implementation (https://github.com/arduino-libraries/NTPClient/blob/master/NTPClient.cpp):



unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;

this->_currentEpoc = secsSince1900 - SEVENZYYEARS;









share|improve this question




























    2















    The Arduino NTP implementation is rather naive in some respects. It basically just grabs the time in seconds from the raw packet, and then converts it to Unix time via subtraction. How would it be possible to create an implementation that is safe from at least this next NTP rollover (due in 2036)? I'd rather not design something that might suddenly fail in strange ways in a decade or two when I have forgotten why it might do so (but it's not horribly important if it's not easily fixed).



    If it can make it to 2100, I'd have larger problems (the RTC would crap itself), so just this rollover is fine.



    The existing implementation (https://github.com/arduino-libraries/NTPClient/blob/master/NTPClient.cpp):



    unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
    unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;

    this->_currentEpoc = secsSince1900 - SEVENZYYEARS;









    share|improve this question


























      2












      2








      2








      The Arduino NTP implementation is rather naive in some respects. It basically just grabs the time in seconds from the raw packet, and then converts it to Unix time via subtraction. How would it be possible to create an implementation that is safe from at least this next NTP rollover (due in 2036)? I'd rather not design something that might suddenly fail in strange ways in a decade or two when I have forgotten why it might do so (but it's not horribly important if it's not easily fixed).



      If it can make it to 2100, I'd have larger problems (the RTC would crap itself), so just this rollover is fine.



      The existing implementation (https://github.com/arduino-libraries/NTPClient/blob/master/NTPClient.cpp):



      unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
      unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
      // combine the four bytes (two words) into a long integer
      // this is NTP time (seconds since Jan 1 1900):
      unsigned long secsSince1900 = highWord << 16 | lowWord;

      this->_currentEpoc = secsSince1900 - SEVENZYYEARS;









      share|improve this question
















      The Arduino NTP implementation is rather naive in some respects. It basically just grabs the time in seconds from the raw packet, and then converts it to Unix time via subtraction. How would it be possible to create an implementation that is safe from at least this next NTP rollover (due in 2036)? I'd rather not design something that might suddenly fail in strange ways in a decade or two when I have forgotten why it might do so (but it's not horribly important if it's not easily fixed).



      If it can make it to 2100, I'd have larger problems (the RTC would crap itself), so just this rollover is fine.



      The existing implementation (https://github.com/arduino-libraries/NTPClient/blob/master/NTPClient.cpp):



      unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]);
      unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]);
      // combine the four bytes (two words) into a long integer
      // this is NTP time (seconds since Jan 1 1900):
      unsigned long secsSince1900 = highWord << 16 | lowWord;

      this->_currentEpoc = secsSince1900 - SEVENZYYEARS;






      esp8266 time






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 7 hours ago









      VE7JRO

      1,80251324




      1,80251324










      asked 9 hours ago









      RDragonrydrRDragonrydr

      429




      429




















          1 Answer
          1






          active

          oldest

          votes


















          5














          This implementation is perfectly fine. The calculations are done with
          unsigned numbers, so they are naturally rollover safe. The day NTP time
          rolls over, secsSince1900 will become a very small number, and
          subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
          to the rules of modular arithmetics, these two rollovers compensate and
          you are guaranteed to get the correct result modulo
          232 s.



          In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
          is traditionally signed, which makes the 32-bit representation roll over
          in January 2038. The authors of this library have instead chosen to
          represent it as an unsigned number, which means it will roll over in
          February 2106.






          share|improve this answer























          • Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

            – RDragonrydr
            7 hours ago











          • @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

            – Peter Cordes
            10 mins ago












          Your Answer






          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("schematics", function ()
          StackExchange.schematics.init();
          );
          , "cicuitlab");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "540"
          ;
          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',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          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%2farduino.stackexchange.com%2fquestions%2f65883%2fntp-rollover-safe-design-with-esp8266-curiosity%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









          5














          This implementation is perfectly fine. The calculations are done with
          unsigned numbers, so they are naturally rollover safe. The day NTP time
          rolls over, secsSince1900 will become a very small number, and
          subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
          to the rules of modular arithmetics, these two rollovers compensate and
          you are guaranteed to get the correct result modulo
          232 s.



          In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
          is traditionally signed, which makes the 32-bit representation roll over
          in January 2038. The authors of this library have instead chosen to
          represent it as an unsigned number, which means it will roll over in
          February 2106.






          share|improve this answer























          • Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

            – RDragonrydr
            7 hours ago











          • @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

            – Peter Cordes
            10 mins ago
















          5














          This implementation is perfectly fine. The calculations are done with
          unsigned numbers, so they are naturally rollover safe. The day NTP time
          rolls over, secsSince1900 will become a very small number, and
          subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
          to the rules of modular arithmetics, these two rollovers compensate and
          you are guaranteed to get the correct result modulo
          232 s.



          In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
          is traditionally signed, which makes the 32-bit representation roll over
          in January 2038. The authors of this library have instead chosen to
          represent it as an unsigned number, which means it will roll over in
          February 2106.






          share|improve this answer























          • Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

            – RDragonrydr
            7 hours ago











          • @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

            – Peter Cordes
            10 mins ago














          5












          5








          5







          This implementation is perfectly fine. The calculations are done with
          unsigned numbers, so they are naturally rollover safe. The day NTP time
          rolls over, secsSince1900 will become a very small number, and
          subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
          to the rules of modular arithmetics, these two rollovers compensate and
          you are guaranteed to get the correct result modulo
          232 s.



          In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
          is traditionally signed, which makes the 32-bit representation roll over
          in January 2038. The authors of this library have instead chosen to
          represent it as an unsigned number, which means it will roll over in
          February 2106.






          share|improve this answer













          This implementation is perfectly fine. The calculations are done with
          unsigned numbers, so they are naturally rollover safe. The day NTP time
          rolls over, secsSince1900 will become a very small number, and
          subtracting SEVENZYYEARS from it will cause an extra roll over. Owing
          to the rules of modular arithmetics, these two rollovers compensate and
          you are guaranteed to get the correct result modulo
          232 s.



          In the end, you get a Unix time as an unsigned 32-bit integer. Unix time
          is traditionally signed, which makes the 32-bit representation roll over
          in January 2038. The authors of this library have instead chosen to
          represent it as an unsigned number, which means it will roll over in
          February 2106.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 8 hours ago









          Edgar BonetEdgar Bonet

          25.5k22546




          25.5k22546












          • Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

            – RDragonrydr
            7 hours ago











          • @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

            – Peter Cordes
            10 mins ago


















          • Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

            – RDragonrydr
            7 hours ago











          • @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

            – Peter Cordes
            10 mins ago

















          Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

          – RDragonrydr
          7 hours ago





          Huh. That's actually rather cool. I knew of a similar method for millis(), but didn't know this worked for NTP as well. Thanks!

          – RDragonrydr
          7 hours ago













          @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

          – Peter Cordes
          10 mins ago






          @RDragonrydr: carry propagates from low to high in addition/subtraction. The low bits of the result do not depend on any higher bit positions, so if you want a 32-bit result it's always safe to truncate your inputs instead of doing a 64-bit subtract and truncating the result. Same for left shift, or the low N bits of an N x N multiply. See also Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?

          – Peter Cordes
          10 mins ago


















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Arduino Stack Exchange!


          • 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%2farduino.stackexchange.com%2fquestions%2f65883%2fntp-rollover-safe-design-with-esp8266-curiosity%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

          Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

          Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

          Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її