@jmitchell i have a question about TAI. presume you want to get current time from system. you don’t have a TAI clock there, only UNIX. UNIX does not count leap seconds. so i think if you want to do that, you should know when there are leap seconds? right?
@kip Thank you for implementing this. it is a good implementation but i think it is a little too complex for anyone who is going to implement their new Calendar to understand integer_date and change their basis for conversion on that!
Even for your own calendar the official determinations require astronomical calculation of whether the vernal equinox before true noon. That’s way more complex.
In order to convert between calendars there needs to be some common representation, ihink that’s agreed. If it’s to be the Gregorian calendar (which he unix timestamp ultimately is) then that’s fine. However I don’t think the burden of calculator is any greater than the one I’ve described.
The reason I suggested the basis I did is that the means to calculate he integer date (called fixed date by Dershowitz and Rheingold) is that hey have already defined the conversations for 23 different calendars including arithmetic and astronomical calendars.
Therefore I would argue that the calculation comolexity is actually reduced because D&R have already done the hard work.
Last point, but I think it’s relevant - using a unix timestamp means you’re now taking responsibility for time as well as date. Dates are complex enough, time is really hard, The recent challenges of the the leap second illustrate that.
First of all, Unix timestamp is NOT Gregorian calendar. UNIX counts milliseconds from 1970,1,1 right?
Now suppose Jalaali calendar. Can we say UNIX is number of milliseconds from 1348,10,11? Answer is YES. so UNIX is not a Gregorian calendar
In case of leap seconds, think you are going to get current system time and you are not connected to internet. So you don’t know if 2016 had a leap second. same problem happens with Integer day number here.
Another thing is, if we use Day number. we are adding complexity for developers who want to implement Calendars for elixir. I did’t find any platform that currently uses Day number for conversion. if you had, please share it.
Hmm…, the UNIX (Or, to be precise, POSIX) time counts seconds (but subdividing these in milliseconds or smaller is allowed.) from 1970-01-01T00:00:00.00, but defines a ‘day’ to contain exactly 86400 seconds. This means that when an UTC day (either december 31st or june 30th) contains a leap second, the POSIX time needs to be adjusted. This is done differently by different organizations/implementations.
One possibility is to ‘jump back’ after the leap second was done. (This is what systems following the POSIX standard strictly are supposed to do, I believe, but for many computer systems this is unacceptable as incoming events are no longer ordered.)
Another possibility is to not update the POSIX timestamp at all during the leap second.
Another possibility is to ‘slow down’ time slightly during the time around the leap second: This is the so-called ‘leap smear’ that e.g. Google uses.
This means that POSIX time follows UTC except during leap seconds. Oddly enough, that in turn means that if we want to find out the TAI from a given POSIX timestamp, we actually need to know the amount of leap seconds that has passed (because these are implicitly part of the POSIX timestamp!). Still, because TAI does increase monotonically during leap seconds, it is a better standard for timestamp conversion. After all, it is only UTC → TAI and TAI → UTC that needs to handle the leap second problem.
In the case a computer is fully disconnected from the internet, its clock will start to diverge (regardless of what representation we use). The OS-clock will not count leap seconds in that case either way, because it has no way of knowing about them (when connected, the Network Time Protocol (NTP) is often used to regulate leap seconds). Also, a computer clock simply is not as precise as an atomic clock.
This method cannot handle leap seconds, because in above example, a day (for some calendar-defined definition of ‘a day’) is the smallest unit of time used.
If you want to, e.g. convert the UTC datetime 2054-01-07T00:00:00.00 to another calendar right now, you might turn out to be off by a couple of seconds, because leap seconds (or leap second removals, which can theoretically occur as well) are only announced six months in advance. So: We cannot handle leap seconds when converting to/from UTC datetimes for moments further than six months in the future. Is this a problem? Only if we do not document it; there is no other way to resolve this issue.
If, however, you do not have the exact datetime precision like above, but only work with complete days, then you can convert to any other calendar, as long as the concept of ‘a day’ is the same. If, for instance, the ‘day’ in the other calendar starts at noon (or at sunrise, etc), you have a problem since now there are two possible result dates for 2054-01-07: either before or after noon. That is why I agree with @kip that if you want to unambiguously convert between two calendars, you need to use a base unit that is small enough to specify exactly in both calendars what moment you mean.
Because time is hard is why I proposed calendar conversions deal only in dates and not periods less than a day.
@alisinabh expressed concern that converting to/from an integer date introduced more complexity than a calendar writer should be expected to cope with, I still believe the same level of complexity remains no matter what common epoch is chosen.
I think the complexity increases quite a lot if the expectstion is for calendar conversion is to manage time conversion as well given the expectations of precision and the reality that days don’t always start at midnight as @Qqwy notes.
The Elixir calendar module already introduces/recognises a lack of precision (as do many calendar libraries) because its proletpic. Further complications happen because th date of adoption of the Gregorian calendar is different in different countries. Unix made a half-hearted attempt to cover that example, but ultimately I think there is an understanding that calendar operations are mostly correct in the current era, and suspect In the distant past far future.
On the contrary, expectations of time are, it seems to me, quite strict - and maintaining the expected level of accuracy and precision is beyond the expectations set for a calendar writer in my opinion.
Therefore my reasoning is that using any form of timestsmp as the basis of calendar conversion sets an expectation of accuracy that is unlikely to be met,
The actual common epoch to be used as the basis of conversion is just a number. I’ve proposed an approach that is well documented by two respected scientists and they’ve created the algorithms for conversions for a lot of calendars and tested them +/- 10,000 years. If the community prefers another approach then that’s cool too.
TAI sounds interesting, wish I knew about it a decade ago! ^.^
Back then I had to create a time system that handled relativity properly. I.E., time was not a global constant but rather was only a relative offset between two points and velocities. I ended up building something that worked with relativistic calculations, but it was definitely a unique experience. ^.^
But yes, Time is hard, and arbitrary calendars are weird.
Also, B.C. and A.D. has fallen out of favor in everything that I’ve seen for years, instead C.E. and B.C.E. is used now (Common Era and Before Common Era).
Although I like the growing suggestion of of using the Holocene Calendar. The only Calendar hanging in my house right now is a Holocene Calendar.
The Holocene Calendar uses H.E. (for Human Era), and B.H.E. (for Before Human Era). It would be easy to add it to Elixir as well, it is just the Gregorian calendar with 10000 years added to it for C.E. (or 10001 for B.C.E. since the Gregorian calendar has no ‘0’ year stupidly enough).
I have developed Jalaali calendar for Elixir. which is what this topic was about
For date conversion in Jalaali i’ve used JDN (Julian day number). it was enough there. (Julian day number is not an integer, its a float in the algorithm i have used)
I’m only concerned if there is a calendar which cannot handle conversion using day number.
After all if a calendar implementation is easier with day number than it is with POSIX, it can use erlang’s core functions on calendar module to convert it to Gregorian and then to JDN:
Converting to JDN from Gregorian is this easy:
I’m just afraid using Day number has these two cons:
It may be hard for other Elixir developers to port calendar previously implemented on other languages (AFAIK java (Joda-Time) and python are using UNIX epoch for conversion)
on some calendars that we don’t know of, it may be impossible/hard to use day number to make a conversion
Flow of getting current system time in other calendars will be: :os.system_time |> to_iso |> to_integer_date |> dst_calendar.from_integer_date but in case of using POSIX it will be :os.system_time |> dst_calendar.from_unix(:native) i think it removes lots of overheads.
UNIX / POSIX time is quite definitely counted from 1970-01-01T00:00:00.00
Yep, tricky one… in fact, it feels pretty weird to even talk about calendar conversions without having a specific time in a particular location in mind. Why… 2054-01-07 isn’t necessarily even 20154-01-07 in the same calendar if you move a few timezones east or west.
I disagree, since in most ecosystems converting to/from UNIX is common but i didn’t found any that commonly uses Day number. did you?
I actually don’t see any downsides in functionalities of both implementations. both of them will work. i am just saying using UNIX as base timestamp is common in most ecosystems. so for supporting more calendars on Elixir we only need to port libraries that were previously implemented and battle tested by other big communities.
AND we can convert UNIX to day number easily with a very low cost. but reversing that result in loosing of precision. right?
My bad I don’t know much about Time and Calendar though it looks interesting that’s why wanted to explore any tips where should i start to implement for elixir?
Count number of days past your calendar begin for a given time in your calendar
Convert count of days since the beggining of your calendar to its equivalent date in your calendar
After this you may start implementing a Hijri.Calendar module (implementation of Calendar module)
Note that you can implement your logic in another module to be able to test it more accurately.
If you face any other problems i’d be more than happy to help.