/**
* utils for gregorian date
* @ignore
* @author yiminghe@gmail.com
*/
KISSY.add('date/gregorian/utils', function (S, Const) {
var ACCUMULATED_DAYS_IN_MONTH
// 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 9/1 10/1 11/1 12/1
= [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
ACCUMULATED_DAYS_IN_MONTH_LEAP
// 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1 9/1
// 10/1 11/1 12/1
= [ 0, 31, 59 + 1, 90 + 1, 120 + 1, 151 + 1, 181 + 1,
212 + 1, 243 + 1, 273 + 1, 304 + 1, 334 + 1],
DAYS_OF_YEAR = 365,
DAYS_OF_4YEAR = 365 * 4 + 1,
DAYS_OF_100YEAR = DAYS_OF_4YEAR * 25 - 1,
DAYS_OF_400YEAR = DAYS_OF_100YEAR * 4 + 1,
Utils = {};
function getDayOfYear(year, month, dayOfMonth) {
return dayOfMonth + (isLeapYear(year) ?
ACCUMULATED_DAYS_IN_MONTH_LEAP[month] :
ACCUMULATED_DAYS_IN_MONTH[month]);
}
function getDayOfWeekFromFixedDate(fixedDate) {
// The fixed day 1 (January 1, 1 Gregorian) is Monday.
if (fixedDate >= 0) {
return fixedDate % 7;
}
return mod(fixedDate, 7);
}
function getGregorianYearFromFixedDate(fixedDate) {
var d0;
var d1, d2, d3;//, d4;
var n400, n100, n4, n1;
var year;
d0 = fixedDate - 1;
n400 = floorDivide(d0 / DAYS_OF_400YEAR);
d1 = mod(d0, DAYS_OF_400YEAR);
n100 = floorDivide(d1 / DAYS_OF_100YEAR);
d2 = mod(d1, DAYS_OF_100YEAR);
n4 = floorDivide(d2 / DAYS_OF_4YEAR);
d3 = mod(d2, DAYS_OF_4YEAR);
n1 = floorDivide(d3 / DAYS_OF_YEAR);
year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
// ?
if (!(n100 == 4 || n1 == 4)) {
++year;
}
return year;
}
S.mix(Utils, {
'isLeapYear': function (year) {
if ((year & 3) != 0) {
return false;
}
return (year % 100 != 0) || (year % 400 == 0);
},
mod: function (x, y) {
// 负数时不是镜像关系
return (x - y * floorDivide(x / y));
},
// month: 0 based
getFixedDate: function (year, month, dayOfMonth) {
var prevYear = year - 1;
// 考虑公元前
return DAYS_OF_YEAR * prevYear + floorDivide(prevYear / 4) -
floorDivide(prevYear / 100) + floorDivide(prevYear / 400) +
getDayOfYear(year, month, dayOfMonth);
},
getGregorianDateFromFixedDate: function (fixedDate) {
var year = getGregorianYearFromFixedDate(fixedDate);
var jan1 = Utils.getFixedDate(year, Const.JANUARY, 1);
var isLeap = isLeapYear(year);
var ACCUMULATED_DAYS = isLeap ? ACCUMULATED_DAYS_IN_MONTH_LEAP : ACCUMULATED_DAYS_IN_MONTH;
var daysDiff = fixedDate - jan1;
var month, i;
for (i = 0; i < ACCUMULATED_DAYS.length; i++) {
if (ACCUMULATED_DAYS[i] <= daysDiff) {
month = i;
} else {
break;
}
}
var dayOfMonth = fixedDate - jan1 - ACCUMULATED_DAYS[month] + 1;
var dayOfWeek = getDayOfWeekFromFixedDate(fixedDate);
return {
year: year,
month: month,
dayOfMonth: dayOfMonth,
dayOfWeek: dayOfWeek,
isLeap: isLeap
};
}
});
var floorDivide = Math.floor,
isLeapYear = Utils.isLeapYear,
mod = Utils.mod;
return Utils;
}, {
requires: ['./const']
});