The Sentience

The Sentience

Tuesday, August 16, 2011

The Hindu Lunisolar Calendar

Research Sources

  • Calendrical Calculations: Third Edition - Nachum Dershowitz and Edward M. Reingold
  • Notes and Errata on Calendrical Calculations: Third Edition - 25th May 2011
  • Astronomical Algorithms: First Edition - Jean Meeus
  • Practical Astronomy with your Calculator: Third Edition - Peter Duffet-Smith
  • How to compute planetary positions - Paul Schlyter
  • Indian Calendars - Leow Choon Lian/Professor Helmer Aslaken

Astro Library

Most of the astronomical functions have already been described in the implementation of previous astronomical Calendars. A few functions were appended to the Astro Library to implement the Hindu calendar, namely:

astrosolar.h

double precession(double time)

Calculates the precession value.

double bisectionSearch(double a, double b, bool c, bool d)

Returns the result of bisection search between the two values a and b depending upon the conditions c and d.

double solarLongitudeAtOrAfter(double longitude, double time)

Computes the solar longitude at or after a given moment of time.


KCalendarSystem API

To implement the Chinese calendar, certain changes had to be made in the KCalendar System API in order to incorporate features requiring leap months, namely:

QString monthName(double month, int year, MonthNameFormat format = LongName)

Gets specific calendar type month for a given date. The monthName() method is overloaded to use a double type value of the month returned by calculations.

bool julianDayToDate(int jd, int &year, double &month, double &day) const

Method to convert Julian day to calendar specific date.

bool dateToJulianDay(int year, double month, double day, int &jd) const

Method to convert calendar specific date to Julian day.

int daysInMonth(int year, double month) const

Returns the number of days in the given month of year. The double data type implements functionalities for leap months.

The Hindu Calendar

The header file defining the implementation of Hindu Lunisolar Calendar is kcalendarsystemhindu.h. It has defined two classes:

KCalendarSystemHindu

Class definition in the public domain, publicly inherited from KCalendarSystem. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual QString calendarType() const

Returns the calendar system type.

virtual QDate epoch() const

Returns a QDate holding the epoch of the calendar system. Hindu epoch is defined on Julian Day 599466. (Kali Yug - January 23, -3101 in Gregorian Calendar).

virtual QDate earliestValidDate() const

Returns the earliest date valid in this calendar system implementation, i.e. epoch + 3044*The length of mean sidereal year, as this marks the beginning of the Vikrama Era

virtual QDate latestValidDate() const

Returns the latest date valid in this calendar system implementation, i.e. 9999*The length of mean sidereal year - 1

virtual bool isValid(int year, int month, int day) const

Returns whether a given date is valid in this calendar system.

virtual bool isValid(const QDate &date) const

Returns whether a given date is valid in this calendar system.

virtual bool isLeapYear(int year) const

Returns whether a given year is a leap year.

virtual bool isLeapYear(const QDate &date) const

Returns whether a given year(taken from the QDate) is a leap year.

virtual QString monthName(double month, int year, MonthNameFormat format = LongName) const

Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned. The double data type is used to incorporate functionalities requiring leap months.

virtual QString monthName(const QDate &date, MonthNameFormat format = LongName) const

Gets specific calendar type month name for a given date.

virtual QString weekDayName(int weekDay, WeekDayNameFormat format = LongDayName) const

Gets specific calendar type week day name. If an invalid week day is specified, QString() is returned.

virtual QString weekDayName(const QDate &date, WeekDayNameFormat format = LongDayName) const

Gets specific calendar type week day name.

virtual int weekDayOfPray() const

Returns the weekday of pray for this calendar system, 7th day of the Hindu Week.

virtual bool isLunar() const

Returns whether the calendar is lunar. (False)

virtual bool isLunisolar() const

Returns whether the calendar is lunisolar. (True)

virtual bool isSolar() const

Returns whether the calendar is solar. (False)

virtual bool isProleptic() const

Returns whether the calendar is proleptic, i.e, supports dates before the epoch. (False)

KCalendarSystemHinduPrivate

Class definition in the private domain, publicy inherited from KCalendarSystemPrivate. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual void loadDefaultEraList()

Gives the Era name of the Hindu Calendar, i.e. the Vikrama Era

virtual KLocale::CalendarSystem calendarSystem() const

Returns the calendar type.

virtual int monthsInYear(int year) const

Returns the number of months in the year used by this calendar system.

virtual int daysInMonth(int year, int month) const

Returns the number of days in a month used by this calendar system.

virtual int daysInYear(int year) const

Returns the number of days in a year used by this calendar system.

virtual int daysInWeek() const

Returns the number of days in a week used by this calendar system, i.e, 7.

virtual bool isLeapYear(int year) const

Checks whether a year is a leap year or not.

virtual bool hasLeapMonths() const

Returns true is this calendar system has leap months. The Hindu calendar has leap months.

virtual bool hasYearZero() const

Returns true is this calendar system uses year 0. The Hindu calendar doesn't have a year 0.

virtual int maxDaysInWeek() const

Returns the maximum number of days in a week in this calendar system, i.e, 7.

virtual int maxMonthsInYear() const

Returns the maximum number of months in a year in this calendar system, i.e. 13.

virtual int earliestValidYear() const

Returns the earliest valid year in this calendar system, i.e., year 1.

virtual int latestValidYear() const

Returns the latest valid year in this calendar system, i.e., year 9999.

virtual QString monthName(double month, int year, Locale::DateTimeComponentFormat format, bool possessive) const

Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned.

virtual QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const

Gets specific calendar type weekday name for a given month number If an invalid weekday is specified, QString() is returned.

double meshaSankranti(int year)

Computes the solar longitude at or after Mesha Sankranti.

double siderealSolarLongitude(double time)

Computes the sidereal solar longitude.

int siderealZodiac(double time)

Returns sidereal zodiac based on sidereal solar longitude.

int hinduSunrise(int date)

Returns the time of dawn at the Hindu locale.

int hinduCalendarYear(double time)

Returns the Hindu calendar year at the given time.

void julianDayToHinduDate(int jd, int &year, double &month, bool &leapMonth, double &day, bool &leapDay)

Function used to convert Julian day to Hindu date.

void hinduDateToJulianDay(int year, double month, bool leapMonth, double day, bool leapDay, int &jd)

Function used to convert Hindu date to Julian day.

Astronomical Implementation

Re-implementations of the functions dateToJulianDay() and julianDayToDate() using the functions defined in the Astro Library.

bool julianDayToDate(int jd, int &year, double &month, double &day) const

Returns the date implemented in this calendar system from Julian day. It implements the previously defined julianDayToHinduDate() function.

bool dateToJulianDay(int &jd, int year, double month, double day) const

Returns the Julian day from the date in this calendar system. It implements the previously defined hinduDateToJulianDay() function.

The calculations for implementing the Hindu Calendar have been derived from the public domain Lisp code/Mathematical functions of Calendrical Calculations by Edward M. Reingold on the Illinois Institute of Technology website, and from the book Astronomical Algorithms by Jean Meeus


Monday, July 11, 2011

The Hindu Calendar

Introduction
Hindu Calendars are by far the nearest approaches to the actual machinery of astronomical phenomena governing life on our planet. (Hashim Amir Ali)

The are more than 30 variations of the calendars used in India, the best known of which is the classical Hindu Calendar Surya Siddhanta which is said to have been revealed to Asura Maya the Assyrian at the end of the last Golden Age (2,163,154 BCE). The Hindu lunisolar calendar is similar to the Chinese calendar, but varies in terms of application of fixed ancient methods to approximate true sun and true moon, based on sidereal year. Hindu longitudes are sidereal, having their origin near Piscium, the 6th brightest star in Pisces. However, having sidereal longitudes doesn't really affect the calculations. The calendar is lunisolar in the sense that it uses lunar months to approximate the sidereal year. The epoch used for Hindu calendars dates to January 23, -3101 in the Gregorian Calendar. The era in the Indian calendar is called the Vikram Era, or the Vikram Samvat, which began in 57 BCE.

There are two types of Hindu Lunisolar Calendars:
  • Amanta - one which is based on new moon ending of the lunar month
  • Parimanta - the other is based on full moon ending of the lunar month
I would be designing the Amanta Lunisolar Calendar for KCalendarSystem.

The Month
The amanta month runs from new moon to the next new moon. Each amanta month and hence the lunar year are expressed in integral number of civil days. The lunar month is either 29 or 30 civil days long but always comprises of 30 lunar days. In general, the month is named after the solar month in which the moment of its defining initial new moon falls. The month is divided into two halves, the sudi and the vadi. The sudi half is also known as the sukla paksha or the bright half-month, covering the time period from new moon to the next full moon. The vadi half, also known as the krishna paksha or the dark half-month, covers the period from the full moon to the next new moon.

There are twelve months in Hindu lunar Calendar:

  1. Chaitra (चैत्र, चैत)
  2. Vaishakh (वैशाख, बैसाख)
  3. Jyeshtha(ज्येष्ठ, जेठ)
  4. Ashadha (आषाढ, आषाढ़)
  5. Shravana (श्रावण, सावन)
  6. Bhadrapada (भाद्रपद, भादो)
  7. Ashwin (आश्विन)
  8. Kartik (कार्तिक)
  9. Margashirsha (मार्गशीर्ष, अगहन)
  10. Paush (पौष)
  11. Magh (माघ)
  12. Phalgun (फाल्गुन)
Leap Months
The lunar calendar year is shorter than the solar sidereal year and hence leap months are occasionally added at intervals to keep the lunar calendar and the solar calendar in sync. When a solar month completely covers a lunar month, that is when there are two new moons (one falling at the beginning and the other falling at the end of the solar month), the lunar month that begins at the first new moon is treated as a leap month and is prefixed with the title adhika. An adhika month generally occurs at average intervals of 2 years 8.4 months.

Missing Months
Very rarely, the lunar month can completely cover a solar month, i.e, there is no new moon falling in that solar month and hence no lunar month naming after it. This missing month is called the kshaya or decayed month. When a kshaya month occurs in a lunar year, there will always be two adhika months (one before and on after the kshaya month).

Days
In the Hindu calendar, the day starts with local sunrise. It is allotted five properties, called angas. They are:
  • the tithi (one of 30 divisions of a synodic month) active at sunrise
  • the vaasara, vaar (ravi-vaar, som-vaar, etc.) or weekday
  • the nakshatra (one of 27 divisions of the celestial ecliptic) in which the moon resides at sunrise
  • the yoga (one of 27 divisions based on theecliptic longitude of the sun and moon) active at sunrise
  • the karana (divisions based on tithis) active at sunrise.
Together these are called the panchangas.

Vaar refers to the days of the week and bear striking similarities with the names of the week in many western cultures:

No.↓

Sanskrit name of
the weekday
Celestial object
1

Ravi vaar रविवार Sun
2

Soma vaar सोमवार Moon
3

Mangala vaar मंगलवार Mars
4

Budha vaar बुधवार Mercury
5

Guru vaar गुरुवार
or
Bruhaspati vaar बृहस्पतिवार
Jupiter
6

Shukra vaar शुक्रवार Venus
7

Shani vāsara शनिवार Saturn

Day numbers are determined by the tithi, the time required by the longitude of the moon to increase by 12 degrees over the longitude of the Sun. Sometimes we call it a lunar day. There are 29 or 30 days in a lunar month. Each day is assigned the number of the tithi in effect at sunrise,. However, days are not always counted serially from 1 to 29 or 30. To understand why, it is important to note the fact that the value of a tithi varies from 19.48 hours to 26.78 hours. A short tithi, may begin after sunrise and end before the next sunrise. In this case, a number is omitted from the day count and hence we have skipped a kshaya day. Similarly, a longer tithi may span two sunrises, i.e., there is no tithi ending in that day. Then a day number is carried over to the second day and is treated as a leap day, suffixed by the term adhika.

Thursday, July 7, 2011

The Chinese Lunisolar Calendar

The header file defining the implementation of Chinese Lunisolar Calendar is kcalendarsystemchinese.h. It has defined two classes:

KCalendarSystemChinese

Class definition in the public domain, publicly inherited from KCalendarSystem. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual QString calendarType() const

Returns the calendar system type.

virtual QDate epoch() const

Returns a QDate holding the epoch of the calendar system. Chinese epoch is defined on Julian Day 758326. (8th March 2637 BCE in Julian Calendar)

virtual QDate earliestValidDate() const

Returns the earliest date valid in this calendar system implementation, i.e. the epoch of the calendar system as the Chinese calendar is not proleptic

virtual QDate latestValidDate() const

Returns the latest date valid in this calendar system implementation, i.e. 30th December 9999 in Chinese Calendar (which becomes 5th February 7303 in Gregorian Calendar).

virtual bool isValid(int year, int month, int day) const

Returns whether a given date is valid in this calendar system.

virtual bool isValid(const QDate &date) const

Returns whether a given date is valid in this calendar system.

virtual bool isLeapYear(int year) const

Returns whether a given year is a leap year.

virtual bool isLeapYear(const QDate &date) const

Returns whether a given year(taken from the QDate) is a leap year.

virtual QString monthName(double month, int year, MonthNameFormat format = LongName) const

Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned. The double data type is used for the month to implement functionalities requiring leap months in the Chinese calendar.

virtual QString monthName(const QDate &date, MonthNameFormat format = LongName) const

Gets specific calendar type month name for a given date.

virtual QString weekDayName(int weekDay, WeekDayNameFormat format = LongDayName) const

Gets specific calendar type week day name. If an invalid week day is specified, QString() is returned.

virtual QString weekDayName(const QDate &date, WeekDayNameFormat format = LongDayName) const

Gets specific calendar type week day name.

virtual int weekDayOfPray() const

Returns the weekday of pray for this calendar system, i.e. Sunday (7th day of the Chinese Week).

virtual bool isLunar() const

Returns whether the calendar is lunar. (False)

virtual bool isLunisolar() const

Returns whether the calendar is lunisolar. (True)

virtual bool isSolar() const

Returns whether the calendar is solar. (False)

virtual bool isProleptic() const

Returns whether the calendar is proleptic, i.e, supports dates before the epoch. (False)

KCalendarSystemChinesePrivate

Class definition in the private domain, publicy inherited from KCalendarSystemPrivate. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual AstroLocale* chineseLocation(int date)

Defines the Chinese Locale(as explained in the previous section) for implementing the Chinese Calendar

double midnightInChina(int date)

Computes the Chinese Universal Time for implementing astronomical calculations

int currentMajorSolarTerm(int date)

Returns the major solar term number at the given date, after computing the solar longitude at the given date.

int winterSolsticeOnOrAfter(int date)

Returns the date of December Solstice on or after the given date.

int chineseNewMoonOnOrAfter(int date)

Returns the date when the New Moon is observed at the Chinese Locale on or after the given date.

int chineseNewMoonBefore(int date)

Returns the date when the New Moon is observed at the Chinese Locale before the given date.

bool noMajorSolarTerm(int date)

Checks whether the month containing the given date has a major solar term or not.

bool priorLeapMonth(int m1, int m2)

Checks whether there is a leap month from the date m1(inclusive) to date m2.

int newYearInSui(int date)

Returns the starting date of Chinese New Year after December Solstice.

int newYearOnOrBefore(int date)

Returns the date of Chinese New Year on or before the given date.

void chineseDateToJulianDay(int year, double month, bool leap, int day, int &jd)

Converts Chinese date to Julian day.

void julianDayToChineseDate(int &year, double &month, bool &leap, int &day, int jd)

Converts Julian day to Chinese date. An indicator value (o.5) is added to the month to denote that it is a leap month.

virtual KLocale::CalendarSystem calendarSystem() const

Returns the calendar type.

virtual int monthsInYear(int year) const

Returns the number of months in the year used by this calendar system.

virtual int daysInMonth(int year, double month) const

Returns the number of days in a month used by this calendar system. The double data type implements functionalities for leap months.

virtual int daysInYear(int year) const

Returns the number of days in a year used by this calendar system.

virtual int daysInWeek() const

Returns the number of days in a week used by this calendar system, i.e, 7.

virtual bool isLeapYear(int year) const

Checks whether a year is a leap year or not.

virtual bool hasLeapMonths() const

Returns true is this calendar system has leap months. The Chinese calendar has leap months.

virtual bool hasYearZero() const

Returns true is this calendar system uses year 0. The Chinese calendar doesn't have a year 0.

virtual int maxDaysInWeek() const

Returns the maximum number of days in a week in this calendar system, i.e, 7.

virtual int maxMonthsInYear() const

Returns the maximum number of months in a year in this calendar system, i.e. 13.

virtual int earliestValidYear() const

Returns the earliest valid year in this calendar system, i.e., year 1.

virtual int latestValidYear() const

Returns the latest valid year in this calendar system, i.e., year 9999.

virtual QString monthName(double month, int year, Locale::DateTimeComponentFormat format, bool possessive) const

Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned.

virtual QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const

Gets specific calendar type weekday name for a given month number If an invalid weekday is specified, QString() is returned.

Astronomical Implementation

Re-implementations of the functions dateToJulianDay() and julianDayToDate() using the functions defined in the Astro Library.

bool julianDayToDate(int jd, int &year, double &month, double &day) const

Returns the date implemented in this calendar system from Julian day. It implements the previously defined julianDayToChineseDate() function. The double data type for month and days implement the functionalities of leap months and leap days (as in the Hindu Calendar).

bool dateToJulianDay(int &jd, int year, double month, double day) const

Returns the Julian day from the date in this calendar system. It implements the previously defined chineseDateToJulianDay() function.

Astro Library

Most of the astronomical functions have already been described in the implementation of Chinese Calendar. A few functions were appended to the Astro Library, namely:

astro.h

int roundOff(double value)

Rounds off the double value to the integer value

astrolunar.h

double newMoonBefore(double time)

Returns the moment of a New Moon occurrence before the given time

double newMoonAtOrAfter(double time)

Returns the moment of a New Moon occurrence at or after the given time

astrosolar.h

double estimatePriorSolarLongitude(double longitude, double time)

This function has an important role to play in implementing astronomical solar calendars, as it determines a particular solar longitude on or before the given date. The solar longitude can correspondingly help to find the day of the New Year as per the astronomical calendar.

The calculations for implementing the Chinese Calendar have been derived from the public domain Lisp code/Mathematical functions of Calendrical Calculations by Edward M. Reingold on the Illinois Institute of Technology website, and from the book Astronomical Algorithms by Jean Meeus.

Monday, June 27, 2011

Chinese Calendar - Basics

The Chinese calendar is a lunisolar calendar, as it uses months to approximate the tropical year. By the modern definition, the tropical year has been defined as the time taken by the Sun's mean longitude to increase by 360 degrees. The Chinese lunar calendar is followed by many Asian countries like Japan, Vietnam and Korea. Similar to the Islamic Calendar, 12 synodic months fall short by 11 days to the tropical year. However, instead of using a leap year to compensate for this difference, the Chinese use 'leap months' in about every third year to maintain the synchronization with the tropical year. A more predictable method to get the insertion of leap months is to follow the Metonic Cycle according to which 235 synodic months are equal to 19 tropical years (with a difference of only two hours). To break this down in calendar arithmetics:
  • 235 = 19x12 + 7
Therefore, 7 leap months are inserted in a period of 19 years. More details about the leap months have been mentioned in the forthcoming sections.

Despite the controversial debates going on between the Chinese calendar epoch, in our calculations we have been defined the Chinese epoch as March 8, 2637 BCE. There have been various controversies regarding the selection of the Chinese epoch. Scholars have claimed that the calendar was invented during the reign of Yellow Emperor Huangdi, which began in 2697 BCE. The debate is that some scholars claim that the year was invented in the first year of his reign (2697 BCE) while others claim that the year was invented in the 61st year of his reign (2637 BCE). There have been more than 50 calendar reforms in the Chinese calendar since its inception.

The Solar Terms
The Chinese astronomers use 24 solar nodes(solar terms) which correspond to significant events in the Chinese culture. Seasonal markers cut the ecliptic in 4 sections of 90degrees each. Solar terms cut the ecliptic in 24 sections of 15degrees each. The even terms are called the major solar terms or Zhongqi and the odd ones are called minor solar terms of Jieqi.


Ecliptic
longitude





Chinese name Approx Gregorian
date

Translation
315°




lichun
February 4
start of spring
330°




yushui
February 19
rain water
345°




jingzhe
March 5
awakening of insects





chunfen
March 20
vernal equinox
15°




qingming
April 5
clear and bright
30°




guyu
April 20
grain rains
45°




lixia
May 6
start of summer
60°




xiaoman
May 21
grain full
75°




mangzhong
June 6
grain in ear
90°




xiazhi
June 21
summer solstice
105°




xiaoshu
July 7
minor heat
120°




dashu
July 23
major heat
135°




liqiu
August 7
start of autumn
150°




chushu
August 23
limit of heat
165°




bailu
September 8
white dew
180°




qiufen
September 23
autumnal equinox
195°




hanlu
October 8
cold dew
210°




shuangjiang
October 23
descent of frost
225°




lidong
November 7
start of winter
240°




xiaoxue
November 22
minor snow
255°




daxue
December 7
major snow
270°




dongzhi
December 22
winter solstice
285°




xiaohan
January 6
minor cold
300°




dahan
January 20
major cold

The Month
The Chinese system of 12 double hours starts at 11pm. This has a significant role to play in Chinese astrology. The new moon marks the beginning of the new Chinese month. Regarding the calculations based on locale, before 1929 the calculations of the Chinese astronomy were based on the meridian in Beijing(39.9167degrees, 116.4167degrees); but in 1928, China adopted the standard time zone of 120degrees longitude which is close to the republican capital Nanjing. There are a variety of series for naming months, such as flowers, numbers, etc.


#


Corresponding to
Zodiac Sign
Solar
Longitude
Corresponding to
Flowers
1


正月 zhengyue 330° 正月Primens
2


二月 eryue 杏月 Apricomens
3


三月 sanyue 30° 桃月 Peacimens
4


四月 siyue 60° 梅月 Plumens
5


五月 wuyue 90° 榴月 Guavamens
6


六月 liuyue 120° 荷月 Lotumens
7


七月 qiyue 150° 蘭月 Orchimens
8


八月 bayue 180° 桂月 Osmanthumens
9


九月 jiuyue 210° 菊月 Chrysanthemens
10


十月 shiyue 240° 良月 Benimens
11


十一月 shiyiyue 270° 冬月 Hiemens
12


十二月 shieryue 300° 臘月 Ultimens

The Year
Chinese Calendar = solar calendar + lunisolar calendar
The solar calendar starts at the December Solstice and follows the 24 solar terms. It is known as sui. The lunisolar calendar starts at the Chinese New Year and it consists of 12 or 13 months. It is called nian. The solar calendar follows the tropical year more closely than the lunisolar calendar,. The solar year has a fixed length whereas the length of the lunisolar year is variable. An important rule in implementing the Chinese calendar is the definition of the leap month. The rule followed is:
  • December solstice falls in month 11. A sui is a leap sui if there are 12 complete months between the two 11th months at the beginning and the end of the sui.
  • In a leap sui, the first month that does not contain a major solar term is the leap month.
  • Leap months take the same number as the preceding month, and a prefix "Leap (閏)" before the number.

The Week
The modern Chinese calendar follows a 7-day week with Monday of the Gregorian Calendar being the first day of the week. The weekdays are named in pinyin as:
  1. Xingqi Yi (Weekday One)
  2. Xingqi Er (Weekday Two)
  3. Xingqi San(Weekday Three)
  4. Xingqi Si (Weekday Four)
  5. Xingqi Wu (Weekday Five)
  6. Xingqi Liu (Weekday Six)
  7. Xingqi Tian (Sun Day)

Thursday, June 23, 2011

Observational Islamic Lunar Calendar

After coding the astro library, the next step was to implement the astronomical calculations in the Islamic Calendar. The arithmetical Islamic Calendar had already been defined in the KCalendarSystem API, to implement the astronomical calculations, functions like dateToJulianDay() and julianDayToDate() had to be modified.

The header file for defining the observational Islamic Lunar calendar is kcalendarsystemislamiclunar.h. It defines two classes:

KCalendarSystemIslamicLunar
Class definition in the public domain, publicly inherited from KCalendarSystem. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual QString calendarType() const
Returns the calendar system type.

virtual QDate epoch() const
Returns a QDate holding the epoch of the calendar system. Islamic epoch is defined on 16th July 622 AD, which is Julian Day 1949440.

virtual QDate earliestValidDate() const
Returns the earliest date valid in this calendar system implementation, i.e. the epoch of the calendar system as the Islamic calendar is not proleptic.

virtual QDate latestValidDate() const
Returns the latest date valid in this calendar system implementation, i.e. 29th December 9999.

virtual bool isValid(int year, int month, int day) const
Returns whether a given date is valid in this calendar system.

virtual bool isValid(const QDate &date) const
Returns whether a given date is valid in this calendar system.

virtual bool isLeapYear(int year) const
Returns whether a given year is a leap year.

virtual bool isLeapYear(const QDate &date) const
Returns whether a given year(taken from the QDate) is a leap year.

virtual QString monthName(int month, int year, MonthNameFormat format = LongName) const
Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned.

virtual QString monthName(const QDate &date, MonthNameFormat format = LongName) const
Gets specific calendar type month name for a given date.

virtual QString weekDayName(int weekDay, WeekDayNameFormat format = LongDayName) const
Gets specific calendar type week day name. If an invalid week day is specified, QString() is returned.

virtual QString weekDayName(const QDate &date, WeekDayNameFormat format = LongDayName) const
Gets specific calendar type week day name.

virtual int weekDayOfPray() const
Returns the weekday of pray for this calendar system, i.e. Friday.

virtual bool isLunar() const
Returns whether the calendar is lunar.

virtual bool isLunisolar() const
Returns whether the calendar is lunisolar.
virtual bool isSolar() const
Returns whether the calendar is solar.

virtual bool isProleptic() const
Returns whether the calendar is proleptic, i.e, supports dates before the epoch.

KCalendarSystemIslamicLunarPrivate
Class definition in the private domain, publicy inherited from KCalendarSystemPrivate. It re-implements the virtual functions defined in the KCalendarSystem class. The re-implemented functions are defined in the public domain of the class.

virtual KLocale::CalendarSystem calendarSystem() const
Returns the calendar type.

virtual void loadDefaultEraList()
Loads the era supported by this calendar system.

virtual int monthsInYear(int year) const
Returns the number of months in the year used by this calendar system.

virtual int daysInMonth(int year, int month) const
Returns the number of days in a month used by this calendar system.

virtual int daysInYear(int year) const
Returns the number of days in a year used by this calendar system.

virtual int daysInWeek() const
Returns the number of days in a week used by this calendar system.

virtual bool isLeapYear(int year) const
Checks whether a year is a leap year or not.

virtual bool hasLeapMonths() const
Returns true is this calendar system has leap months. The Islamic calendar doesn't have leap months.

virtual bool hasYearZero() const
Returns true is this calendar system uses year 0. The Islamic calendar doesn't have a year 0.

virtual int maxDaysInWeek() const
Returns the maximum number of days in a week in this calendar system, i.e, 7.

virtual int maxMonthsInYear() const
Returns the maximum number of months in a year in this calendar system, i.e. 12.

virtual int earliestValidYear() const
Returns the earliest valid year in this calendar system, i.e., year 1.

virtual int latestValidYear() const
Returns the latest valid year in this calendar system, i.e., year 9999.

virtual QString monthName(int month, int year, Locale::DateTimeComponentFormat format, bool possessive) const
Gets specific calendar type month name for a given month number If an invalid month is specified, QString() is returned.

virtual QString weekDayName(int weekDay, KLocale::DateTimeComponentFormat format) const
Gets specific calendar type weekday name for a given month number If an invalid weekday is specified, QString() is returned.

Astronomical Implementation
Re-implementations of the functions dateToJulianDay() and julianDayToDate() using the functions defined in the Astro Library.

bool julianDayToDate(int jd, int &year, int &month, int &day) const
Gets the date in this calendar system from the Julian day. The astro library function visibleCrescentBefore() is used to get the Julian day when the visible crescent was observed on or before the jd. The number of months elapsed since the Islamic epoch are then calculated and are used to get the year and month:
  • Year = elapsedMonths/12 + 1
  • Month = elapsedMonths%12 + 1
  • Day = jd - day returned by visiblecrescentbefore() +1
The function returns false if it encounters an invalid date at any point during the calculations, otherwise it returns true.

bool dateToJulianDay(int &jd, int year, int month, int day) const
Gets the Julian day number corresponding to a given date in this calendar system. The astro library function visibleCrescentBefore() is used to get the Julian day when the visible crescent was observed on or before a particular date. The date passed as an argument to the visibleCrescentBefore() function is calculated as:
  • Islamic epoch + the number of days elapsed since the start of the calendar to median of the current month
The Julian day is then calculated by adding to the value returned by the visibleCrescentBefore() function with the aforementioned argument.

The function returns false if it encounters an invalid date at any point during the calculations, otherwise it returns true.

The calculations for implementing the Islamic Lunar Calendar have been derived from the public domain Lisp code/Mathematical functions of Calendrical Calculations by Edward M. Reingold on the Illinois Institute of Technology website.

Wednesday, June 22, 2011

Astro Library

While I was programming the astronomical functions, I had to reconsider some function definitions to match the compatibility with the KCalendarSystem API. The function definitions and their functionality are mentioned in the following post:

astro.h
Astronomical functions require the geographical latitude and longitude for most of their calculations. KDECore does not have any sort of data functionality that would use the geographical latitude and longitude. The only reliable way to get this data is to ask the user to input it while defining the KDE locale (as in KStars, etc). I am yet to talk regarding the feasibility of this feature with my mentor, John Layt, and then decide upon the method to proceed further on this. Until then, I have defined a structure in the header file and would be using this structure as an argument to member functions requiring geographical latitude and longitude. The main reason of using a structure over an enum was due to the fact that I can define the data type in the structure and wouldn't require static casting of data while handling the calculations of latitude and longitude.

static double zoneFromLongitude(struct AstroLocale locale) Calculates the time zone from a given locale (latitude and longitude) and returns it in degrees.

double universalFromLocal(double localTime, struct AstroLocale locale)
Returns the Universal Time from the Local time by at the given locale.

double localFromUniversal(double universalTime, struct AstroLocale locale)
Returns the Local Time from Universal Time.

double standardFromUniversal(double universalTime)
Returns the Standard Time from Universal Time.

double universalFromStandard(double standardTime)
Returns the Universal Time from Standard Time.

double standardFromLocal(double localTime, struct AstroLocale locale) Returns Standard Time from Local Time.

double localFromStandard(double standardTime, struct AstroLocale locale) Returns Local Time from Standard Time.

double ephemerisCorrection(double time)
Returns the corrections based on the astronomical ephemeris, which computes the secondary realizations based on lunar observations and the Cesium atomic clock.

double dynamicalFromUniversal(double time)
Returns the Dynamical(or Ephemeris) Time from Universal Time by applying the Ephemeris Correction to it.

double universalFromDynamical(double time)
Returns Universal Time from Dynamical Time.

double julianCenturies(double time)
Returns the Julian Centuries since January 1, 2000 12:00PM.

double obliquity(double time)
Computes the obliquity of the ecliptic.

double equationOfTime(double time)
Calculates the difference between the apparent solar time and the mean solar time. The equation of time results from the two superposed astronomical causes of the obliquity of the ecliptic and the eccentricity of Earth's orbit which causes a non-uniformity in the apparent daily motion of the Sun relative to the stars.

double apparentFromLocal(double localTime, struct AstroLocale locale)
Returns Apparent Time(calculation of time based on the position of the sun) from Local Time.

double localFromApparent(double apparentTime, struct AstroLocale locale)
Returns Local Time from Apparent Time.

double siderealFromMoment(double time)
Returns the sidereal time from the current moment considering the precession of equinoxes.

double declination(double time, double eclipticLatitude, double eclipticLongitude) double rightAscension(double time, double eclipticLatitude, double eclipticLongitude)
These functions compute the polar coordinates in degrees, from equatorial coordinates.

int roundOff(double value)
Rounds off the double value to integer value

astrosolar.h
Contains functions based on the astronomy of the Sun. As of now, the features required for implementing the Islamic Calendar have been specified in this header file. Other functions/features would be appended later on as per the need of other calendars.

double aberration(double time)
Returns the value in degrees considering the effect of the movement of the Sun to about 20.47 seconds of the arc during the time its light is en route to the Earth.

double nutation(double time)
Returns the value in degrees, compensates for the small irregularity due to the precession of equinoxes.

double solarLongitude(double time)
Returns the equatorial longitude of the Sun.

double solarAnomaly(double time)
Computes solar anomaly observed in the celestial sphere.

double sineOffset(double time, struct AstroLocale locale, double angleDepression)
Computes the offset of the sine of the angle of depression of the Sun at the time of twilight.

double approxTimeOfTwilight(double time, struct AstroLocale locale, double angleDepression, bool early)
Returns an approximate time at which twilight would occur.

double timeOfTwilight(double approxTime, struct AstroLocale locale, double angleDepression, bool early)
Returns the precise time (precision of up to 30seconds) at which the twilight would occur.

double dawn(int time, struct AstroLocale locale, double angleDepression)
Returns the time at which dawn is observed.

double dusk(int time, struct AstroLocale locale, double angleDepression)
Returns the time at which dusk is observed.

double estimatePriorSolarLongitude(double longitude, double time)
This function has an important role to play in implementing astronomical solar calendars, as it determines a particular solar longitude on or before the given date. The solar longitude can correspondingly help to find the day of the New Year as per the astronomical calendar.

astrolunar.h
Contains functions based on the astronomy of the Moon. The Islamic Calendar is a lunar calendar which is based on the sightings of the crescent and observations of the moon. The lunar crescent visibility criteria defined by S.K. Shaukat has been used to derive the astronomical implementation of the calendar.

double nthNewMoon(int n)
Returns the date on which the nth new moon would be observed.

double meanLunarLongitude(double time)
Computes the mean lunar longitude (without considering the effects contributed by the other heavenly bodies in the Celestial Sphere); it returns the value in degrees. The moon is assumed to revolve around the Earth in a circle while calculating the mean lunar longitude.

double lunarElongation(double time)
Returns lunar elongation, i.e., the angular distance of the moon, east of the sun.

double lunarAnomaly(double time)
Computes lunar anomaly.

double moonNode(double time)
Computes the angle of orbital nodes of the moon, i.e. the points where the orbit of the moon crosses the ecliptic.

double lunarLongitude(double time)
Calculates the lunar longitude considering the effects of the Sun, Jupiter, Venus, precession of equinoxes, flattening of the Earth at the poles and the corrections imposed on the mean lunar longitude to make it compatible with the elliptical orbit of the Moon around the earth.

double lunarLatitude(double time)
Calculates the latitude of the moon, considering the effects of Jupiter, flattening of Earth near the poles, and a few other complex factors as derived from Cassini's Law.

double lunarPhase(double time)
Returns the phase of the moon in degrees.

double lunarDistance(double time)
Returns the distance of the moon from the Earth at a given time.

double lunarParallax(double time, struct AstroLocale locale)
Calculates the lunar parallax at a given time as seen from a locale.

double lunarAltitude(double time, struct AstroLocale locale)
Calculates the geocentric lunar altitude in degrees, at a given time as seen from a locale.

double lunarAltitudeTopocentric(double time, struct AstroLocale locale)
Calculates the topocentric lunar altitude at a given time as seen from a locale.

bool lunarCrescentVisibility(int time, struct AstroLocale locale)
Returns whether the lunar crescent is visible from the locale at a given time.

int visibleCrescentBefore(int time, struct AstroLocale locale)
Calculates the date of the same month on which the crescent was visible before the given time, it, therefore, returns the date on which the lunar crescent had just met its visibility criteria.

double newMoonBefore(double time)
Returns the moment of a New Moon occurrence before the given time

double newMoonOnOrAfter(double time)
Returns the moment of a New Moon occurrence at or after the given time

The astronomical functions have been translated/derived from the publicly available Lisp Code of Calendrical Calculations by Edward M. Reingold on the Illinois Institute of Technology website.

Thursday, June 16, 2011

Islamic Calendar - Technical Implementation

For the past few days, I have been researching a lot about the astronomical calculations that are going to be used for the Islamic Calendar. The research has been documented from the following sources, namely:
  • Calendrical Calculations: Third Edition - Nachum Dershowitz and Edward M. Reingold
  • Notes and Errata on Calendrical Calculations: Third Edition - 25th May 2011
  • Astronomical Algorithms: First Edition - Jean Meeus
  • Practical Astronomy with your Calculator: Third Edition - Peter Duffet-Smith
  • How to compute planetary positions - Paul Schlyter
The amount of calculations required for the complete implementation of the calendar are highly extensive, and require very high precision. Without the astronomical calculations, the Islamic Calendar lacks accuracy by 1-2 days and therefore it becomes difficult to predict future dates in the Islamic Calendar. The astronomical calculations are so precisely timed that such an ambiguity in the prediction of dates of the Islamic Calendar is reduced to 1 day in 2500 years. As we have discussed earlier, that the lunar crescent visibility serves as an important criteria in determining the precise Islamic Calendar, we shall be defining the necessary functions that are required to calculate and successfully implement the astronomical calculations in the Islamic Calendar.

The astronomical files will be defined based on the considerations of time and astronomy as deducted from the theoretical research.

astro.h
This header file would contain the general functions for astronomical calculations. The functions perform calculations for converting time between different formats, for calculating Julian centuries and the ephemeris correction, for calculating significant moments of the day that have astronomical significance and polar-coordinate conversion. The following member functions would be implemented:
  • zoneFromLongitude()
  • universalFromLocal()
  • localFromUniversal()
  • standardFromUniversal()
  • universalFromStandard()
  • standardFromLocal()
  • localFromStandard()
  • ephemerisCorrection()
  • dynamicalTime()
  • julianCenturies()
  • equationOfTime()
  • apparentFromLocal()
  • localFromApparent()
  • siderealFromMoment()
  • obliquity()
  • declination()
  • rightAscension()
  • approxMomentOfTwilight()
  • momentOfTwilight()
  • dawn()
  • dusk()
astrosolar.h
Astronomical calculations which relate to various aspects involving the sun would be performed by the functions defined in this file.
  • nutation()
  • aberration()
  • solarAnomaly()
  • solarLongitude()
astrolunar.h
Out of all the heavenly objects that are visible in the celestial sphere, the moon is perhaps the most beautiful of them all. It is also, one of the most hardest to correctly determine it's position and various other astronomical aspects. This header file will be defining the functions which will be used in the astronomical calculations which relate to the moon.
  • lunarCorrection()
  • nthNewMoon()
  • meanLunarLongitude()
  • lunarElongation()
  • lunarAnomaly()
  • moonNode()
  • lunarLongitude()
  • lunarLatitude()
  • lunarPhase()
  • lunarDistance()
  • lunarParallax()
  • lunarAltitude()
  • lunarAltitudeTopocentric()
  • visibleCrescent()
  • lunarPhaseBefore()
All the astronomical calculations required to correctly calculate the Islamic Calendar have been defined in aforementioned header files.

As the project would progress along the time-line, the necessary functionalities required by the other calendar systems could be easily appended/modified/implemented in these files.

The Calendar
Most of the code required in the astronomical Islamic Calendar is similar to the Islamic Civil Calendar, with the difference that the lunar crescent visibility criteria affects the 'day' in both the calendars. The astronomical calendar would be derived from kcalendarsystem.h and would include functionalities to modify the date according to the crescent visibility. The crescent visibility will be implemented mainly through the function lunarPhaseBefore() defined in astrolunar.h.


However, one particular area that I haven't been able to figure out yet, that is, the way in which I am supposed to handle the locale argument for the functions. Many functions use their calculations depending on the latitude and longitude of the locale. KLocale, however, does not define the latitude and longitude in its locale object. The longitude of the locale could be determined by the local time (or time zone) specified in KLocale. To work around the latitude, we might have to manually tabulate the values according to the country (or country code).