1010 lines
30 KiB
JavaScript
1010 lines
30 KiB
JavaScript
|
dojo.provide("dojox.date.HebrewDate");
|
||
|
dojo.experimental("dojox.date.HebrewDate");
|
||
|
|
||
|
dojo.declare("dojox.date.HebrewDate", null, {
|
||
|
// summary: The component defines the Hebrew Calendar Object
|
||
|
//
|
||
|
// description:
|
||
|
// This module is similar to the Date() object provided by JavaScript
|
||
|
//
|
||
|
// example:
|
||
|
// | dojo.require("dojox.date.HebrewDate");
|
||
|
// |
|
||
|
// | var date = new dojox.date.HebrewDate();
|
||
|
// | document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
|
||
|
|
||
|
TISHRI: 0,
|
||
|
HESHVAN: 1,
|
||
|
KISLEV: 2,
|
||
|
TEVET: 3,
|
||
|
SHEVAT: 4,
|
||
|
ADAR_1: 5,
|
||
|
ADAR: 6,
|
||
|
NISAN: 7,
|
||
|
IYAR: 8,
|
||
|
SIVAN: 9,
|
||
|
TAMUZ: 10,
|
||
|
AV: 11,
|
||
|
ELUL: 12,
|
||
|
|
||
|
// Hebrew date calculations are performed in terms of days, hours, and
|
||
|
// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
|
||
|
_HOUR_PARTS: 1080,
|
||
|
_DAY_PARTS: 24*1080,
|
||
|
|
||
|
// An approximate value for the length of a lunar month.
|
||
|
// It is used to calculate the approximate year and month of a given
|
||
|
// absolute date.
|
||
|
_MONTH_DAYS: 29,
|
||
|
_MONTH_FRACT: 12*1080 + 793,
|
||
|
_MONTH_PARTS: 29*24*1080 + 12*1080 + 793,
|
||
|
|
||
|
// The time of the new moon (in parts) on 1 Tishri, year 1 (the epoch)
|
||
|
// counting from noon on the day before. BAHARAD is an abbreviation of
|
||
|
// Bet (Monday), Hey (5 hours from sunset), Resh-Daled (204).
|
||
|
BAHARAD: 11*1080 + 204,
|
||
|
|
||
|
// The Julian day of the Gregorian epoch, that is, January 1, 1 on the
|
||
|
// Gregorian calendar.
|
||
|
JAN_1_1_JULIAN_DAY: 1721426,
|
||
|
|
||
|
/**
|
||
|
* The lengths of the Hebrew months. This is complicated, because there
|
||
|
* are three different types of years, or six if you count leap years.
|
||
|
* Due to the rules for postponing the start of the year to avoid having
|
||
|
* certain holidays fall on the sabbath, the year can end up being three
|
||
|
* different lengths, called "deficient", "normal", and "complete".
|
||
|
*/
|
||
|
|
||
|
_MONTH_LENGTH: [
|
||
|
// Deficient Normal Complete
|
||
|
[ 30, 30, 30 ], //Tishri
|
||
|
[ 29, 29, 30 ], //Heshvan
|
||
|
[ 29, 30, 30 ], //Kislev
|
||
|
[ 29, 29, 29 ], //Tevet
|
||
|
[ 30, 30, 30 ], //Shevat
|
||
|
[ 30, 30, 30 ], //Adar I (leap years only)
|
||
|
[ 29, 29, 29 ], //Adar
|
||
|
[ 30, 30, 30 ], //Nisan
|
||
|
[ 29, 29, 29 ], //Iyar
|
||
|
[ 30, 30, 30 ], //Sivan
|
||
|
[ 29, 29, 29 ], //Tammuz
|
||
|
[ 30, 30, 30 ], //Av
|
||
|
[ 29, 29, 29 ] //Elul
|
||
|
],
|
||
|
|
||
|
/**
|
||
|
* The cumulative # of days to the end of each month in a non-leap year
|
||
|
* Although this can be calculated from the MONTH_LENGTH table,
|
||
|
* keeping it around separately makes some calculations a lot faster
|
||
|
*/
|
||
|
_MONTH_START: [
|
||
|
// Deficient Normal Complete
|
||
|
[ 0, 0, 0 ], // (placeholder)
|
||
|
[ 30, 30, 30 ], // Tishri
|
||
|
[ 59, 59, 60 ], // Heshvan
|
||
|
[ 88, 89, 90 ], // Kislev
|
||
|
[ 117, 118, 119 ], // Tevet
|
||
|
[ 147, 148, 149 ], // Shevat
|
||
|
[ 147, 148, 149 ], // (Adar I placeholder)
|
||
|
[ 176, 177, 178 ], // Adar
|
||
|
[ 206, 207, 208 ], // Nisan
|
||
|
[ 235, 236, 237 ], // Iyar
|
||
|
[ 265, 266, 267 ], // Sivan
|
||
|
[ 294, 295, 296 ], // Tammuz
|
||
|
[ 324, 325, 326 ], // Av
|
||
|
[ 353, 354, 355 ] // Elul
|
||
|
],
|
||
|
|
||
|
/**
|
||
|
* The cumulative # of days to the end of each month in a leap year
|
||
|
*/
|
||
|
LEAP_MONTH_START: [
|
||
|
// Deficient Normal Complete
|
||
|
[ 0, 0, 0 ], // (placeholder)
|
||
|
[ 30, 30, 30 ], // Tishri
|
||
|
[ 59, 59, 60 ], // Heshvan
|
||
|
[ 88, 89, 90 ], // Kislev
|
||
|
[ 117, 118, 119 ], // Tevet
|
||
|
[ 147, 148, 149 ], // Shevat
|
||
|
[ 177, 178, 179 ], // Adar I
|
||
|
[ 206, 207, 208 ], // Adar II
|
||
|
[ 236, 237, 238 ], // Nisan
|
||
|
[ 265, 266, 267 ], // Iyar
|
||
|
[ 295, 296, 297 ], // Sivan
|
||
|
[ 324, 325, 326 ], // Tammuz
|
||
|
[ 354, 355, 356 ], // Av
|
||
|
[ 383, 384, 385 ] // Elul
|
||
|
],
|
||
|
|
||
|
GREGORIAN_MONTH_COUNT: [
|
||
|
//len len2 st st2
|
||
|
[ 31, 31, 0, 0 ], // Jan
|
||
|
[ 28, 29, 31, 31 ], // Feb
|
||
|
[ 31, 31, 59, 60 ], // Mar
|
||
|
[ 30, 30, 90, 91 ], // Apr
|
||
|
[ 31, 31, 120, 121 ], // May
|
||
|
[ 30, 30, 151, 152 ], // Jun
|
||
|
[ 31, 31, 181, 182 ], // Jul
|
||
|
[ 31, 31, 212, 213 ], // Aug
|
||
|
[ 30, 30, 243, 244 ], // Sep
|
||
|
[ 31, 31, 273, 274 ], // Oct
|
||
|
[ 30, 30, 304, 305 ], // Nov
|
||
|
[ 31, 31, 334, 335 ] // Dec
|
||
|
// len length of month
|
||
|
// len2 length of month in a leap year
|
||
|
// st days in year before start of month
|
||
|
// st2 days in year before month in leap year
|
||
|
],
|
||
|
|
||
|
_date: 0,
|
||
|
_month: 0,
|
||
|
_year: 0,
|
||
|
_hours: 0,
|
||
|
_minutes: 0,
|
||
|
_seconds: 0,
|
||
|
_milliseconds: 0,
|
||
|
_day: 0,
|
||
|
|
||
|
constructor: function(){
|
||
|
// summary: This is the constructor
|
||
|
// description:
|
||
|
// This fucntion initialize the date object values
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// |
|
||
|
// | var date2 = new dojox.date.HebrewDate(date1);
|
||
|
// |
|
||
|
// | var date3 = new dojox.date.HebrewDate(5768,2,12);
|
||
|
var arg_no = arguments.length;
|
||
|
if(arg_no==0){// use the current date value
|
||
|
var date = new Date();
|
||
|
var result = this._computeHebrewFields(date);
|
||
|
this._date = result[2];
|
||
|
this._month = result[1];
|
||
|
this._year = result[0];
|
||
|
this._hours = date.getHours();
|
||
|
this._minutes = date.getMinutes();
|
||
|
this._seconds = date.getSeconds();
|
||
|
this._milliseconds = date.getMilliseconds();
|
||
|
this._day = date.getDay();
|
||
|
}else if(arg_no ==1){
|
||
|
this._year = arguments[0].getFullYear();
|
||
|
this._month = arguments[0].getMonth();
|
||
|
this._date = arguments[0].getDate();
|
||
|
this._hours = arguments[0].getHours();
|
||
|
this._minutes = arguments[0].getMinutes();
|
||
|
this._seconds = arguments[0].getSeconds();
|
||
|
this._milliseconds = arguments[0].getMilliseconds();
|
||
|
|
||
|
}else if(arg_no >=3){
|
||
|
// YYYY MM DD arguments passed, month is from 0-12
|
||
|
this._year = parseInt(arguments[0]);
|
||
|
this._month = parseInt(arguments[1]);
|
||
|
this._date = parseInt(arguments[2]);
|
||
|
|
||
|
if(!this.isLeapYear(this._year) && this._month>=5)
|
||
|
{this._month++;}
|
||
|
if(this._month >12 || (!this.isLeapYear(this._year) && this._month > 11)){
|
||
|
console.warn("the month is incorrect , set 0");
|
||
|
this._month = 0;
|
||
|
}
|
||
|
this._hours = (arguments[3]!=null )? parseInt(arguments[3]):0;
|
||
|
this._minutes = (arguments[4]!=null )? parseInt(arguments[4]):0;
|
||
|
this._seconds = (arguments[5]!=null )? parseInt(arguments[5]):0;
|
||
|
this._milliseconds = (arguments[6]!=null )? parseInt(arguments[6]):0;
|
||
|
}
|
||
|
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
},
|
||
|
|
||
|
getDate: function(){
|
||
|
// summary: This function returns the date value (1 - 30)
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// |
|
||
|
// | document.writeln(date1.getDate);
|
||
|
return parseInt(this._date);
|
||
|
},
|
||
|
|
||
|
getMonth: function(){
|
||
|
// summary: This function return the month value ( 0 - 11 )
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// |
|
||
|
// | document.writeln(date1.getMonth()+1);
|
||
|
return parseInt(this._month);
|
||
|
},
|
||
|
|
||
|
|
||
|
getFullYear: function(){
|
||
|
// summary: This function return the Year value
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// |
|
||
|
// | document.writeln(date1.getFullYear());
|
||
|
return parseInt(this._year);
|
||
|
},
|
||
|
|
||
|
getHours: function(){
|
||
|
//summary: returns the Hour value
|
||
|
return this._hours;
|
||
|
},
|
||
|
|
||
|
getMinutes: function(){
|
||
|
//summary: returns the Minuites value
|
||
|
|
||
|
return this._minutes;
|
||
|
},
|
||
|
|
||
|
getSeconds: function(){
|
||
|
//summary: returns the seconde value
|
||
|
return this._seconds;
|
||
|
},
|
||
|
|
||
|
getMilliseconds: function(){
|
||
|
//summary: returns the Milliseconds value
|
||
|
|
||
|
return this._milliseconds;
|
||
|
},
|
||
|
|
||
|
setDate: function(/*number*/date){
|
||
|
// summary: This function sets the Date
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// | date1.setDate(2);
|
||
|
date = parseInt(date);
|
||
|
|
||
|
if(date>0){
|
||
|
for(var mdays = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
date > mdays;
|
||
|
date -= mdays,mdays = this.getDaysInHebrewMonth(this._month, this._year)){
|
||
|
this._month ++;
|
||
|
if(!this.isLeapYear(this._year)&&(this._month==5)) { this._month ++;}
|
||
|
if(this._month >= 13){this._year++; this._month -= 13;}
|
||
|
}
|
||
|
|
||
|
this._date = date;
|
||
|
}else{
|
||
|
for(mdays = this.getDaysInHebrewMonth((this._month-1)>=0 ? (this._month-1) : 12 ,((this._month-1)>=0)? this._year : this._year-1);
|
||
|
date<=0;
|
||
|
mdays = this.getDaysInHebrewMonth((this._month-1)>=0 ? (this._month-1) : 12,((this._month-1)>=0)? this._year : this._year-1) ){
|
||
|
this._month --;
|
||
|
if(!this.isLeapYear(this._year) && this._month == 5){ this._month--; }
|
||
|
if(this._month < 0){this._year--; this._month += 13;}
|
||
|
|
||
|
date+=mdays;
|
||
|
}
|
||
|
this._date = date;
|
||
|
}
|
||
|
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setYear: function(/*number*/year){
|
||
|
// summary: This function set Year
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// | date1.setYear(5768);
|
||
|
|
||
|
this._year = parseInt(year);
|
||
|
if(!this.isLeapYear(this._year) && this._month==6){
|
||
|
this._month--;
|
||
|
}
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setMonth: function(/*number*/month){
|
||
|
// summary: This function set Month
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// | date1.setMonth(0); //first month
|
||
|
var newMonth = parseInt(month);
|
||
|
|
||
|
if(!this.isLeapYear(this._year) && newMonth > 5){newMonth ++;}
|
||
|
|
||
|
if(newMonth>=0){
|
||
|
while (newMonth >12){
|
||
|
this._year++;
|
||
|
newMonth -=13;
|
||
|
if (!this.isLeapYear(this._year) && newMonth > 5) {newMonth ++;}
|
||
|
}
|
||
|
}else{
|
||
|
while (newMonth<0){
|
||
|
this._year--;
|
||
|
newMonth +=13;
|
||
|
if (!this.isLeapYear(this._year) && newMonth <= 5) {newMonth --;}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this._month = newMonth;
|
||
|
|
||
|
var dnum = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
if(dnum < this._date){
|
||
|
this._date = dnum;
|
||
|
} // if the date in this month more than number of the days in this month
|
||
|
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setHours: function(){
|
||
|
//summary: set the Hours 0-23
|
||
|
|
||
|
var hours_arg_no = arguments.length;
|
||
|
var hours = 0;
|
||
|
if(hours_arg_no >= 1){
|
||
|
hours = parseInt(arguments[0]);
|
||
|
}
|
||
|
|
||
|
if(hours_arg_no >= 2){
|
||
|
this._minutes = parseInt(arguments[1]);
|
||
|
}
|
||
|
|
||
|
if(hours_arg_no >= 3){
|
||
|
this._seconds = parseInt(arguments[2]);
|
||
|
}
|
||
|
|
||
|
if(hours_arg_no == 4){
|
||
|
this._milliseconds = parseInt(arguments[3]);
|
||
|
}
|
||
|
|
||
|
while(hours >= 24){
|
||
|
this._date++;
|
||
|
var mdays = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
if(this._date > mdays)
|
||
|
{
|
||
|
this._month++;
|
||
|
if(!this.isLeapYear(this._year)&&(this._month==5)){ this._month++; }
|
||
|
if(this._month >= 13){this._year++; this._month -= 13;}
|
||
|
this._date -= mdays;
|
||
|
}
|
||
|
hours -= 24;
|
||
|
}
|
||
|
this._hours = hours;
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setMinutes: function(/*number*/minutes){
|
||
|
//summary: set the Minutes frm 0-59
|
||
|
while(minutes >= 60){
|
||
|
this._hours++;
|
||
|
if(this._hours >= 24){
|
||
|
this._date++;
|
||
|
this._hours -= 24;
|
||
|
var mdays = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
if(this._date > mdays){
|
||
|
this._month ++;
|
||
|
if(!this.isLeapYear(this._year)&&(this._month==5)){ this._month++; }
|
||
|
if(this._month >= 13){this._year++; this._month -= 13;}
|
||
|
this._date -= mdays;
|
||
|
}
|
||
|
}
|
||
|
minutes -= 60;
|
||
|
}
|
||
|
this._minutes = minutes;
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setSeconds: function(/*number*/seconds){
|
||
|
//summary: set the Seconds from 0-59
|
||
|
|
||
|
while(seconds >= 60){
|
||
|
this._minutes++;
|
||
|
if(this._minutes >= 60){
|
||
|
this._hours++;
|
||
|
this._minutes -= 60;
|
||
|
if(this._hours >= 24){
|
||
|
this._date++;
|
||
|
this._hours -= 24;
|
||
|
var mdays = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
if(this._date > mdays){
|
||
|
this._month++;
|
||
|
if(!this.isLeapYear(this._year)&&(this._month==5)){ this._month++; }
|
||
|
if(this._month >= 13){this._year++; this._month -= 13;}
|
||
|
|
||
|
this._date -= mdays;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
seconds -= 60;
|
||
|
}
|
||
|
this._seconds = seconds;
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
setMilliseconds: function(/*number*/milliseconds){
|
||
|
//summary: set the setMilliseconds
|
||
|
while(milliseconds >= 1000){
|
||
|
this.setSeconds++;
|
||
|
if(this.setSeconds >= 60){
|
||
|
this._minutes++;
|
||
|
this._seconds -= 60;
|
||
|
if(this._minutes >= 60){
|
||
|
this._hours++;
|
||
|
this._minutes -= 60;
|
||
|
if(this._hours >= 24){
|
||
|
this._date++;
|
||
|
this._hours -= 24;
|
||
|
var mdays = this.getDaysInHebrewMonth(this._month, this._year);
|
||
|
if(this._date > mdays)
|
||
|
{
|
||
|
this._month ++;
|
||
|
if(!this.isLeapYear(this._year)&&(this._month==5)) this._month ++;
|
||
|
if(this._month >= 13){this._year++; this._month -= 13;}
|
||
|
this._date -= mdays;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
milliseconds -= 1000;
|
||
|
}
|
||
|
this._milliseconds = milliseconds;
|
||
|
var day = this._startOfYear(this._year);
|
||
|
if(this._month != 0){
|
||
|
if(this.isLeapYear(this._year)){
|
||
|
day += this.LEAP_MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}else{
|
||
|
day += this._MONTH_START[this._month][this._yearType(this._year)];
|
||
|
}
|
||
|
}
|
||
|
day += (this._date - 1);
|
||
|
this._day = ((day+1) % 7);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
|
||
|
toString: function(){
|
||
|
// summary: This returns a string representation of the date in "dd, MM, YYYY HH:MM:SS" format
|
||
|
// |
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// | document.writeln(date1.toString());
|
||
|
|
||
|
return this._date + ", " + ((!this.isLeapYear(this._year) && this._month>5) ? this._month : (this._month+1)) + ", " + this._year + " " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
|
||
|
},
|
||
|
|
||
|
valueOf: function(){
|
||
|
return this.toGregorian().valueOf();
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
getDaysInHebrewMonth: function(/*number*/month, /*number*/ year){
|
||
|
// summary: returns the number of days in the month used
|
||
|
switch(month){
|
||
|
case this.HESHVAN:
|
||
|
case this.KISLEV:
|
||
|
// These two month lengths can vary
|
||
|
return this._MONTH_LENGTH[month][this._yearType(year)];
|
||
|
default:
|
||
|
// The rest are a fixed length
|
||
|
return this._MONTH_LENGTH[month][0];
|
||
|
}
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
_yearType: function(/*number*/year){
|
||
|
var yearLength = this._handleGetYearLength(Number(year));
|
||
|
if(yearLength > 380){
|
||
|
yearLength -= 30; // Subtract length of leap month.
|
||
|
}
|
||
|
|
||
|
switch(yearLength){
|
||
|
case 353:
|
||
|
return 0;
|
||
|
case 354:
|
||
|
return 1;
|
||
|
case 355:
|
||
|
return 2;
|
||
|
}
|
||
|
throw new Error("Illegal year length " + yearLength + " in year " + year);
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
_handleGetYearLength: function(/*number*/eyear){
|
||
|
return this._startOfYear(eyear+1) - this._startOfYear(eyear);
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
_startOfYear: function(/*number*/year){
|
||
|
|
||
|
var months = Math.floor((235 * year - 234) / 19); // # of months before year
|
||
|
|
||
|
var frac = months * this._MONTH_FRACT + this.BAHARAD; // Fractional part of day #
|
||
|
var day = months * 29 + Math.floor(frac / this._DAY_PARTS); // Whole # part of calculation
|
||
|
frac %= this._DAY_PARTS; // Time of day
|
||
|
|
||
|
var wd = day % 7; // Day of week (0 == Monday)
|
||
|
|
||
|
if(wd == 2 || wd == 4 || wd == 6){
|
||
|
// If the 1st is on Sun, Wed, or Fri, postpone to the next day
|
||
|
day += 1;
|
||
|
wd = day % 7;
|
||
|
}
|
||
|
if(wd == 1 && frac > 15 * this._HOUR_PARTS + 204 && !this.isLeapYear(year)){
|
||
|
// If the new moon falls after 3:11:20am (15h204p from the previous noon)
|
||
|
// on a Tuesday and it is not a leap year, postpone by 2 days.
|
||
|
// This prevents 356-day years.
|
||
|
day += 2;
|
||
|
}else if(wd == 0 && frac > 21 * this._HOUR_PARTS + 589 && this.isLeapYear(year-1)){
|
||
|
// If the new moon falls after 9:32:43 1/3am (21h589p from yesterday noon)
|
||
|
// on a Monday and *last* year was a leap year, postpone by 1 day.
|
||
|
// Prevents 382-day years.
|
||
|
day += 1;
|
||
|
}
|
||
|
|
||
|
return day;
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
isLeapYear: function(/*number*/year){
|
||
|
// summary:
|
||
|
// Determines if the year (argument) is a leap year
|
||
|
// description: The Leap year contains additional month adar sheni
|
||
|
//
|
||
|
//return (year * 12 + 17) % 19 >= 12;
|
||
|
var x = (year*12 + 17) % 19;
|
||
|
return x >= ((x < 0) ? -7 : 12);
|
||
|
},
|
||
|
|
||
|
|
||
|
fromGregorian: function(/*Date*/gdate){
|
||
|
// summary: This function returns the equivalent Hebrew Date value for the Gregorian Date
|
||
|
// example:
|
||
|
// | var dateHebrew = new dojox.date.HebrewDate();
|
||
|
// | var dateGregorian = new Date(2008,10,12);
|
||
|
// | dateHebrew.fromGregorian(dateGregorian);
|
||
|
var result = this._computeHebrewFields(gdate);
|
||
|
this._year = result[0];
|
||
|
this._month = result[1];
|
||
|
this._date = result[2];
|
||
|
this._hours = gdate.getHours();
|
||
|
this._milliseconds = gdate.getMilliseconds();
|
||
|
this._minutes = gdate.getMinutes();
|
||
|
this._seconds = gdate.getSeconds();
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.HebrewCalendar.handleComputeFields from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
_computeHebrewFields: function(/*Date*/gdate){
|
||
|
var julianDay = this._getJulianDayFromGregorianDate(gdate);
|
||
|
var d = julianDay - 347997;
|
||
|
var m = Math.floor((d * this._DAY_PARTS) / this._MONTH_PARTS); // Months (approx)
|
||
|
var year = Math.floor((19 * m + 234) / 235) + 1; // Years (approx)
|
||
|
var ys = this._startOfYear(year); // 1st day of year
|
||
|
var dayOfYear = (d - ys);
|
||
|
// Because of the postponement rules, it's possible to guess wrong. Fix it.
|
||
|
while(dayOfYear < 1){
|
||
|
year--;
|
||
|
ys = this._startOfYear(year);
|
||
|
dayOfYear = d - ys;
|
||
|
}
|
||
|
|
||
|
// Now figure out which month we're in, and the date within that month
|
||
|
|
||
|
var typeofYear = this._yearType(year);
|
||
|
var monthStart = this.isLeapYear(year) ? this.LEAP_MONTH_START : this._MONTH_START;
|
||
|
var month = 0;
|
||
|
while(dayOfYear > monthStart[month][typeofYear]){
|
||
|
month++;
|
||
|
}
|
||
|
month--;
|
||
|
var dayOfMonth = dayOfYear - monthStart[month][typeofYear];
|
||
|
return [year, month, dayOfMonth];
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.Calendar.computeGregorianFields from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
toGregorian: function(){
|
||
|
// summary: This returns the equevalent Grogorian date value in Date object
|
||
|
// example:
|
||
|
// | var dateHebrew = new dojox.date.HebrewDate(5768,11,20);
|
||
|
// | var dateGregorian = dateHebrew.toGregorian();
|
||
|
var hYear = this._year;
|
||
|
var hMonth = this._month;
|
||
|
var hDate = this._date;
|
||
|
var day = this._startOfYear(hYear);
|
||
|
if(hMonth != 0){
|
||
|
if(this.isLeapYear(hYear)){
|
||
|
day += this.LEAP_MONTH_START[hMonth][this._yearType(hYear)];
|
||
|
} else{
|
||
|
day += this._MONTH_START[hMonth][this._yearType(hYear)];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var julianDay = (hDate + day + 347997);
|
||
|
// The Gregorian epoch day is zero for Monday January 1, year 1.
|
||
|
var gregorianEpochDay = julianDay - this.JAN_1_1_JULIAN_DAY;
|
||
|
// Here we convert from the day number to the multiple radix
|
||
|
// representation. We use 400-year, 100-year, and 4-year cycles.
|
||
|
// For example, the 4-year cycle has 4 years + 1 leap day; giving
|
||
|
// 1461 == 365*4 + 1 days.
|
||
|
var rem = new Array(1);
|
||
|
var n400 = this._floorDivide(gregorianEpochDay , 146097, rem); // 400-year cycle length
|
||
|
|
||
|
var n100 = this._floorDivide(rem[0] , 36524, rem); // 100-year cycle length
|
||
|
|
||
|
var n4 = this._floorDivide(rem[0] , 1461, rem); // 4-year cycle length
|
||
|
|
||
|
var n1 = this._floorDivide(rem[0] , 365, rem);
|
||
|
var year = 400*n400 + 100*n100 + 4*n4 + n1;
|
||
|
var dayOfYear = rem[0]; // zero-based day of year
|
||
|
if(n100 == 4 || n1 == 4){
|
||
|
dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
|
||
|
}else{
|
||
|
++year;
|
||
|
}
|
||
|
|
||
|
var isLeap = !(year%4) && // equiv. to (year%4 == 0)
|
||
|
(year%100 || !(year%400));
|
||
|
var correction = 0;
|
||
|
var march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
|
||
|
if(dayOfYear >= march1){ correction = isLeap ? 1 : 2; }
|
||
|
var month = Math.floor((12 * (dayOfYear + correction) + 6) / 367); // zero-based month
|
||
|
var dayOfMonth = dayOfYear -
|
||
|
this.GREGORIAN_MONTH_COUNT[month][isLeap?3:2] + 1; // one-based DOM
|
||
|
|
||
|
return new Date(year, month, dayOfMonth, this._hours, this._minutes, this._seconds, this._milliseconds);
|
||
|
},
|
||
|
_floorDivide: function(numerator, denominator, remainder){
|
||
|
|
||
|
if(numerator >= 0){
|
||
|
remainder[0] = (numerator % denominator);
|
||
|
return Math.floor(numerator / denominator);
|
||
|
}
|
||
|
var quotient = Math.floor(numerator / denominator);
|
||
|
remainder[0] = numerator - (quotient * denominator);
|
||
|
return quotient;
|
||
|
},
|
||
|
|
||
|
getDay: function(){
|
||
|
// summary: This function return Week Day value ( 0 - 6 )
|
||
|
//
|
||
|
// example:
|
||
|
// | var date1 = new dojox.date.HebrewDate();
|
||
|
// |
|
||
|
// | document.writeln(date1.getDay());
|
||
|
|
||
|
var hYear = this._year;
|
||
|
var hMonth = this._month;
|
||
|
var hDate = this._date;
|
||
|
var day = this._startOfYear(hYear);
|
||
|
if(hMonth != 0){
|
||
|
if(this.isLeapYear(hYear)){
|
||
|
day += this.LEAP_MONTH_START[hMonth][this._yearType(hYear)];
|
||
|
} else{
|
||
|
day += this._MONTH_START[hMonth][this._yearType(hYear)];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
day += hDate - 1;
|
||
|
return (day+1) % 7;
|
||
|
},
|
||
|
|
||
|
// ported from the Java class com.ibm.icu.util.Calendar.computeGregorianMonthStart from ICU4J v3.6.1 at http://www.icu-project.org/
|
||
|
_getJulianDayFromGregorianDate: function(gdate){
|
||
|
//summary: returns the Julian day of a Gregorian date
|
||
|
|
||
|
var year = gdate.getFullYear();
|
||
|
var month = gdate.getMonth();
|
||
|
var d = gdate.getDate();
|
||
|
var isLeap = !(year%4) && (year%100 || !(year%400)); //TODO: dup
|
||
|
var y = year - 1;
|
||
|
// This computation is actually ... + (JAN_1_1_JULIAN_DAY - 3) + 2.
|
||
|
// Add 2 because Gregorian calendar starts 2 days after Julian
|
||
|
// calendar.
|
||
|
var julianDay = 365*y + Math.floor(y/4) - Math.floor(y/100) +
|
||
|
Math.floor(y/400) + this.JAN_1_1_JULIAN_DAY - 1;
|
||
|
// At this point julianDay indicates the day BEFORE the first day
|
||
|
// of January 1, <eyear> of the Gregorian calendar.
|
||
|
if(month != 0){
|
||
|
julianDay += this.GREGORIAN_MONTH_COUNT[month][isLeap?3:2];
|
||
|
}
|
||
|
|
||
|
julianDay += d;
|
||
|
return julianDay;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
dojox.date.HebrewDate.fromGregorian = function(/*Date*/gdate){
|
||
|
// summary: This function returns the equivalent Hebrew Date value for the Gregorian Date
|
||
|
// example:
|
||
|
// | var dateGregorian = new Date(2008,10,12);
|
||
|
// | var dateHebrew = dojox.date.HebrewDate.fromGregorian(dateGregorian);
|
||
|
|
||
|
var dateHebrew = new dojox.date.HebrewDate();
|
||
|
return dateHebrew.fromGregorian(gdate);
|
||
|
};
|
||
|
|
||
|
|
||
|
// Utility methods to do arithmetic calculations with HebrewDates
|
||
|
|
||
|
dojox.date.HebrewDate.add = function(/*HebrewDate*/date, /*String*/interval, /*int*/amount){
|
||
|
// based on and similar to dojo.date.add
|
||
|
// summary:
|
||
|
// Add to a Date in intervals of different size, from milliseconds to years
|
||
|
// date: HebrewDate
|
||
|
// Date object to start with
|
||
|
// interval:
|
||
|
// A string representing the interval. One of the following:
|
||
|
// "year", "month", "day", "hour", "minute", "second",
|
||
|
// "millisecond", "week", "weekday"
|
||
|
// amount:
|
||
|
// How much to add to the date.
|
||
|
|
||
|
var newHebrDate = new dojox.date.HebrewDate(date);
|
||
|
|
||
|
switch(interval){
|
||
|
case "day":
|
||
|
newHebrDate.setDate(date.getDate() + amount);
|
||
|
break;
|
||
|
case "weekday":
|
||
|
var day = date.getDay();
|
||
|
if (((day + amount) < 5) && ((day + amount) >0)) {
|
||
|
newHebrDate.setDate(date.getDate() + amount);
|
||
|
}else{
|
||
|
var adddays = 0; /*weekend */
|
||
|
var remdays = 0;
|
||
|
if (day == 5) {//friday
|
||
|
day = 4;
|
||
|
remdays = (amount > 0) ? -1 : 1;
|
||
|
}else if (day == 6){ //shabat
|
||
|
day = 4;
|
||
|
remdays = (amount > 0) ? -2 : 2;
|
||
|
}
|
||
|
var add = (amount > 0) ? (5 - day - 1) : ( 0-day);
|
||
|
var amountdif = amount - add;
|
||
|
var div=parseInt(amountdif /5);
|
||
|
if ((amountdif %5) != 0){
|
||
|
adddays = (amount > 0) ? 2 : -2;
|
||
|
}
|
||
|
adddays = adddays + div*7 + amountdif %5 + add;
|
||
|
newHebrDate.setDate(date.getDate() + adddays + remdays);
|
||
|
}
|
||
|
break;
|
||
|
case "year":
|
||
|
newHebrDate.setYear(date.getFullYear() + amount );
|
||
|
break;
|
||
|
case "week":
|
||
|
amount *= 7;
|
||
|
newHebrDate.setDate(date.getDate() + amount);
|
||
|
break;
|
||
|
case "month":
|
||
|
var month = date.getMonth();
|
||
|
if(!date.isLeapYear(date.getFullYear()) && month > 5){month --;}
|
||
|
newHebrDate.setMonth(month + amount );
|
||
|
break;
|
||
|
case "hour":
|
||
|
newHebrDate.setHours(date.getHours() + amount );
|
||
|
break;
|
||
|
case "minute":
|
||
|
newHebrDate.setMinutes(date.getMinutes() + amount );
|
||
|
break;
|
||
|
case "second":
|
||
|
newHebrDate.setSeconds(date.getSeconds() + amount );
|
||
|
break;
|
||
|
case "millisecond":
|
||
|
newHebrDate.setMilliseconds(date.getMilliseconds() + amount );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return newHebrDate; // Date
|
||
|
};
|
||
|
|
||
|
dojox.date.HebrewDate.difference = function(/*HebrewDate*/date1, /*HebrewDate?*/date2, /*String?*/interval){
|
||
|
// based on and similar to dojo.date.difference
|
||
|
// summary:
|
||
|
// date1 - date2
|
||
|
// date2 is HebrewDate object. If not specified, the current HebrewDate is used.
|
||
|
// interval:
|
||
|
// A string representing the interval. One of the following:
|
||
|
// "year", "month", "day", "hour", "minute", "second",
|
||
|
// "millisecond", "week", "weekday"
|
||
|
// Defaults to "day".
|
||
|
|
||
|
date2 = date2 || new dojox.date.HebrewDate();
|
||
|
interval = interval || "day";
|
||
|
var yearDiff = date1.getFullYear() - date2.getFullYear();
|
||
|
var delta = 1; // Integer return value
|
||
|
switch(interval){
|
||
|
case "weekday":
|
||
|
var days = Math.round(dojox.date.HebrewDate.difference(date1, date2, "day"));
|
||
|
var weeks = parseInt(dojox.date.HebrewDate.difference(date1, date2, "week"));
|
||
|
var mod = days % 7;
|
||
|
|
||
|
// Even number of weeks
|
||
|
if(mod == 0){
|
||
|
days = weeks*5;
|
||
|
}else{
|
||
|
// Weeks plus spare change (< 7 days)
|
||
|
var adj = 0;
|
||
|
var aDay = date2.getDay();
|
||
|
var bDay = date1.getDay();
|
||
|
|
||
|
weeks = parseInt(days/7);
|
||
|
mod = days % 7;
|
||
|
// Mark the date advanced by the number of
|
||
|
// round weeks (may be zero)
|
||
|
var dtMark = new dojox.date.HebrewDate(date2);
|
||
|
dtMark.setDate(dtMark.getDate()+(weeks*7));
|
||
|
var dayMark = dtMark.getDay();
|
||
|
|
||
|
// Spare change days -- 6 or less
|
||
|
if(days > 0){
|
||
|
switch(true){
|
||
|
// Range starts on Fri
|
||
|
case aDay == 5:
|
||
|
adj = -1;
|
||
|
break;
|
||
|
// Range starts on Sat
|
||
|
case aDay == 6:
|
||
|
adj = 0;
|
||
|
break;
|
||
|
// Range ends on Fri
|
||
|
case bDay == 5:
|
||
|
adj = -1;
|
||
|
break;
|
||
|
// Range ends on Sat
|
||
|
case bDay == 6:
|
||
|
adj = -2;
|
||
|
break;
|
||
|
// Range contains weekend
|
||
|
case (dayMark + mod) > 5:
|
||
|
adj = -2;
|
||
|
}
|
||
|
}else if(days < 0){
|
||
|
switch(true){
|
||
|
// Range starts on Fri
|
||
|
case aDay == 5:
|
||
|
adj = 0;
|
||
|
break;
|
||
|
// Range starts on Sat
|
||
|
case aDay == 6:
|
||
|
adj = 1;
|
||
|
break;
|
||
|
// Range ends on Fri
|
||
|
case bDay == 5:
|
||
|
adj = 2;
|
||
|
break;
|
||
|
// Range ends on Sat
|
||
|
case bDay == 6:
|
||
|
adj = 1;
|
||
|
break;
|
||
|
// Range contains weekend
|
||
|
case (dayMark + mod) < 0:
|
||
|
adj = 2;
|
||
|
}
|
||
|
}
|
||
|
days += adj;
|
||
|
days -= (weeks*2);
|
||
|
}
|
||
|
delta = days;
|
||
|
break;
|
||
|
case "year":
|
||
|
delta = yearDiff;
|
||
|
break;
|
||
|
case "month":
|
||
|
var startdate = (date1.toGregorian() > date2.toGregorian()) ? date1 : date2; // more
|
||
|
var enddate = (date1.toGregorian() > date2.toGregorian()) ? date2 : date1;
|
||
|
|
||
|
var month1 = startdate.getMonth();
|
||
|
var month2 = enddate.getMonth();
|
||
|
|
||
|
if (yearDiff == 0){
|
||
|
delta = ( !date1.isLeapYear(date1.getFullYear()) && startdate.getMonth() > 5 && enddate.getMonth() <=5) ? (startdate.getMonth() - enddate.getMonth() - 1) :
|
||
|
(startdate.getMonth() - enddate.getMonth() );
|
||
|
}else{
|
||
|
delta = (!enddate.isLeapYear(enddate.getFullYear()) && month2 < 6) ? (13-month2-1) : (13-month2);
|
||
|
delta += (!startdate.isLeapYear(startdate.getFullYear()) && month1 > 5) ? (month1 -1): month1;
|
||
|
var i = enddate.getFullYear() + 1;
|
||
|
var e = startdate.getFullYear();
|
||
|
for (i; i < e; i++){
|
||
|
delta += enddate.isLeapYear(i) ? 13 : 12;
|
||
|
}
|
||
|
}
|
||
|
if (date1.toGregorian() < date2.toGregorian()){
|
||
|
delta = -delta;
|
||
|
}
|
||
|
break;
|
||
|
case "week":
|
||
|
// Truncate instead of rounding
|
||
|
// Don't use Math.floor -- value may be negative
|
||
|
delta = parseInt(dojox.date.HebrewDate.difference(date1, date2, "day")/7);
|
||
|
break;
|
||
|
case "day":
|
||
|
delta /= 24;
|
||
|
// fallthrough
|
||
|
case "hour":
|
||
|
delta /= 60;
|
||
|
// fallthrough
|
||
|
case "minute":
|
||
|
delta /= 60;
|
||
|
// fallthrough
|
||
|
case "second":
|
||
|
delta /= 1000;
|
||
|
// fallthrough
|
||
|
case "millisecond":
|
||
|
delta *= date1.toGregorian().getTime()- date2.toGregorian().getTime();
|
||
|
}
|
||
|
|
||
|
// Round for fractional values and DST leaps
|
||
|
return Math.round(delta); // Number (integer)
|
||
|
};
|
||
|
|
||
|
|
||
|
|