react-native-ethiopian-calendar
Version:
A react native calendar component which is mainly intended for applications which require Ethiopian calendar.
87 lines (82 loc) • 3.08 kB
JavaScript
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { mod, CalendarError, BasicDate } from '../Core';
const epoch = 1721425.5;
const MONTH_MAX_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
export class GregorianCalendar {
constructor() {
_defineProperty(this, "jdnToYear", jdn => {
const jd0 = Math.floor(jdn - 0.5) + 0.5;
const depoch = jd0 - epoch;
const quadricent = Math.floor(depoch / 146097);
const dqc = mod(depoch, 146097);
const cent = Math.floor(dqc / 36524);
const dcent = mod(dqc, 36524);
const quad = Math.floor(dcent / 1461);
const dquad = mod(dcent, 1461);
const yindex = Math.floor(dquad / 365);
return quadricent * 400 + cent * 100 + quad * 4 + yindex + (cent !== 4 && yindex !== 4 ? 1 : 0);
});
}
/**
* Test if a year is leap year or not.
* @param {number} year
* @returns {boolean} Boolean
*/
isLeap(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
/**
* Convert Gregorian Date to Julian day number (JDN)
* @param {number} day
* @param {number} month
* @param {number} year
* @returns {number} jdn (Julian Date Number)
*/
toJDN(year, month, day) {
this.validator(year, month, day);
const y1 = year - 1;
const isLeapYear = this.isLeap(year);
const jdn = epoch - 1 + 365 * y1 + Math.floor(y1 / 4) - Math.floor(y1 / 100) + Math.floor(y1 / 400) + Math.floor((367 * month - 362) / 12 + (month <= 2 ? 0 : isLeapYear ? -1 : -2) + day);
return jdn;
}
/**
* Convert Julian day number (JDN) to Gregorian Date.
* @param {number} jdn (Julian Date Number)
* @returns {object} Date object.
*/
fromJDN(jdn) {
const jd0 = Math.floor(jdn - 0.5) + 0.5;
const year = this.jdnToYear(jd0);
const yearDay = jd0 - this.toJDN(year, 1, 1);
const isLeapYear = this.isLeap(year);
const leapAdj = jd0 < this.toJDN(year, 3, 1) ? 0 : isLeapYear ? 1 : 2;
const month = Math.floor(((yearDay + leapAdj) * 12 + 373) / 367);
const day = jd0 - this.toJDN(year, month, 1) + 1;
return new BasicDate(year, month, day, jdn);
}
validator(year, month, day) {
// Month cannot be less than 1 or greater than 12.
if (month < 1 || month > 12) {
throw new CalendarError('INVALID_MONTH');
}
// Day cannot be less than 1
if (day < 1) {
throw new CalendarError('INVALID_DAY');
}
// February can only be 28 or 29 days.
MONTH_MAX_DAYS[1] = this.isLeap(year) ? 29 : 28;
if (month === 2 && day > MONTH_MAX_DAYS[1]) {
throw new CalendarError('INVALID_LEAP_DAY');
}
if (MONTH_MAX_DAYS[month - 1] < day) {
throw new CalendarError('INVALID_DAY');
}
return true;
}
/**
* Convert Julian day number (JDN) to Year.
* @param {number} jdn Julian day number
* @returns {number} year
*/
}
//# sourceMappingURL=GregorianCalendar.js.map