Sunday, April 16, 2017

variance of khmer lunar calendar

in lunar calendar, we have to add days to keep pace with solar calendar, since there's only 354 days a year. so we use big leap year to small leap year to add all  those missing days.

the calendar below has the following rules
- big leap year we add a month = 30 days, and we have 7 big leap year in 19 year circle
- small leap year we add a day, and we have 11 in 57 year period circle.
- big leap year happens in year 3,6,9,11,14,17,19]
- small leap year happens in year 5,10,15,20,25,30,35,40,45,50,55

*** month name can letter code
Caitra             e  29  ចេត្រ
Vaisākha         f  30  ពិសាខ
Jyaiṣṭha           g  29  ជេស្ឋ
Āṣāḍha           h  30  អាសាឍ
Śrāvaṇa          i  29  ស្រាពណ៍
Bhādrapada    j  30  ភទ្របទ
Āśvina            k  29  អស្សុជ
Kārttika          l  30  កត្តិក
Mārgaśirṣa     a  29 មិគសិរ
Pauṣa              b  30 បុស្ស
Māgha            c  29 មាឃ
Phālguna       d  30  ផល្គុន

and h2 for double Āṣāḍha, when there's a big leap year






************ code *********
#!/usr/bin/python
import sys
import datetime

import calendar
g = calendar.TextCalendar()
# g.pryear(1900)

now = datetime.datetime.now()
thisyear = now.year
n = calendar.Calendar(0)
# print n
b = n.yeardatescalendar(1900)
def getoneyear(b, y):
    dr = {}
    dr[y] = []
    for i in b:
        # print i
        for j in i:
            # print j
            for l in j:
                for o in l:
                   
                    # print type(o.year)
                    if o.year == y:
                        # print "break"
                        # break
                        # print o
                        dr[y].append(o)
    return sorted(list(set(dr[y])))
    # break
wholedict = {}
def addluny(d,sostart,lustart):
    pass
# n = 9
# n = 750
# n = 1035
# n = 1320
n = 1548
# n = 1800
# n = 1900
cal1 = calendar.Calendar(0)
# for i in range (200):
# for i in range (300):
for i in range (1500):
    year = n + i
    wholedict[year]= []
    b = cal1.yeardatescalendar(year)
    wholedict[year]=getoneyear(b,year)

# getoneyear(b,1900)
# b.prcal()
# print b
# print "))))))))))))"
# l = g.formatyear(1900)
# print type(l)
wholedictbud = {}
bn = 1
bmo = 1


#if 1900 db = 1, big=True mb = 'b', curcal 1909

#9, or 114 circle from -390
db = 10
big = True
mb = 'b'
bigleapi = 19
bigleap = True
smallleapi = 57
smallleap = True


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

#1800
# db = 6
# big = True
# mb = 'b'
# bigleapi = 5
# bigleap = False
# smallleapi = 10
# smallleap = True

# 1900
# db = 1
# big = True
# mb = 'b'
# bigleapi = 10
# bigleap = False
# smallleapi = 13

jindex = 1


# bigleapi = 10

# smallleapi = 13

wleap = False
for k in sorted(wholedict.keys()):
    wholedictbud[k] = []
    # if bmo % 2 == 0:
    #     big =True
    # else:
    #     big = False
    # bmo += 1
    # print k
    # print len(wholedict[k])
   
    if bigleapi in [3,6,9,11,14,17,19]:
            bigleap =True
    else:
        bigleap = False
    if bigleapi == 19:
        bigleapi = 0

    # if smallleapi in [5,10,14,20,24,28,33,39,44,48,53]:
    # if smallleapi in [5,9,15,19,24,28,34,39,44,48,53]:

    if smallleapi in [5,10,15,20,25,30,35,40,45,50,55]:
        smallleap = True
        # smallleap = wleap
        # if bigleap == True:
        #     wleap = True
        # else:
        #     smallleap = True
        #     wleap = False
       
    else:
        smallleap = False

    # if wleap == True:
    #     smallleap = True
    #     wleap = False

    if smallleapi == 57:
        smallleapi = 0
    for j in wholedict[k]:
        # print j
        # we we just db instead of jindex as the day tracker we can start buddist day at any day
       
        if big == True:
            cbig = False
            # for j in range(31):
            mdb = mb + ":" + str(db)
           
            idata = [j, mdb]
           
            # if jindex == 30:
            if db == 30:
               
                if mb == 'l':
                    mb = 'a'
                elif mb == 'h':
                    # print int(k)
                   
                    # if int(k) == 1901 or k == 1904 or k == 1907 or k ==1909 or k==1912\
                    #      or k == 1915 or k==1918 or k==1920 or k==1923 or k==1926 or k==1928\
                    #      or k ==1931 or k==1934 or k==1937 or k==1939 or k==1942 or k==1945\
                    #      or k==1947 or k==1950 or k==1993:
                    # if    k in [1901,1904,1907,1909,1912,1915,1918,1920,1923,1926,1928,1931,1934,1937\
                    #          ,1939,1942,1945,1947,1950,1953,1956,1959,1961,1964,1966,1969,1972\
                    #          ,1975,1977,1980,1983,1985,1988,1991,1994,1996,1999,2002,2004,2007,2010,2012\
                    #          ,2015,2018,2021,2023,2026,2029,2031,2034,2037,2040,2042,2045,2048,2051,2053\
                    #          ,2056,2059,2061,2064,2067,2069,2072,2075,2078,2080,2083,2086,2088,2091,2094,2097,2099\
                    #          ,2102]:
                        # print k
                    if bigleap == True:   
                        mb = "h2"
                        cbig = True
                        # print mb
                    else:
                        mb = chr(ord(mb) + 1)
                elif mb == "h2":
                    mb = 'i'
                else:
                    mb = chr(ord(mb) + 1)
                db = 0
                jindex = 0
                big = cbig

            # db +=1

        else:
            # for j in range(30):
            mdb = mb + ":" + str(db)
            idata = [j, mdb]
            # if (k == 1902 or k == 1906 or k == 1911 or k == 1917 or k==1922\
            #     or k==1927 or k==1932 or k==1938 or k==1943 or k==1948)and mb =="g":
            # if    (k in [1902,1906,1911,1917,1922,1927,1932,1938,1943,1948,1954,1959,1963,1968,1973\
            #     ,1978,1984,1989,1993,2000,2005,2009,2016,2020,2025,2030,2035,2041,2046,2050\
            #     ,2057,2062,2066,2071,2076,2082,2087,2092,2098,2103,2108,2104,2119,2123,2128\
            #     ,2133,2138,2144,2149,2153,2160,2165,2169,2174,2180]) and mb=="g":
            if smallleap == True and mb =="g":
            # if bigleap == True and mb=="g":
                if db == 30:
                    if mb == 'l':
                        mb = 'a'

                    else:
                        mb = chr(ord(mb) + 1)
                    db = 0
                    jindex = 0
                    big = True
            else:
                if db == 29:
                    if mb == 'l':
                        mb = 'a'

                    else:
                        mb = chr(ord(mb) + 1)
                    db = 0
                    jindex = 0
                    big = True
           
        db +=1
           
            # print idata
        # print idata
        wholedictbud[k].append(idata)
        jindex += 1
    bigleapi +=1
    smallleapi +=1
        # print jindex
        # sys.exit()
    # break
inpy = int(sys.argv[1])
inpm = int(sys.argv[2])
weekday = calendar.weekday(inpy, inpm, 1)
# print weekday
outp = wholedictbud[inpy]
outindex = weekday
outre = []
for i in outp:
    if i[0].month == inpm:
        data = [i[0],i[1],outindex]
        if outindex == 6:
            outindex = -1
        outindex += 1
        outre.append(data)
print "\t\t",sys.argv[1], "^" ,str(inpy + 544)
print "\t\t    " + str(inpm)
dayname = ["Mon  ", "Tue  ", "Wen  ", "Thu  ", "Fri  ", "Sat  ","Sun  "]
col_width = max(len(word) for row in dayname for word in row) + 2
print " ".join(word.ljust(col_width) for word in dayname)
rerow = []
rerow2 = []
count = 1
for ii in outre:
    cblue = bcolors.OKBLUE
    cred = bcolors.FAIL
    if len(str(ii[0].day)) == 1:
        mpler = 4
    else:
        mpler = 3
    if len(ii[1]) ==3:
        rerow2.append(ii[1] + "  ")
    elif len(ii[1]) ==4:
        rerow2.append(ii[1] + " ")
    else:
        rerow2.append(ii[1])
    rerow.append(str(ii[0].day) + " " * mpler )
   
    if ii[2] == 6:
        if len(rerow)<7:
            if int(rerow[0]) == 0:
                while len(rerow) <=7:
                    rerow.append("    ")
                    rerow2.append("    ")
            if int(rerow[0])> 0:
                while len(rerow) < 7:
                    rerow.insert(0,"     ")
                    rerow2.insert(0,"     ")
        # print rerow
        col_width = max(len(word) for row in rerow for word in row) + 2
        col_width2 = max(len(word) for row in rerow2 for word in row) + 2
        print cblue +" ".join(word.ljust(col_width) for word in rerow)
        print cred + " ".join(word.ljust(col_width) for word in rerow2)
        rerow = []
        rerow2 = []
    if len(outre) == count:
        # col_width = max(len(word) for row in rerow for word in row) + 2
        # print " ".join(word.ljust(col_width) for word in rerow)
        col_width = max(len(word) for row in rerow for word in row) + 2
        col_width2 = max(len(word) for row in rerow2 for word in row) + 2
        print cblue + " ".join(word.ljust(col_width) for word in rerow)
        print  cred +" ".join(word.ljust(col_width) for word in rerow2)

    count += 1
   
# for i in wholedictbud[inpy]:
#     print i
# print len(whledict[2000])
# hi = 1
# for i in wholedict[1900]:
#     print i
#     print hi
#     hi +=1
# n = 1
# for i in sorted(wholedict.keys()):
#     print wholedict[i]
#     if n == 3:
#         break
#     n += 1

"""
Caitra         e  29
Vaisakha       f  30
Jyaistha       g  29
Asadha         h  30
Sravana        i  29
Bhadrapada     j  30
Asvina         k  29
Karttika       l  30
Margasirsa     a  29
Pausa          b  30
Magha          c  29
Phalguna       d  30
"""



**********useage *********

$ python script.py year month

example output on year 2017, november
$ python lunar-calendar.py 2017 11
                2017 ^ 2561
                    11
Mon   Tue   Wen   Thu   Fri   Sat   Sun 
            1     2     3     4     5   
            l:13  l:14  l:15  l:16  l:17
6     7     8     9     10    11    12  
l:18  l:19  l:20  l:21  l:22  l:23  l:24
13    14    15    16    17    18    19  
l:25  l:26  l:27  l:28  l:29  l:30  a:1 
20    21    22    23    24    25    26  
a:2   a:3   a:4   a:5   a:6   a:7   a:8 
27    28    29    30  
a:9   a:10  a:11  a:12


No comments:

Post a Comment