Closed gazzatav closed 2 years ago
The main thing to know when writing a calendar is the ability to convert to and from sys_days
and local_days
(which is the same math under the hood). sys_days
is a "calendar" where 1970-01-01 is day 0, and the numbers go positive into the future and negative into the past. Once you've got that conversion going, you can convert Darian to every other calendar that supports a conversion to/from sys_days
.
To learn about the algorithms used for date::year_month_day
, see: http://howardhinnant.github.io/date_algorithms.html
It includes a detailed derivation of each algorithm, including the one for doy
that you quote above. That particular line of code is not unique to date
. You can find it, and variations of it in many calendrical programs across many programming languages.
@HowardHinnant Thank you. I have a MarsClock with the epoch back in 1955 and using declarations for mars_day, mars_hour and mars_year. I was amazed (not really, I know your libraries are brilliant!) how easily I could convert from earth time to mars time. I'll read up on those algorithms, they may be common but without a name or keyword, internet searches always return the 'is_leap_year' type of algorithm. At the moment I am close with:
(167*(m-1))/6 +1 -m/6
but not perfect.
To close this question, the Darian calendar has four quarters of 6 months. Each month of the quarter has 28 days except the last which has 27 for a total of 167 days per quarter. Leap years add a day to the last month of the year so they can be ignored here (and elsewhere the year does not need to be decremented). An expression for doy, using mp from the range [0, 23] and extra parentheses to emphasise integer division is:-
doy = 167 * mp/6 + (mp - (mp/6) * 6) * 28 + d - 1
Possibly it would be worth calculating mp/6 before the expression and using the result twice - I checked on Compiler Explorer and it saved 10 lines of assembly :)
I'm trying to write a class similar to year_month_date to express a version of the Mars Darian calendar. The to_days function looks really important and I'm half way to understanding it. The line below to find day of year seems particularly important.
auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1;
Does this algorithm have a name or is it unique to the date library? It would be great to know how it was derived. I would like to understand it better to create a similar expression for mars.
Thanks.