# Computer Method

The previous section shows the steps to determine if a given year is a normal year, a leadp-day year or a leap-month year. With the result, we can loop through the calendar year from a known point until the target year.

## Sample Php Code

The following are Php code from the algorithm from previous section. The following are based on the books by Mr. Roath Kim Soeun. This is only a portion of the calculation that needed to determine if the year is a regular year, a leap-day year, or a leap-month year.

// return 0-29 function get_bodithey($year) { $ahk = get_aharkun($year); $avml = floor((11 * $ahk + 25) / 692); $m = $avml + $ahk + 29; return ($m % 30); } // return 0-291 function get_avoman($year) { $ahk = get_aharkun($year); $avm = (11 * $ahk + 25) % 692; return $avm; } // return int function get_aharkun($ad_year) { $beyear = get_be_year($ad_year); $t = $beyear * 292207 + 499; $ahk = floor($t / 800) + 4; return $ahk; } // return 1-800 function kromthupul($be_year) { $akh = get_akhakun_mod($be_year); $krom = 800 - $akh; return $krom; } function is_khmer_solar_leap($year) { $be_year = get_be_year($year); $krom = kromthupul($be_year); if ($krom <= 207) return 1; else return 0; } function get_akhakun_mod($be_year) { $t = $be_year * 292207 + 499; $ahkmod = $t % 800; return $ahkmod; } // return 0:regular, 1:leap month, 2:leap day, 3:leap day and month function get_bodithey_leap($ad_year) { $result = 0; $a = get_avoman($ad_year); $b = get_bodithey($ad_year); // check bodithey leap month $bodithey_leap = 0; if ($b >= 25 || $b <= 5) { $bodithey_leap = 1; } // check for avoman leap-day based on gregorian leap $avoman_leap = 0; if (is_khmer_solar_leap($ad_year)) { if ($a <= 126) $avoman_leap = 1; } else { if ($a <=137) { // check for avoman case 137/0, 137 must be normal year (p.26) if (get_avoman($ad_year + 1) == 0) { $avoman_leap = 0; } else $avoman_leap = 1; } } // case of 25/5 consecutively // only bodithey 5 can be leap-month, so set bodithey 25 to none if ($b == 25) { $next_b = get_bodithey($ad_year + 1); if ($next_b == 5) $bodithey_leap = 0; } // case of 24/6 consecutively, 24 must be leap-month if ($b == 24) { $next_b = get_bodithey($ad_year + 1); if ($next_b == 6) $bodithey_leap = 1; } // format leap result (0:regular, 1:month, 2:day, 3:both) if ($bodithey_leap == 1 && $avoman_leap == 1) { $result = 3; } else if ($bodithey_leap == 1) { $result = 1; } else if ($avoman_leap == 1) { $result = 2; } else $result = 0; return $result; } // return 0:regular, 1:leap month, 2:leap day (no leap month and day together) function get_protetin_leap($adyear) { $b = get_bodithey_leap($adyear); if ($b == 3) { return 1; } if ($b == 2 || $b == 1) { return $b; } // case of previous year is 3 if (get_bodithey_leap($adyear - 1) == 3) { return 2; } // normal case return 0; }

The final get_protetin_leap function can tell us whether a particular year is a normal year, a leap-month year or a leap-day year. Thus we can iterate through the year from a know point to a target year.

## Iteration

The approach is to use the known Gregorian calendar then mapped out the correspond Khmer calendar system. After knowing the type of Khmer calendar year, we will increment one year at a time from a specific year to the target year. To do that we first need a start date. I use January 1, 1900 AD in Gregorian calendar. This date will be called an epoch. The associate Khmer known date is 1 Keit of Bos (month number two).

Epoch Date: January 1, 1900

Associate Khmer Epoch Date: epoch_year = 1900; khmer_month = 2; // 1:Makasay, 2:Boss khmer_day = 1; // First day of the month (1-30)

Next, we will start iterate from the Epoch year to the desired calendar year that we wanted to show. We start of by saving off the Epoch month and day into $newm and $newd respectively.

newm = epoch_month; newd = epoch_day;

We need to update the $newm and $newd per each iteration. In order to perform this update, we need to know how many days in a Gregorian year. This function (is_gregorian_leap) determines if a year is a Gregorian leap year or not. See the code section for detail implementation of this function. If a year a Gregorian year is a leap year then it has 366 days and 365 days if it is not. We save this in $gnumday variable.

// get number of days in a Gregorian year if (is_gregorian_leap(year)) { gnumday = 366; } else { gnumday = 365; }

Then we find the number of days that differ in Gregorian year and Khmer year. The number of days in Khmer year is determined by the type of Khmer year (discuss in the next section). If it is a leap-day year the number of days is 355 days, a leap-month year is 384 days, and a normal year is 354 days.

// get number of days in a Khmer year if (is_khmer_leap_month(year)) { knumday = 384; } else if (is_khmer_leap_day(year)) { knumday = 355; } else { knumday = 354; } // find the different between gnumday and knumday diff = gnumday - knumday;

From the differences in number of days above (diff), we can update newm and newd for that year. This update is using the fact that if Khmer year is shorter or longer than Gregorian year by x number of days, we just subtract or add from the current KhmerDay and KhmerMonth respectively.

This method is done by determining how many days in a particular Khmer month in case the subtraction or addition goes pass the valid number of day in Khmer month (1 to 29 or 30).

// find newd, newm of Khmer date newd = newd + diff; maxday = get_numofday_in_kmonth(newm, year); // if newd is bigger the number of day in // in that month, adjust the newm and newd while(newd > maxday) { newd = newd - maxday; newm++; maxday = get_numofday_in_kmonth(newm, year); } // if newd is negative (case of subtraction) while (newd <= 0) { newd = get_numofday_in_kmonth(newm - 1, year) + newd; newm--; }

In this iteration, the Khmer month and day would result in January 1, 1901.

The iteration repeats until the year matches the year we want to show. At the end of the iteration, we know that Khmer date for the beginning of the year to display. This is saved in $newm and $newd for Khmer month and day respectively.

Now we call to the Khmer calculation to determine the type of year for Khmer calendar.

get_protetin_leap($year);After knowing the KhmerDay and KhmerMonth for a given year, we can display the monthly calendar with Khmer date. We first need to identify if the given Khmer year is a normal, leap-day, or leap-month year.

- If it is a normal year, we know that there are 12 months in that year and the number of days per month can be found in the appendix. Notice that the month of Jays is 29.
- If it a leap-day year, everything is the same as above except Jays has 30 days instead of 29 days.
- If it is a leap-month year, there are 13 months for that year and the month of Ashad become 2 months (Badhamasad and Thutiyasad) with 30 days each. Note that the month of Jays has 29 days.

## Khmer Monthly Calendar Utility

From the algorithm above, I can create a Khmer monthly calendar. Khmer calendar typically added specific the moon phases. We can use the Khmer day to determine the moon phases. If the Khmer day is 8 (8 Keit), it is a first quarter and 15 (15 Keit) is a full moon. If it is the last day of the Khmer month which is 29 or 30 (14 Roaj or 15 Roaj), it is a new moon.

There are also specific types of day that are added to the calendar. For example Tgnai Koar, Tgnai Pengboramei, and Tgnai Sel are usually shown in Khmer calendar. See Khmer Terminologies in the appendix for more detail on how to add these types of day.

It is important to display the Khmer associated months in the calendar. One Gregorian month can span exactly one Khmer month or it can span up to three months. To accommodate the possibilities, I use three different color codes to identify the month. The Khmer date shown each day will have the color that corresponds to the month.

A calendar cannot be complete without display the year. The most used era in Khmer calendar is Buddhist Era (BE). To find BE year, we just add 544 to the current Gregorian year. Be aware that BE year is incremented in Khmer New Year day. The date is typically fall in April. See the section about Songkran date for more detail. The following is the pseudo code for determining the BE.

if (current_month < april) { BE = current_year + 543; } else { BE = current_year + 544; }

Khmer also uses Moha Sakaraj (MS)1 and Jolak Sakaraj (JS)2. The following shows the pseudo code of calculating the MS and JS.

MS = current_year - 78; JS = current_year - 638;

The religious events can also be added to the calendar by using the Khmer date. See the appendix for religious events.

## Data Verification

The following are list of dates that has Khmer Calendar and Gregorian Calendar from different sites I found online.

Source | Event | Khmer Calendar Date | Gregorian Date | Comment |
---|---|---|---|---|

http://km.wikipedia.org/wiki/និល_ទៀង | និល ទៀង ប្រសូត | ថ្ងៃព្រហស្បតិ៍ ២កើត ខែអស្សុជ ឆ្នាំឆ្លូវ បញ្ចស័ក ព.ស.២៤៥៧ | ២ តុលា គ.ស.១៩១៣ | Matched |

http://whoincam.wordpress.com/ | ថ្ងៃព្រហស្បតិ៍ ១៣រោច ខែបុស្ស ឆ្នាំវក (ឆស័ក)ព.ស.២៤៨៨ | ថ្ងៃទី១១ ខែមករា ឆ្នាំ១៩៤៤ | 1945 would match | |

http://km.wikipedia.org/wiki/ប្រាក់_ហ៊ិន | ប្រាក់ ហ៊ិន | ៨កើត ខែកក្ដិក ឆ្នាំកុរ ព.ស.២៤៩១ | ២០ ខែវិច្ឆិកា គ.ស.១៩៤៧ | Matched |

http://km.wikipedia.org/wiki/ជួន_ណាត | Chuon Nath | ថ្ងៃ១៣កើត និង១៤កើត ខែភទ្របទ (ឆ្នាំរកា ឯកស័ក, ព.ស. ២៥១៣) |
ថ្ងៃទី២៤ និង២៥ ខែកញ្ញា ឆ្នាំ១៩៦៩ | Matched |

http://whoincam.wordpress.com/ | ថ្ងៃច័ន្ទ ៦រោច ខែអស្សុជ ឆ្នាំរោង (សំរឹទ្ធិស័ក) ព.ស.២៥៣២ | ថ្ងៃទី៣១ ខែតុលា គ.ស.១៩៨៧ | 1988 would match | |

http://km.wikipedia.org/wiki/ជួន_ណាត | Chuon Nath Death | ថ្ងៃ១២កើត ខែភទ្របទ ឆ្នាំរកា ឯកស័ក ព.ស.២៥១៣ | ថ្ងៃទី២៣ កញ្ញា ឆ្នាំ១៩៦៩ |
Matched |

http://www.everyday.com.kh | ពិធីច្រត់ព្រះនង្គ័ល | ថ្ងៃ ៤ រោច ខែពិសាខ | ថ្ងៃទី ២៦ ឧសភា2005 | Matched |

http://www.chanbokeo.com | ថ្ងៃ ចន្ទ ១២កើត ខែមាឃ ឆ្នាំខាលទោស័ក ព.ស ២៤៩៣ | ទី១៨ ខែកុម្ភៈឆ្នាំ១៩៥១ | Matched | |

http://khmeritforyou.blogspot.com | ថ្ងៃ ភ្ជុំបិណ្ឌ | ថ្ងៃ ១៥ រោច ខែ ភទ្របទ ឆ្នាំ ជូត សំរិទ្ធិស័ក ព.ស. ២៥៥២ |
ទី 29 ខែ កញ្ញា ឆ្នាំ 2008 | Matched |

## Sample Computer Programs

See the Calendar Tools section more information about the web utilities and source codes on related materials.

This is a sample utility that displays Khmer Chhankitek calendar. The implementation is done using PHP.

<< Calendar Algorithm | < Table of Content > | Khmer New Year >> |