UNPKG

blumjs

Version:
230 lines (196 loc) 7.98 kB
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; } }