blumjs
Version:
A UI Package for Angular2
230 lines (196 loc) • 7.98 kB
text/typescript
import {DatePipe} from "@angular/common";
import {CalendarBase} from "../calendarbase";
import {DateUnit} from "../dateunit";
import {Row, Cell} from "../elements";
export class Jalali implements CalendarBase {
weekDayNames = ['یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'];
weekFirstDay = 6;
monthNames = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'ابان', 'آذر', 'دی', 'بهمن', 'اسفند'];
private monthLength = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29];
private leapYearMonthLength = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30];
getNameOfMonth(num: number): string {
return this.monthNames[num];
}
dateToString(date: Date, format: string): string {
let res;
if(date.getFullYear() > 1800) {
res = date
} else {
res = Jalali.jalaliToGregorian(+date.getFullYear(),+date.getMonth()+1, +date.getDate());
res.setMonth(res.getMonth()-1);
}
let output = new DatePipe('fa-fa').transform(res, format);
return output.replace('ه.ش.', '');
}
dateToDateUnit(date: Date): DateUnit {
let uDate: DateUnit = new DateUnit();
if (date.getFullYear() > 1800) {
let tempDate = Jalali.gregorianToJalali(date.getFullYear(), date.getMonth()+1, date.getDate());
uDate.year = tempDate.jy;
uDate.month = tempDate.jm-1;
uDate.day = tempDate.jd;
} else {
uDate.year = date.getFullYear();
uDate.month = date.getMonth();
uDate.day = date.getDate();
}
uDate.hour = date.getHours();
uDate.minute = date.getMinutes();
uDate.seconds = date.getSeconds();
return uDate;
}
dateUnitToDate(date: DateUnit): Date {
return new Date(date.year, date.month, date.day, date.hour, date.minute, date.seconds);
}
getMonthLength(date: DateUnit) {
let r = Jalali.jalaliCal(date.year);
if (r.leap) {
return this.monthLength[date.month];
}
return this.leapYearMonthLength[date.month];
}
weekHeaders() {
let row = new Row();
for (let i = 0; i < 7; i++) {
row.cells[i] = new Cell;
let index = i + this.weekFirstDay;
index -= (i + this.weekFirstDay < 7) ? 0 : 7;
row.cells[i].content = this.weekDayNames[index];
}
return row;
}
dayNumberOfMonthFirst(date: DateUnit): number {
let temp = this.dateUnitToDate(date);
return Jalali.jalaliToGregorian(temp.getFullYear(), temp.getMonth(), 1).getDay();
}
public static jalaliToGregorian(year, month, day) {
let r = Jalali.jalaliCal(year);
let d = Jalali.div((r.gy + Jalali.div(3 - 8, 6) + 100100) * 1461, 4)
+ Jalali.div(153 * Jalali.mod(3 + 9, 12) + 2, 5)
+ r.march - 34840408;
d = d - Jalali.div(Jalali.div(r.gy + 100100 + Jalali.div(3 - 8, 6), 100) * 3, 4) + 752;
let result = d + (month - 1) * 31 - Jalali.div(month, 7) * (month - 7) + day - 1;
let j, i, gd, gm, gy;
j = 4 * result + 139361631;
j = j + Jalali.div(Jalali.div(4 * result + 183187720, 146097) * 3, 4) * 4 - 3908;
i = Jalali.div(Jalali.mod(j, 1461), 4) * 5 + 308;
gd = Jalali.div(Jalali.mod(i, 153), 5) + 1;
gm = Jalali.mod(Jalali.div(i, 153), 12) + 1;
gy = Jalali.div(j, 1461) - 100100 + Jalali.div(8 - gm, 6);
return new Date(gy, gm, gd);
}
public static gregorianToJalali(year, month, day) {
let d = Jalali.div((year + Jalali.div(month - 8, 6) + 100100) * 1461, 4)
+ Jalali.div(153 * Jalali.mod(month + 9, 12) + 2, 5)
+ day - 34840408;
d = d - Jalali.div(Jalali.div(year + 100100 + Jalali.div(month - 8, 6), 100) * 3, 4) + 752;
let j0, i0, gd0, gm0, gy0;
j0 = 4 * d + 139361631;
j0 = j0 + Jalali.div(Jalali.div(4 * d + 183187720, 146097) * 3, 4) * 4 - 3908;
i0 = Jalali.div(Jalali.mod(j0, 1461), 4) * 5 + 308;
gd0 = Jalali.div(Jalali.mod(i0, 153), 5) + 1;
gm0 = Jalali.mod(Jalali.div(i0, 153), 12) + 1;
gy0 = Jalali.div(j0, 1461) - 100100 + Jalali.div(8 - gm0, 6);
let d2g = {
gy: gy0
, gm: gm0
, gd: gd0
};
// Calculate Gregorian year (gy).
let gy = d2g.gy;
let jy = gy - 621;
let r = Jalali.jalaliCal(jy);
let jdn1f = Jalali.div((gy + Jalali.div(3 - 8, 6) + 100100) * 1461, 4)
+ Jalali.div(153 * Jalali.mod(3 + 9, 12) + 2, 5)
+ r.march - 34840408;
jdn1f = jdn1f - Jalali.div(Jalali.div(gy + 100100 + Jalali.div(3 - 8, 6), 100) * 3, 4) + 752;
let jd;
let jm;
let k;
// Find number of days that passed since 1 Farvardin.
k = d - jdn1f;
if (k >= 0) {
if (k <= 185) {
// The first 6 months.
jm = 1 + Jalali.div(k, 31);
jd = Jalali.mod(k, 31) + 1;
return {
jy: jy
, jm: jm
, jd: jd
}
} else {
// The remaining months.
k -= 186
}
} else {
// Previous Jalali year.
jy -= 1;
k += 179;
if (r.leap === 1)
k += 1;
}
jm = 7 + Jalali.div(k, 30);
jd = Jalali.mod(k, 30) + 1;
return {
jy: jy
, jm: jm
, jd: jd
}
}
private static jalaliCal(jy) {
let breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210
, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178
]
, bl = breaks.length
, gy1 = jy + 621
, leapJ = -14
, jp = breaks[0]
, jm1
, jump
, leap
, leapG
, march
, n
, i1;
if (jy < jp || jy >= breaks[bl - 1])
throw new Error('Invalid Jalali year ' + jy);
// Find the limiting years for the Jalali year jy.
for (i1 = 1; i1 < bl; i1 += 1) {
jm1 = breaks[i1];
jump = jm1 - jp;
if (jy < jm1)
break;
leapJ = leapJ + Jalali.div(jump, 33) * 8 + Jalali.div(Jalali.mod(jump, 33), 4);
jp = jm1
}
n = jy - jp;
// Find the number of leap years from AD 621 to the beginning
// of the current Jalali year in the Persian calendar.
leapJ = leapJ + Jalali.div(n, 33) * 8 + Jalali.div(Jalali.mod(n, 33) + 3, 4);
if (Jalali.mod(jump, 33) === 4 && jump - n === 4)
leapJ += 1;
// And the same in the Gregorian calendar (until the year gy).
leapG = Jalali.div(gy1, 4) - Jalali.div((Jalali.div(gy1, 100) + 1) * 3, 4) - 150;
// Determine the Gregorian date of Farvardin the 1st.
march = 20 + leapJ - leapG;
// Find how many years have passed since the last leap year.
if (jump - n < 6)
n = n - jump + Jalali.div(jump + 4, 33) * 33;
leap = Jalali.mod(Jalali.mod(n + 1, 33) - 1, 4);
if (leap === -1) {
leap = 4
}
return {
leap: leap
, gy: gy1
, march: march
};
}
private static div(a, b): number {
return ~~(a / b);
}
private static mod(a, b): number {
return a - ~~(a / b) * b;
}
}