1. 7
    1. 6

      I like messing around with calendrical calculations. My favourite code for converting a proleptic Gregorian date into a linear day number is,

          int ymd2rd(int y, int m, int d) {
              if (m > 2) m += 1; else m += 13, y -= 1;
              return y*1461/4 - y/100 + y/400 + m*153/5 + d - 428;
          }
      

      (This uses the RD epoch ymd2rd(1,1,1) == 1; adjust the 428 to change epoch.)

      Irritatingly, this fails for negative numbers with the common semantics of the division operator. But it works with Euclidean division! Happily, div_euclid is in Rust’s standard library. It isn’t too hard to work around a lack of Euclidean division, but it is rather tedious.

      The Euclidean remainder turns up when converting linear seconds (like NTP or time_t) to time-of-day. The obvious dance with % 60 fails for negative times before the epoch for common meanings of %, but works with Euclidean %.

      And when the divisor is a power of two, the straightfoward translation of division into >> and remainder into & works for negative numbers on a two’s complement machine if division is Euclidean, but not for common division.

      Bah! I wish Euclidean division was the default, it seems a lot more sensible to me.

      1. 1

        Hm interesting, when do you have negative numbers? When y is negative for BC years?

        Also I’ve never run into the problem of times before the epoch, that is interesting!

        1. 1

          With the proleptic Gregorian calendar, usually you’d have year 0 = 1 BC, year -1 = 2 BC, and so on.

        2. 1

          RD

          Looking at Wikipedia’s disambiguation page for “RD”, I guess this is https://en.wikipedia.org/wiki/Rata_Die?