Home Articles FAQs XREF Games Software Instant Books BBS About FOLDOC RFCs Feedback Sitemap
irt.Org

Related items

JavaScript Y2K Issues

And now...The Weekly Update Script

The 24 Hour World

Today's The Day

Extending "Born of the 4th of July"

Easter

The 3rd Saturday in November

Born on the 4th of July

What sign are you?

Monday's child is full of grace

The Chinese New Year

You are here: irt.org | Articles | JavaScript | Date and Time | The Chinese New Year [ previous next ]

Published on: Saturday 1st November 1997 By: Martin Webb

Introduction

This article describes how to show the year of the chinese calendar that a date falls in, including the dates and days for the year.

More Arrays of Data

The following additional arrays are utilised in this article, using the makeArray() function described in Blind Date:

var chinese        = new makeArray('Rat','Ox','Tiger','Hare',
                                   'Dragon','Snake','Horse','Sheep',
                                   'Monkey','Fowl','Dog','Pig');
var branches       = new makeArray('Zi','Chou','Yin','Mao',
                                   'Chen','Si','Wu','Wei',
                                   'Shen','You','Xu','Hai');
var stems          = new makeArray('Jia','Yi','bing','Ding','Wu',
                                   'Ji','Geng','Xin','Ren','Gui');

The Chinese year names have a sixty-year cycle, and are created by pairing a Celestrial Stem with a Terrestrial Branch. The Celestial Stems are specified by Chinese characters that have no English translation; the Terrestrial Branches are named after twelve animals.

chinese[ ]branches[ ]stems[ ]
Rat Zi Jia
Ox ChouYi
Tiger Yin Bing
Hare Mao Ding
DragonChenWu
Snake Si Ji
Horse Wu Geng
Sheep Wei Xin
MonkeyShenRen
Fowl You Gui
Dog Xu
Pig Hai

The initial year (jia-zi) of the current cycle began on 1984 February 2. The full list of the sexagenary year names is as follows:

#Year Names#Year Names#Year Names#Year Names
1. Jia-Zi 16.Ji-Mao 31.Jia-Wu 46.Ji-You
2. Yi-Chou 17.Geng-Chen32.Yi-Wei 47.Geng-Xu
3. Bing-Yin 18.Xin-Si 33.Bing-Shen48.Xin-Hai
4. Ding-Mao 19.Ren-Wu 34.Ding-You 49.Ren-Zi
5. Wu-Chen 20.Gui-Wei 35.Wu-Xu 50.Gui-Chou
6. Ji-Si 21.Jia-Shen 36.Ji-Hai 51.Jia-Yin
7. Geng-Wu 22.Yi-You 37.Geng-Zi 52.Yi-Mao
8. Xin-Wei 23.Bing-Xu 38.Xin-Chou 53.Bing-Chen
9. Ren-Shen 24.Ding-Hai 39.Ren-Yin 54.Ding-Si
10.Gui-You 25.Wu-Zi 40.Gui-Mao 55.Wu-Wu
11.Jia-Xu 26.Ji-Chou 41.Jia-Chen 56.Ji-Wei
12.Yi-Hai 27.Geng-Yin 42.Yi-Si 57.Geng-Shen
13.Bing-Zi 28.Xin-Mao 43.Bing-Wu 58.Xin-You
14.Ding-chou29.Ren-Chen 44.Ding-Wei 59.Ren-Xu
15.Wu-Yin 30.gui-Si 45.Wu-Shen 60.Gui-Hai

The Chinese celebrate New Year's Day sometime between January 10th and February 19th of the Gregorian calendar.

The following chinesenewyear[] array holds the dates of the Chinese New Year from 1900 to 1999, in the format M.DD, where M is the number of the month, and DD is the date within the month M:

var chinesenewyear = new makeArray(1.31,2.19,2.08,1.29,2.16,2.04,1.25,2.13,2.02,1.22,
                                   2.10,1.30,2.18,2.06,1.26,2.14,2.03,1.23,2.11,2.01,
                                   2.20,2.08,1.28,2.16,2.05,1.25,2.13,2.02,1.23,2.10,
                                   1.30,2.17,2.06,1.26,2.14,2.04,1.24,2.11,1.31,2.19,
                                   2.08,1.27,2.15,2.05,1.25,2.13,2.02,1.22,2.10,1.29,
                                   2.17,2.06,1.27,2.14,2.03,1.24,2.12,1.31,2.18,2.08,
                                   1.28,2.15,2.05,1.25,2.13,2.02,1.21,2.09,1.30,2.17,
                                   2.06,1.27,2.15,2.03,1.23,2.11,1.31,2.18,2.07,1.28,
                                   2.16,2.05,1.25,2.13,2.02,2.20,2.09,1.29,2.17,2.06,
                                   1.27,2.15,2.04,1.23,2.10,1.31,2.19,2.07,1.28,2.16);

So for example in 1900 the Chinese New Year fell on 1.31, i.e. the 31st of January. For years outside this range, only a rough estimate of the animal associated with each year is calculated.

The Year of the Dragon

Not unlike a leap year, where you simple divide the year with 4, 100, or 400 to test whether or not a year is a leap year, to calculate the Chinese branch, you must first subtract 3 from the year before dividing by 12 to find out which animal is associated with the year:

number = (year - 3)%12;

So for example, for 1997:

1997 - 3 = 1994 1994 % 12 = 2 chinese[2] = Ox, branches[2] = Chou

To retrieve the Chinese stem, it is necessary to subtract 3 from the year and then divide by 10:

number = (year - 3)%10;

So for 1997:

1997 - 3 = 1994 1994 % 10 = 4 stems[4] = Ding

Therefore 1997 was the Chinese year Chou-Ding, or the year of the Ox.

However, life is not that simple. As mentioned, the start of the Chinese New Year varies from January 10th to February 19th. People always think that because I was born in 1965 then that means I was born in the year of the Snake. But because I was born on the 4th January, I was actually born in the year of the Dragon.

By testing the start of the Chinese New Year, we can account for this. Rather than calculate the beginning of the Chinese New Year, which may even be beyond the capability of JavaScript (although I am currently working on this), we'll use the chinesenewyear[] array described above.

To retrieve the details for any particular year from 1900 to 1999 we use the following:

var number = chinesenewyear[year - 1899];

To retrieve the month and day from a floating point number, e.g. 9.99, we use the following:

var month = Math.floor(number);
var day   = Math.round((number*100)-(month*100));

Then all we need to do is compare the date entered with the start of the Chinese New Year, if its the same or greater then it is a simple matter of retrieving the chinese branch for the year, and if its less than then it requires retrieving the chinese branch for the previous year:

if ((month > newMonth) || ((month == newMonth) && (day >= newDay))) {
    var chineseBranch = (year-3)%12;
    var chineseStem = (year-3)%10;
}
else {
    var chineseBranch = (year-4)%12;
    var chineseStem = (year-4)%10;
}

The following Chinese() function does all of this and more. It returns the animal name for the day, month and year passed, and also calculates the values of chineseyearrange the Chinese year range for the date, and chineseyearname the full name of the Chinese year.

The chineseyearrange can only be correctly returned for the years 1901 to 1998, as we must have the values for the years before 1901 and after 1998 to correctly calculate the start and end of the relevant years.

It also makes use of the FullDate() function described in the previous article Monday's child is full of grace

function Chinese(day,month,year) {
    if ((year > 1900) && (year < 1999)) {
        var newYear = chinesenewyear[year - 1899];
        var newMonth = Math.floor(newYear);
        var newDay = Math.round((newYear*100)-(newMonth*100));

        if ((month > newMonth) || ((month == newMonth) && (day >= newDay))) {
            // this year
            var chineseBranch = (year-3)%12;
            var chineseStem = (year-3)%10;

            var nextYear = chinesenewyear[year - 1899 + 1];
            var nextMonth = Math.floor(nextYear);
            var nextDay = Math.round((nextYear*100)-(nextMonth*100));

            var lastDay = nextDay - 1;
            if (lastDay == 0) {
                lastMonth = nextMonth - 1;
                lastDay = 31;
            }
            else lastMonth = nextMonth;
            
            chineseyearrange = FullDate(newDay,newMonth,year) + ' - ' +
                               FullDate(lastDay,lastMonth,year+1);
        }
        else {
            // last year
            var chineseBranch = (year-4)%12;
            var chineseStem = (year-4)%10;

            var oldYear = chinesenewyear[year - 1899 - 1];
            var oldMonth = Math.floor(oldYear);
            var oldDay = Math.round((oldYear*100)-(oldMonth*100));

            var lastDay = newDay - 1;
            if (lastDay == 0) {
                lastMonth = newMonth - 1;
                lastDay = 31;
            }
            else lastMonth = newMonth;
            
            chineseyearrange = FullDate(oldDay,oldMonth,year-1) + ' ' +
                               FullDate(lastDay,lastMonth,year);
        }
    }
    else {
        var chineseBranch = (year-3)%12;
        var chineseStem = (year-3)%10;
    }

    if (chineseBranch == 0)
        chineseBranch = 12;

    if (chineseStem == 0)
        chineseStem = 10;

    chineseyearname = '(' + stems[chineseStem] + '-' + branches[chineseBranch] + ')';

    return chinese[chineseBranch];
}

To retrieve the data the following JavaScript defines two global variables chineseyearrnage and chineseyearname which are populated by the Chinese() function:

var chineseyearrange = '';
var chineseyearname = '';
var chineseyear = Chinese(day,month,year);

document.write('Chinese year of the ' + chineseyear + ' ' + chineseyearname + '
' + chineseyearrange);

Working Example

Why not try it out the frame version yourself.

Source Code

You can view the source code of the four components:

Related items

JavaScript Y2K Issues

And now...The Weekly Update Script

The 24 Hour World

Today's The Day

Extending "Born of the 4th of July"

Easter

The 3rd Saturday in November

Born on the 4th of July

What sign are you?

Monday's child is full of grace

©2018 Martin Webb