Hi Bahman,
On 13 Nov 2013, at 09:19, Bahman Movaqar <[email protected]> wrote:
> On 11/13/2013 11:39, Bahman Movaqar wrote:
>> On 11/13/2013 11:13, Bahman Movaqar wrote:
>>> Let's say I have a method with signature in a language like Java as below:
>>> gregorianDayToJulianDay(year, month, day)
>>>
>>> What could be a proper naming for this method in Smalltalk? I'm a bit
>>> confused as I'm so used to the concept of methods being "verbs" which
>>> accept some arguments.
>>>
>>> I'd appreciate any help/idea.
>
> After reading Sven's reply, I came up with this design. Is it the
> idiomatic way to handle this problem in Smalltalk:
>
> <pseudo-design>
> class JulianConverter:
> instance variable: 'day'
>
> #toGregorian
> #toIranian
>
> class GregorianConverter:
> instance variable: 'year month day'
>
> #toJulian
>
> class IranianConverter:
> instance variable: 'year month day'
>
> #toJulian
>
> </pseudo-design>
There is not necessarily a right and a wrong way. Design is hard to explain, I
am not going to try. Sorry ;-)
But please do have a look at the Chronos library, it even has a
PersianCalender, among many others. This is the class comment:
[Chronos] All code (classes and methods, and all associated documentation,)
distributed as part of the Chronos Date/Time library are © Copyright 2005-2006
by Alan L. Lovejoy. All Rights Reserved. Usage is controlled by the Chronos
License (which is included in the distribution as the contents of the file
{chronos-license.txt}, and is also available from the Chronos web site
{http://www.chronos-st.org/License.html})
PersianCalendar
Concept:
PersianCalendar implements the arithmetical version of the
Persian Calendar. There is also an astronomical version of the Persian
Calendar, which some authorities claim is the one actually used in Iran,
although other authorities claim otherwise. Chronos does not currently provide
implementations of any astronomical calendars. The astronomical version of the
Persian Calendar will (eventually) be implemented by class named
AstronomicalPersianCalendar, whose registration key will be
#'Persian-Astronomical'.
For any and all discussion of what a 'Calendar' is
conceptually, how an instance of a Calendar can and/or should be used, the
general implementation requirements for subclasses of Calendar, or the
architectural requirements and responsibilities of Calendar instances with
respect to the rest of the Chronos Date/Time Library, please refer to the
documentation of class Calendar. The remainder of this text discusses the
specific nature of the Persian Calendar itself (and its implementation by this
class,) and assumes that the reader has already become familiar with all the
concepts and terminology documented in class Calendar.
The Persian Calendar (as implemented here) is an arithmetical,
solar calendar. A solar calendar is one that attempts to match the (average)
length of its years to that of mean solar years.
Epoch Date
The epoch date of the Persian Calendar, 0001-01-01
[Persian], corresponds to 0622-03-22 [Gregorian] and to 0622-03-19 [Julian].
The Julian Date of the epoch of the Persian Calendar is 1,948,320.50
(midnight.)
The epoch date of the Persian Calendar is the vernal
equinox of the year in which the "hijra" of Mohammed to Medina occurred
("hijra" means "flight from danger.")
The era of the Persian Calendar is called "Anno
Persico" or "Anno Persarum" (AP)--which is Latin for "In the Year of Persia/the
Persians."
Time-of-Day Clock
Modernly, midnight is both the zero-point of the
time-of-day clock and also the initial moment of the day. However, such has
not always been the case for all users of the Persian Calendar.
{PersianCalendar clock today}
{PersianCalendar clock now}
Year Numbering Policy
The Persian Calendar uses "zeroless ordinal" year
numbering. This means that the epoch year is an ordinal number whose value is
1, and the year that immediately precedes the year 1 is the year -1.
Leap Year Rule
According to Birashk [A. Birashk, "A Comparative
Calendar of the Iranian, Muslim Lunar, and Christian Eras for Three Thousand
Years," Mazda Publishers (in association with Bibliotheca Persica,) Costa Mesa,
CA, 1993], the arithmetical form of the Persian Calendar uses the following
rather complicated leap year rules:
There is a master cycle of 2820 years, during which 683
years are leap years. Each standard year contains 365 days, and each leap year
contains 366 days, so the master 2820-year cycle contains 1,029,983 days [(2820
* 365) + 683 = 1,029,983]. Based on the current mean length of the tropical
year and solar day, there are 1,029,983.00118 days in 2820 tropical years. So,
were it not for the fact that a) the length of the tropical year and the length
of a mean solar day is slowly changing, and b) the length of the tropical year
(which is defined by the duration between winter solstices) is not the same as
the length of the spring equinoctial year (which is defined by the duration
between vernal equinoxes,) it would be fair to say that the Persian
arithmetical calendar deviates from the length of a year by only 101.952
minutes in 2820 years. But for those (and other) caveats, the Persian
arithmetical calendar would slip from perfect alignment with the tropical year
by only one day every 39,829.68 years--which is astounding accuracy, in spite
of the caveats.
Within each 2820-year cycle, there are 22
subcycles--the first 21 each contain 128 years, and the 22nd (final) subcycle
contains 132 years [2820 = 21 * 128 + 132].
Each 128-year subcycle contains one 29-year
sub-subcycle (the first,) followed by three 33-year sub-subcycles [128 = 29 +
(3 * 33)].
Each 132-year subcycle contains one 29-year
sub-subcycle (the first,) followed by two 33-year sub-subcycles, followed by
one 37-year sub-subcycle [132 = 29 + (2 * 33) + 37].
A year in a sub-subcycle (whether it contains 29, 33 or
37 years) is a leap year if the ordinal index of the year within the cycle
satisfies the following two predicate tests: 1) it's greater than 1, and 2) the
remainder after dividing it by 4 is 1 (so the first year in sub-subcyle is
never a leap year; the first leap year is the fifth year in the sub-subcycle.)
Thus, a 29-year sub-subcycle has 7 leap years, a 33-year sub-subcycle has 8
leap years, and a 37-year sub-subcycle has 9 leap years (Note: the last year of
a sub-subcycle is always a leap year, since 29, 33 and 37 all result in a
remainder of 1 when divided by 4) [21 * (7 + (3 * 8)) + (7 + (2 * 8) + 9) =
683].
The base year of the 2820 cycle of years is NOT the
Persian year zero or 1, however. The base year of the 2820-year cycle of years
is the Persian year 475 (which starts on 21 March 1096 [Gregorian] or 15 March
1096 [Julian].) However, to facilitate the use of modular arithmetic, the
Chronos implementation uses Persian year 474 as the zeroeth year of the
2820-year cycle.
Algorithm of Predicate Function that answers true if a
<persianYear> is a leap year (input arg=<persianYear>):
1. If <persianYear> >= 1 then
set <cardinalYear> to <persianYear> - 1;
else
set <cardinalYear> to <persianYear>;
end
2. Set <dividend> to <cardinalYear> - 473.
3. Set <year> to (dividend mod 2820) + 474.
4. Return (((<year> + 38) * 682) mod 2816) < 682
Month Structure
Month Days In Month
Standard
Year/Leap Year
1: Farvardin 31/31
2: Ordibehesht 31/31
3: Xordad 31/31
4: Tir 31/31
5: Mordad 31/31
6: Shahrivar 31/31
7: Mehr 30/30
8: Aban 30/30
9: Azar 30/30
10: Dey 30/30
11: Bahman 30/30
12: Esfand 29/30
Days In Year 365/366
The semantic month-key of a month is the same as the
month's (English) name (as given here.)
Pretty deep, right ?
HTH,
Sven
Yes, the main website is down, but you should be able to load the code in Pharo
2.0 using the configuration.
> --
> Bahman Movaqar (http://BahmanM.com)
>
> ERP Evaluation, Implementation & Deployment Consultant
> PGP Key ID: 0x6AB5BD68 (keyserver2.pgp.com)
>
>