source: Dev/branches/rest-dojo-ui/client/dojox/date/hebrew/Date.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 22.3 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/declare",
4        "./numerals"
5], function(dojo, declare, numerals){
6
7dojo.getObject("date.hebrew.Date", true, dojox);
8dojo.experimental("dojox.date.hebrew.Date");
9
10dojo.declare("dojox.date.hebrew.Date", null, {
11        // summary: A Date-like object which implements the Hebrew calendar
12        //
13        // description:
14        //      A Date-like object which implements the Hebrew Calendar.  Because this object
15        //      implements many of the same methods as the native JavaScript Date object, which
16        //      implements the Gregorian calendar, it can often be used its place.  Note that
17        //      this object does not extend Date or use its prototype.
18        //
19        // example:
20        // |    dojo.require("dojox.date.hebrew.Date");
21        // |
22        // |    var date = new dojox.date.hebrew.Date();
23        // |    console.log(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
24
25        // Hebrew date calculations are performed in terms of days, hours, and
26        // "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
27        //_HOUR_PARTS: 1080,
28        //_DAY_PARTS: 24*1080,
29   
30        // An approximate value for the length of a lunar month.
31        // It is used to calculate the approximate year and month of a given
32        // absolute date.
33        //_MONTH_FRACT: 12*1080 + 793,
34        //_MONTH_PARTS: 29*24*1080 + 12*1080 + 793,
35           
36        // The time of the new moon (in parts) on 1 Tishri, year 1 (the epoch)
37        // counting from noon on the day before.  BAHARAD is an abbreviation of
38        // Bet (Monday), Hey (5 hours from sunset), Resh-Daled (204).
39        //_BAHARAD: 11*1080 + 204,
40
41        // The Julian day of the Gregorian epoch, that is, January 1, 1 on the
42        // Gregorian calendar.
43        //_JAN_1_1_JULIAN_DAY: 1721426,
44
45        /**
46        * The lengths of the Hebrew months.  This is complicated, because there
47        * are three different types of years, or six if you count leap years.
48        * Due to the rules for postponing the start of the year to avoid having
49        * certain holidays fall on the sabbath, the year can end up being three
50        * different lengths, called "deficient", "normal", and "complete".
51        */
52       
53        //"Absolute" indexes of  months:  Tishri -  0, Heshvan - 1, Kislev - 2, Tevet - 3, Shevat -  4, Adar I (leap years only) - 5, Adar - 6, Nisan - 7, Iyar - 8, Sivan - 9,   Tammuz-10, Av - 11, Elul - 12.
54
55        _MONTH_LENGTH:  [
56                // Deficient  Normal     Complete
57                [   30,     30,     30  ],               //Tishri    0
58                [   29,     29,     30  ],               //Heshvan   1
59                [   29,     30,     30  ],               //Kislev   2
60                [   29,     29,     29  ],               //Tevet  3
61                [   30,     30,     30  ],               //Shevat  4
62                [   30,     30,     30  ],               //Adar I (leap years only)  5
63                [   29,     29,     29  ],               //Adar  6
64                [   30,     30,     30  ],               //Nisan  7
65                [   29,     29,     29  ],               //Iyar  8
66                [   30,     30,     30  ],               //Sivan  9
67                [   29,     29,     29  ],               //Tammuz  10
68                [   30,     30,     30  ],               //Av  11
69                [   29,     29,     29  ]                //Elul  12
70        ],
71
72        /**
73        * The cumulative # of days to the end of each month in a non-leap year
74        * Although this can be calculated from the MONTH_LENGTH table,
75        * keeping it around separately makes some calculations a lot faster
76        */
77        _MONTH_START:  [
78                // Deficient  Normal    Complete
79                [    0,         0,              0  ],           // (placeholder)
80                [   30,     30,     30  ],              // Tishri
81                [   59,     59,     60  ],              // Heshvan
82                [   88,     89,     90  ],              // Kislev
83                [  117,    118,    119  ],              // Tevet
84                [  147,    148,    149  ],              // Shevat
85                [  147,    148,    149  ],              // (Adar I placeholder)
86                [  176,    177,    178  ],              // Adar
87                [  206,    207,    208  ],              // Nisan
88                [  235,    236,    237  ],              // Iyar
89                [  265,    266,    267  ],              // Sivan
90                [  294,    295,    296  ],              // Tammuz
91                [  324,    325,    326  ],              // Av
92                [  353,    354,    355  ]               // Elul
93        ],
94
95        /**
96        * The cumulative # of days to the end of each month in a leap year
97        */
98        _LEAP_MONTH_START:  [
99                // Deficient  Normal    Complete
100                [    0,         0,              0  ],           // (placeholder)
101                [   30,     30,     30  ],              // Tishri
102                [   59,     59,     60  ],              // Heshvan
103                [   88,     89,     90  ],              // Kislev
104                [  117,    118,    119  ],              // Tevet
105                [  147,    148,    149  ],              // Shevat
106                [  177,    178,    179  ],              // Adar I
107                [  206,    207,    208  ],              // Adar II
108                [  236,    237,    238  ],              // Nisan
109                [  265,    266,    267  ],              // Iyar
110                [  295,    296,    297  ],              // Sivan
111                [  324,    325,    326  ],              // Tammuz
112                [  354,    355,    356  ],              // Av
113                [  383,    384,    385  ]               // Elul
114        ],
115       
116        _GREGORIAN_MONTH_COUNT:  [
117                //len len2   st  st2
118                [  31,  31,   0,   0 ], // Jan
119                [  28,  29,  31,  31 ], // Feb
120                [  31,  31,  59,  60 ], // Mar
121                [  30,  30,  90,  91 ], // Apr
122                [  31,  31, 120, 121 ], // May
123                [  30,  30, 151, 152 ], // Jun
124                [  31,  31, 181, 182 ], // Jul
125                [  31,  31, 212, 213 ], // Aug
126                [  30,  30, 243, 244 ], // Sep
127                [  31,  31, 273, 274 ], // Oct
128                [  30,  30, 304, 305 ], // Nov
129                [  31,  31, 334, 335 ] // Dec
130                // len  length of month
131                // len2 length of month in a leap year
132                // st   days in year before start of month
133                // st2  days in year before month in leap year
134        ],
135
136    _date: 0,
137        _month: 0,
138        _year: 0,
139        _hours: 0,
140        _minutes: 0,
141        _seconds: 0,
142        _milliseconds: 0,
143        _day: 0,
144
145        constructor: function(){
146                // summary: initialize the date object value
147                //
148                // example:
149                // |            var date1 = new dojox.date.hebrew.Date();
150                // |
151                // |            var date2 = new dojox.date.hebrew.Date(date1);
152                // |
153                // |            var date3 = new dojox.date.hebrew.Date(5768,2,12);
154
155                var len = arguments.length;
156                if(!len){// use the current date value, added "" to the similarity to date
157                        this.fromGregorian(new Date());
158                }else if(len == 1){
159                        var arg0 = arguments[0];
160                        if(typeof arg0 == "number"){ // this is time "valueof"
161                                arg0 = new Date(arg0);
162                        }
163
164                        if(arg0 instanceof Date){
165                                this.fromGregorian(arg0);
166                        }else if(arg0 == ""){
167                                // date should be invalid.  Dijit relies on this behavior.
168                                this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
169                        }else{  // this is hebrew.Date object
170                                this._year = arg0._year;
171                                this._month =  arg0._month;
172                                this._date = arg0._date;
173                                this._hours = arg0._hours;
174                                this._minutes = arg0._minutes;
175                                this._seconds = arg0._seconds;
176                                this._milliseconds = arg0._milliseconds;
177                        }
178                }else if(len >= 3){
179                        // YYYY, MM, DD arguments passed, month is from 0-12,  "absolute" index of month
180                        this._year += arguments[0];
181                        this._month += arguments[1];
182                        this._date += arguments[2];
183                       
184                        if(this._month > 12){
185                                console.warn("the month is incorrect , set 0  " + this._month + "   " + this._year );
186                                this._month = 0;
187                        }
188                        this._hours += arguments[3] || 0;
189                        this._minutes += arguments[4] || 0;
190                        this._seconds += arguments[5] || 0;
191                        this._milliseconds += arguments[6] || 0;
192                }
193 
194                this._setDay();
195        },
196       
197        getDate: function(){
198                // summary: returns the date value (1 - 30)
199                //
200                // example:
201                // |            var date1 = new dojox.date.hebrew.Date();
202                // |
203                // |            console.log(date1.getDate());
204
205                return this._date; // int
206        },
207
208        getDateLocalized: function(/*String?*/locale){
209                // summary: returns the date value as hebrew numerals for the Hebrew locale,
210                //              a number for all others.
211                //
212                // example:
213                // |            var date1 = new dojox.date.hebrew.Date();
214                // |
215                // |            console.log(date1.getDate());
216
217                return (locale || dojo.locale).match(/^he(?:-.+)?$/) ?
218                        numerals.getDayHebrewLetters(this._date) : this.getDate();
219        },
220
221        getMonth: function(){
222                // summary: returns the month value (0 - 12)
223                //
224                // description: the result is the index in the month array:
225                //      0. Tishri
226                //      1. Heshvan
227                //      2. Kislev
228                //      3. Tevet
229                //      4. Shevat
230                //      5. Adar I (leap years only)
231                //      6. Adar
232                //      7. Nisan
233                //      8. Iyar
234                //      9. Sivan
235                //      10. Tammuz
236                //      11.     Av
237                //      12. Elul - 12
238                // For non leap years, for months after Shevat, the actual position of
239                // the month in the year (used for short format) is less than
240                // the "absolute" index by 1.
241                //
242                // example:
243                // |            var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
244                // |
245                // |            console.log(date1.getMonth()+1);
246                // |            >> 7
247
248                return this._month;
249        },
250
251        getFullYear: function(){
252                // summary: returns the Year value
253                //
254                // example:
255                // |            var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
256                // |
257                // |            console.log(date1.getFullYear());
258                // |            >> 5769
259                return this._year;
260        },
261                       
262        getHours: function(){
263                //summary: returns the hour value
264                return this._hours;
265        },
266               
267        getMinutes: function(){
268                //summary: returns the minutes value
269
270                return this._minutes;
271        },
272
273        getSeconds: function(){
274                //summary: returns the seconds value
275                return this._seconds;
276        },
277
278        getMilliseconds: function(){
279                //summary: returns the milliseconds value
280
281                return this._milliseconds;
282        },
283
284        setDate: function(/*number*/date){
285                // summary: sets the date number for a given month
286                // example:
287                // |            var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
288                // |            date1.setDate(2);
289
290                date = +date;
291                var mdays;
292                if(date>0){
293                        while (date > (mdays = this.getDaysInHebrewMonth(this._month, this._year))){
294                                date -= mdays;
295                                this._month++;
296                                if(this._month >= 13){this._year++; this._month -= 13;}
297                        }
298                }else{
299                        while(date<=0){
300                                mdays = this.getDaysInHebrewMonth((this._month-1)>=0 ? (this._month-1) : 12, ((this._month-1)>=0)? this._year : this._year-1);
301                                this._month--;
302                                if(this._month < 0){this._year--; this._month += 13;}
303                                date += mdays;
304                        }
305                }
306                this._date = date;
307                this._setDay();
308                return this;
309        },
310       
311
312        setFullYear: function(/*number*/year, /*number?*/month, /*number?*/ date){
313                // summary: set the year
314                //
315                // example:
316                // |            var date1 = new dojox.date.hebrew.Date();
317                // |            date1.setFullYear(5768);
318                // |            date1.setFullYear(5768, 1, 1);
319               
320                this._year = year = +year;
321                if(!this.isLeapYear(year) && this._month==5){  //incorrect month number for non leap year
322                        this._month++;
323                }
324               
325                if(month !== undefined){this.setMonth(month);}
326                if(date !== undefined){this.setDate(date);}
327               
328                var dnum = this.getDaysInHebrewMonth(this._month, this._year);
329                if(dnum < this._date){
330                        this._date = dnum;
331                } // if the date in this month more than number of the days in this month
332               
333                this._setDay();
334                return this;
335        },
336
337        setMonth: function(/*number*/month){
338                // summary: sets the month.  You should use "absolute" index in the month array:
339                //      0. Tishri
340                //      1. Heshvan
341                //      2. Kislev
342                //      3. Tevet
343                //      4. Shevat
344                //      5. Adar I (leap years only)
345                //      6. Adar
346                //      7. Nisan
347                //      8. Iyar
348                //      9. Sivan
349                //      10. Tammuz
350                //      11.     Av
351                //      12. Elul - 12
352                //  For non leap years, for months after Shevat, the actual position of
353                //      the month in the year (used for short format) is less than
354                //      the "absolute" index by 1.
355                //
356                // example:
357                // |            var date1 = new dojox.date.hebrew.Date();
358                // |            date1.setMonth(0); //first month
359
360                month = +month; // coerce to a Number
361                if(!this.isLeapYear(this._year) && month == 5){month++;}
362       
363                if(month>=0){
364                        while(month >12){
365                                this._year++;
366                                month -= 13;
367                                if (!this.isLeapYear(this._year) && month >= 5){month++;}
368                        }
369                }else{
370                        while(month<0){
371                                this._year--;
372                                month += (!this.isLeapYear(this._year)  &&  month < -7) ? 12 : 13;
373                        }
374                }
375               
376                this._month = month;
377
378                var dnum = this.getDaysInHebrewMonth(this._month, this._year);
379                if(dnum < this._date){
380                        this._date = dnum;
381                } // if the date in this month more than number of the days in this month
382               
383                this._setDay();
384                return this;
385        },
386
387        setHours: function(){
388                //      summary: sets the hour
389                //
390                //      description: Sets the hour and optionally minutes, seconds, milliseconds also.
391                //
392                // example:
393                // |            var date1 = new dojox.date.hebrew.Date();
394                // |            date1.setHours(12, 30, 0, 0);
395
396                var hours_arg_no = arguments.length;
397                var hours = 0;
398                if(hours_arg_no >= 1){
399                        hours += +arguments[0];
400                }
401
402                if(hours_arg_no >= 2){
403                        this._minutes += +arguments[1];
404                }
405
406                if(hours_arg_no >= 3){
407                        this._seconds += +arguments[2];
408                }
409
410                if(hours_arg_no == 4){
411                        this._milliseconds += +arguments[3];
412                }
413
414                while(hours >= 24){
415                        this._date++;
416                        var mdays = this.getDaysInHebrewMonth(this._month, this._year);
417                        if(this._date > mdays)
418                        {
419                                this._month++;
420                                if(!this.isLeapYear(this._year) && this._month==5){ this._month++; }
421                                if(this._month >= 13){this._year++; this._month -= 13;}
422                                this._date -= mdays;
423                        }
424                        hours -= 24;
425                }
426                this._hours = hours;
427                this._setDay();
428                return this;
429        },
430
431        _addMinutes: function(/*Number*/minutes){
432                minutes += this._minutes;
433                this.setMinutes(minutes);
434                this.setHours(this._hours + parseInt(minutes / 60));
435                return this;
436        },
437
438        _addSeconds: function(/*Number*/seconds){
439                seconds += this._seconds;
440                this.setSeconds(seconds);
441                this._addMinutes(parseInt(seconds / 60));
442                return this;
443        },
444
445        _addMilliseconds: function(/*Number*/milliseconds){
446                milliseconds += this._milliseconds;
447                this.setMilliseconds(milliseconds);
448                this._addSeconds(parseInt(milliseconds / 1000));
449                return this;
450        },
451
452        setMinutes: function(/*Number*/minutes){
453                //summary: sets the minutes (0-59) only.
454                this._minutes = minutes % 60;
455                return this;
456        },
457
458        setSeconds: function(/*Number*/seconds){
459                //summary: sets the seconds (0-59) only.
460                this._seconds = seconds % 60;
461                return this;
462        },
463
464        setMilliseconds: function(/*Number*/milliseconds){
465                this._milliseconds = milliseconds % 1000;
466                return this;
467        },
468
469        _setDay: function(){
470                var day = this._startOfYear(this._year);
471                if(this._month != 0){
472                        day += (this.isLeapYear(this._year) ? this._LEAP_MONTH_START : this._MONTH_START)[this._month || 0][this._yearType(this._year)];
473                }
474                day += this._date - 1;
475                this._day = (day+1) % 7;
476        },
477
478        toString: function(){
479                // summary: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format
480                //
481                // description: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format (all numeric)
482                //      For user presentation, use dojox.date.hebrew.locale.format which will present in the appropriate language
483                //  and format.  toString() language- and culturally-specific conventions to keep this module free of
484                //      dependencies on dojox.date.locale and dojo.cldr.
485                //
486                // example:
487                // |            var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
488                // |            console.log(date1.toString());
489                // |            >>> "1, 6, 5769 0:0:0"
490                return this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
491        },
492
493        // ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
494        getDaysInHebrewMonth: function(/*Number*/month, /*Number*/ year){
495                // summary: returns the number of days in the given month and year
496
497                // Aside from the leap month, these two months can vary: 1=HESHVAN, 2=KISLEV
498                // The rest are a fixed length
499                var yearType = (month == 1 || month == 2) ? this._yearType(year) : 0;
500                return (!this.isLeapYear(this._year) && month == 5) ? 0 : this._MONTH_LENGTH[month][yearType];
501        },
502
503        // ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
504        _yearType: function(/*Number*/year){
505                var yearLength = this._handleGetYearLength(Number(year));
506                if(yearLength > 380){
507                        yearLength -= 30;        // Subtract length of leap month.
508                }
509
510                var yearType = yearLength - 353;
511                if (yearType < 0 || yearType > 2){
512                        throw new Error("Illegal year length " + yearLength + " in year " + year);
513                }
514                return yearType;
515        },
516
517        // ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
518        _handleGetYearLength: function(/*number*/eyear){
519                return this._startOfYear(eyear+1) - this._startOfYear(eyear);
520        },
521
522        // ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
523        _startOfYear: function(/*number*/year){
524                var months = Math.floor((235 * year - 234) / 19),       // # of months before year
525                        frac = months * (12*1080 + 793) + 11*1080 + 204/*BAHARAD*/,     // Fractional part of day #
526                        day  = months * 29 + Math.floor(frac / (24*1080));      // Whole # part of calculation
527                frac %= 24*1080;        // Time of day
528
529                var wd = day % 7;       // Day of week (0 == Monday)
530
531                if(wd == 2 || wd == 4 || wd == 6){
532                        // If the 1st is on Sun, Wed, or Fri, postpone to the next day
533                        day += 1;
534                        wd = day % 7;
535                }
536                if(wd == 1 && frac > 15 * 1080 + 204 && !this.isLeapYear(year)){
537                        // If the new moon falls after 3:11:20am (15h204p from the previous noon)
538                        // on a Tuesday and it is not a leap year, postpone by 2 days.
539                        // This prevents 356-day years.
540                        day += 2;
541                }else if(wd == 0 && frac > 21 * 1080 + 589 && this.isLeapYear(year-1)){
542                        // If the new moon falls after 9:32:43 1/3am (21h589p from yesterday noon)
543                        // on a Monday and *last* year was a leap year, postpone by 1 day.
544                        // Prevents 382-day years.
545                        day += 1;
546                }
547
548                return day;
549        },
550
551        // ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
552        isLeapYear: function(/*Number*/year){
553        //      summary:
554        //              Determines if the year (argument) is a leap year
555        //      description: The Leap year contains additional month adar sheni
556        //
557                //return (year * 12 + 17) % 19 >= 12;
558                var x = (year*12 + 17) % 19;
559                return x >= ((x < 0) ? -7 : 12);
560        },
561
562       
563        fromGregorian: function(/*Date*/gdate){
564                // summary: This function sets this Date to the Hebrew Date corresponding to the Gregorian Date
565                // example:
566                // |            var dateHebrew = new dojox.date.hebrew.Date();
567                // |            var dateGregorian = new Date(2008,10,12);
568                // |            dateHebrew.fromGregorian(dateGregorian);
569
570                var result = (!isNaN(gdate)) ? this._computeHebrewFields(gdate) : NaN;
571                this._year = (!isNaN(gdate)) ? result[0] : NaN;
572                this._month = (!isNaN(gdate))? result[1] : NaN;
573                this._date = (!isNaN(gdate)) ? result[2] : NaN;
574                this._hours = gdate.getHours();
575                this._milliseconds = gdate.getMilliseconds();
576                this._minutes = gdate.getMinutes();
577                this._seconds = gdate.getSeconds();
578                if (!isNaN(gdate)) this._setDay();
579                return this;
580        },
581
582        // ported from the Java class com.ibm.icu.util.HebrewCalendar.handleComputeFields from ICU4J v3.6.1 at http://www.icu-project.org/
583        _computeHebrewFields: function(/*Date*/gdate){
584                var julianDay = this._getJulianDayFromGregorianDate(gdate),
585                        d = julianDay - 347997,
586                        m = Math.floor((d * 24*1080) / (29*24*1080 + 12*1080 + 793)),       // Months (approx)
587                        year = Math.floor((19 * m + 234) / 235) + 1,  // Years (approx)
588                        ys  = this._startOfYear(year),                 // 1st day of year
589                        dayOfYear = (d - ys);
590                // Because of the postponement rules, it's possible to guess wrong.  Fix it.
591                while(dayOfYear < 1){
592                        year--;
593                        ys  = this._startOfYear(year);
594                        dayOfYear = d - ys;
595                }
596
597                // Now figure out which month we're in, and the date within that month
598
599                var typeofYear = this._yearType(year),
600                        monthStart = this.isLeapYear(year) ? this._LEAP_MONTH_START : this._MONTH_START,
601                        month = 0;
602
603                while(dayOfYear > monthStart[month][typeofYear]){
604                        month++;
605                }
606                month--;
607                var dayOfMonth = dayOfYear - monthStart[month][typeofYear];
608                return [year, month, dayOfMonth];
609        },
610
611        // ported from the Java class com.ibm.icu.util.Calendar.computeGregorianFields from ICU4J v3.6.1 at http://www.icu-project.org/
612        toGregorian: function(){
613                // summary: returns the equivalent Grogorian date value as a native Date object
614                // example:
615                // |            var dateHebrew = new dojox.date.hebrew.Date(5768,11,20);
616                // |            var dateGregorian = dateHebrew.toGregorian();
617               
618                var hYear = this._year || 0,
619                        hMonth = this._month || 0,
620                        hDate = this._date || 0,
621                        day = this._startOfYear(hYear);
622
623                if(hMonth != 0){
624                        day += (this.isLeapYear(hYear) ? this._LEAP_MONTH_START : this._MONTH_START)[hMonth][this._yearType(hYear)];
625                }
626
627                var julianDay =  (hDate + day + 347997),
628                // The Gregorian epoch day is zero for Monday January 1, year 1.
629                        gregorianEpochDay = julianDay - 1721426;
630
631                // Here we convert from the day number to the multiple radix
632                // representation.  We use 400-year, 100-year, and 4-year cycles.
633                // For example, the 4-year cycle has 4 years + 1 leap day; giving
634                // 1461 == 365*4 + 1 days.
635                var rem = [];
636                var n400 = this._floorDivide(gregorianEpochDay , 146097, rem), // 400-year cycle length
637                        n100 = this._floorDivide(rem[0] , 36524, rem), // 100-year cycle length
638                        n4 = this._floorDivide(rem[0] , 1461, rem), // 4-year cycle length
639                        n1 = this._floorDivide(rem[0] , 365, rem),
640                        year = 400*n400 + 100*n100 + 4*n4 + n1,
641                        dayOfYear = rem[0]; // zero-based day of year
642
643                if(n100 == 4 || n1 == 4){
644                        dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
645                }else{
646                        ++year;
647                }
648
649                var isLeap = !(year%4) && // equiv. to (year%4 == 0)
650                                (year%100 || !(year%400)),
651                        correction = 0,
652                        march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
653                if(dayOfYear >= march1){ correction = isLeap ? 1 : 2; }
654                var month = Math.floor((12 * (dayOfYear + correction) + 6) / 367); // zero-based month
655                var dayOfMonth = dayOfYear -
656                                this._GREGORIAN_MONTH_COUNT[month][isLeap ? 3 : 2] + 1; // one-based DOM
657
658                return new Date(year, month, dayOfMonth, this._hours, this._minutes, this._seconds, this._milliseconds); // Date
659        },
660        _floorDivide: function(numerator, denominator, remainder){
661                if(numerator >= 0){
662                        remainder[0] = (numerator % denominator);
663                        return Math.floor(numerator / denominator);
664                }
665                var quotient = Math.floor(numerator / denominator);
666                remainder[0] = numerator - (quotient * denominator);
667                return quotient;
668        },
669
670        getDay: function(){
671                // summary: returns weekday value (0 - 6)
672                //
673                // example:
674                // |            var date1 = new dojox.date.hebrew.Date();
675                // |
676                // |            console.log(date1.getDay());
677
678                var hYear = this._year,
679                        hMonth = this._month,
680                        hDate = this._date,
681                        day = this._startOfYear(hYear);
682
683                if(hMonth != 0){
684                        day += (this.isLeapYear(hYear) ? this._LEAP_MONTH_START : this._MONTH_START)[hMonth][this._yearType(hYear)];
685                }
686
687                day += hDate - 1;
688                return (day+1) % 7;
689        },
690
691        // ported from the Java class com.ibm.icu.util.Calendar.computeGregorianMonthStart from ICU4J v3.6.1 at http://www.icu-project.org/
692        _getJulianDayFromGregorianDate: function(gdate){
693                //summary: returns the Julian day of a Gregorian date
694
695                var year = gdate.getFullYear(),
696                        month = gdate.getMonth(),
697                        d = gdate.getDate(),
698                        isLeap = !(year%4) && (year%100 || !(year%400)), //TODO: dup
699                        y = year - 1;
700                // This computation is actually ... + (_JAN_1_1_JULIAN_DAY - 3) + 2.
701                // Add 2 because Gregorian calendar starts 2 days after Julian
702                // calendar.
703                var julianDay = 365*y + Math.floor(y/4) - Math.floor(y/100) +
704                        Math.floor(y/400) + 1721426 - 1;
705                // At this point julianDay indicates the day BEFORE the first day
706                // of January 1, <eyear> of the Gregorian calendar.
707                if(month > 0) {
708                        julianDay += this._GREGORIAN_MONTH_COUNT[month][isLeap ? 3 : 2];
709                }
710               
711                julianDay += d;
712                return julianDay;
713        }
714});
715
716dojox.date.hebrew.Date.prototype.valueOf = function(){
717        return this.toGregorian().valueOf();
718};
719return dojox.date.hebrew.Date;
720});
Note: See TracBrowser for help on using the repository browser.