Jalaali (Shamsi) calendar for elixir (Persian calendar)

@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?

Maybe i did not understand it good!?

@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!

What do you think?

I have implemented UNIX method in a bit lighter way. it is on pull #5609

Please do review it and if you think it is ok, lets check it for bugs.

I think calendars are complicated

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.

2 Likes

I agree, calendars are complicated!

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.

Cheers!

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.

Yes, I think that would be the proper way to go.

@Qqwy I don’t understand!

Can you explain this issue to me:

Think you want to convert 2054,1,7 to another calendar. how can this method handle leap seconds?

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.

(Gah, calendars are hard… )

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.

1 Like

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).

2 Likes

(WTH is going on with calendars? )

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:

``````defp g2d({gy, gm, gd}) do
d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4) + div(153 * rem(gm + 9, 12) + 2, 5) + gd - 34840408
d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752
end
``````

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.

Thank you @kip, @Qqwy, @jmitchell, @OvermindDL1 and @josevalim
It is a pleasure talking and arguing with such a professional community.

Cheers!

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.

Whoops! That was a (grave…) typo. I took the liberty to edit my earlier post and fix this mistake. Thank you for noticing.

As for time + location: Yes. UTC is not the same time (‘calendar’) as UTC+2 or UTC+5.5.

All right, the talk about calendars in general seems to be getting too far off-topic.
A new topic to discuss calendars and possible general implementations can be found here.

The current topic is to be used for more discussion about @alisinabh 's implementation of the Jalaali calendar for Elixir.

1 Like

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?

Lets move to this topic: Calendars & Calendar Conversions

Jalaali 0.2.0 is Released!

Hi everyone.

The new version of Jalaali is released supporting Elixir Calendar system announced in Elixir 1.5

In the new system Dates/DateTimes can be converted easily thanks to @qqwy and @josevalim

You can easily type `DateTime.utc_now(Jalaali.Calendar)` in order to get current DateTime in any calendar (in this example Jalaali)

Or you can use `Date.convert` or `DateTime.convert` functions to convert any Date/DateTime to any calendar implemented in Elixir.

For more information on how to use this new features you can either read Jalaali docs github.com/jalaali/elixir-jalaali or Elixir calendar docs.

Please report any issues you encounter while using Jalaali.

Thanks

8 Likes

This is excellent to hear. Thank you!

2 Likes

Is there any package for Gregorian calendar to hijri converter calendar support?
if not i’m interested in working on this looking for help.

1 Like

@maqbool UTC is a time zone as far as i know. hijri is a calendar system. I didn’t find any hijri implementation for elixir.

1 Like

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?

1 Like

First of all you need the logic.

You need to be able to

• 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.

2 Likes