Closed ebraminio closed 3 years ago
Per https://en.wikipedia.org/wiki/Iran_Standard_Time
Iran Standard Time (IRST) or Iran Time (IT) is the time zone used in Iran. Iran uses a UTC offset UTC+03:30. IRST is defined by the 52.5 degrees east meridian, the same meridian which defines the Iranian calendar and is the official meridian of Iran.
So the use of 52.5 makes sense actually.
Dear @ebraminio
Both the official leap year for AP 1469 (Gregorian year - GY 2090) and the one calculated in this project for AP 1470 (GY 2091) are projected.
This project bases its calculation on the sources of the book Calendrical Calculations, which comes with source code in Common Lisp.
From here on, the discussion is about the Persian Astronomical calendar, not the Persian Arithmetic calendar (which has a cycle of 2880 years).
The calculations take into account the exact geo-location of the observatory in Tehran, as well as its altitude, which is around 1100 metres above the sea level.
The location
in the source code and the definition of "Iran Standard Time" zone are two different things.
IRST is used to specify the time difference relative to Greenwich (London), it is a time zone which is valid for all of Iran.
The source code mentioned defines Tehran's location as
(defconstant tehran
;; TYPE location
;; Location of Tehran, Iran.
(location (deg 35.68L0) (deg 51.42L0)
(mt 1100) (hr (+ 3 1/2))))
It does not specify it as (deg 52.5L0)
.
So, in order to identify if a given Persian year is leap, the time-span between Favardin 1 of the following year and Favardin 1 of the year in question is calculated; if it is 365 [days], the year is not leap. It is only a leap year for 366 [days].
In order to determine if AP 1469 or AP 1470 are leap years, we run this code in SBCL, an open source Common Lisp implementation:
;; is AP 1469 a leap year ?
( - (fixed-from-persian (persian-date (1470 1 1))
(fixed-from-persian (persian-date (1469 1 1))
)
;; is AP 1470 a leap year ?
( - (fixed-from-persian (persian-date (1471 1 1))
(fixed-from-persian (persian-date (1470 1 1))
)
fixed-from-persian
means, convert the persian astronomical date to Julian Day Number (JDN).
The evaluation of both expressions gives us 365
and 366
respectively.
This means that AP 1469 is not a leap year, but 1470 is.
That is, if you go with the algorithms published in the book introduced above.
I am willing to extend the test suite with more cases.
However, I am not changing the code as suggested.
Given the fact that we do not exactly know how the official leap years were calculated, and the fact that there is only one discrepancy between them and the leap years in this project, I am sticking with the book's algorithms.
I am aware that this discrepancy may disqualify its usage for certain parties.
Thank you, good pointers and no problem, I'm actually here more for the sake information exchange reason and wasn't aware altitude have any interference to the calculation, thanks!
I really appreciate your contributions.
I am very interested in the .NET implementation, thank you for pointing it out!
A better link for it is this, https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendricalCalculationsHelper.cs which is solely used in its implementation which is tested here https://github.com/dotnet/runtime/blob/main/src/libraries/System.Globalization.Calendars/tests/System/Globalization/PersianCalendarTests.cs I think "CalendricalCalculationsHelper" in its name somehow indicates that also used the same source? Interesting to know who they found they should use 52.5 instead which actually matches with what Iran's Calendar Center publishes also.
The Calendar Center also publishes Spring equinoxes but they have some differences less than a minute with Spring equinox algorithms I've found in the net, as you may know Spring equinox moment is highly related to Persian calendar leap years those but somehow I couldn't find yet a way to extract that from the code. If calendariale could provide them somehow I can check whether they match official ones better or not, here is its test https://github.com/persian-calendar/equinox/blob/main/src/test/java/io/github/persiancalendar/MainTests.java#L14 which has a difference less than one minute.
Interesting this topic is mentioned on https://www.fourmilab.ch/documents/calendar/ and IRST is chosen there apparently.
There is some controversy about the reference meridian at which the equinox is determined in this calendar. Various sources cite Tehran, Esfahan, and the central meridian of Iran Standard Time as that where the equinox is determined; in this implementation, the Iran Standard Time longitude is used, as it appears that this is the criterion used in Iran today. As this calendar is proleptic for all years prior to 1925 c.e., historical considerations regarding the capitals of Persia and Iran do not seem to apply.
It would be great to have a list of leap years prior to 1925 C.E.
6 years ago I replicated the site you mentioned Fourmilab, enhanced it, see CalendarConverter.
I contacted the author of the site to incorporate the enhancements.
It would be great to have a list of leap years prior to 1925 C.E.
The dotnet has something about it https://github.com/dotnet/runtime/blob/main/src/libraries/System.Globalization.Calendars/tests/System/Globalization/PersianCalendarTests.cs#L246
But even better this page (nojum, the site's domain, means astronomy) has something about it, specially look at this section of the page, "اصول کبیسهها در تقویم هجری شمسی" which interestingly mentions IRST's 52.5 also,
The table says something about leaps years between -940 to 1498 of Persian Calendar
6 years ago I replicated the site you mentioned Fourmilab, enhanced it, see CalendarConverter.
Found its link from your GitHub page but didn't know the history, thanks
Just checked that list of 2270 leap years.
The algorithm gets 19 "wrong", which is less than 1 % (0.84 %).
Using 52.5 for Tehran's location indeed misses none of the leap years.
Calendariale probably is more accurate however,Update: see the next postAccording to officially published Calendar Center here is the official leap years of Persian Calendar in use in Iran as the main calendar,
which is also what .NET also does,
But calendariale fails on 1469 so the following (Persian Calendar is now in 1400 so this is 69 years from now, no worries 😄),
Which expects 1469 to be 1470 and can be resolved with this change on calendariale
To make it match with dotnet's implementation https://github.com/microsoft/referencesource/blob/5697c29/mscorlib/system/globalization/CalendricalCalculationsHelper.cs#L291 which uses 52.5
Hopefully this would be a useful information to you, please note that Persian arithmetic is way off, if performance is a concern with the implementation, something like this can be done (I also have the non-lookup table one here based on the dotnet implementation, I could use the calendariale one but this minor issue which I wasn't aware how easily can be resolved made me to go to port the .NET one)
Thanks!