omniserror
Version:
Abstraction over common javascript date management libraries
203 lines (165 loc) • 4.77 kB
text/typescript
import Moment from "moment";
import iMoment from "moment-hijri";
import DefaultMomentUtils from "@date-io/moment";
import { DateIOFormats } from "@date-io/core/IUtils";
var symbolMap = {
1: "١",
2: "٢",
3: "٣",
4: "٤",
5: "٥",
6: "٦",
7: "٧",
8: "٨",
9: "٩",
0: "٠"
};
interface Opts {
instance?: typeof iMoment;
formats?: Partial<DateIOFormats>;
}
type Moment = iMoment.Moment;
const defaultFormats: DateIOFormats = {
dayOfMonth: "iD",
fullDate: "iYYYY, iMMMM Do",
fullDateTime: "iYYYY, iMMMM Do, hh:mm A",
fullDateTime12h: "iD iMMMM hh:mm A",
fullDateTime24h: "iD iMMMM HH:mm",
fullTime: "LT",
fullTime12h: "hh:mm A",
fullTime24h: "HH:mm",
hours12h: "hh",
hours24h: "HH",
keyboardDate: "iYYYY/iMM/dd",
keyboardDateTime: "iYYYY/iMM/iDD LT",
keyboardDateTime12h: "iYYYY/iMM/iDD hh:mm A",
keyboardDateTime24h: "iYYYY/iMM/iDD HH:mm",
minutes: "mm",
month: "iMMMM",
monthAndDate: "iD iMMMM",
monthAndYear: "iMMMM iYYYY",
monthShort: "iMMM",
normalDate: "dddd, iD iMMM",
normalDateWithWeekday: "DD iMMMM",
seconds: "ss",
shortDate: "iD iMMM",
year: "iYYYY"
};
export default class MomentUtils extends DefaultMomentUtils {
public moment: typeof iMoment;
public locale?: string;
public formats: DateIOFormats;
constructor({ instance, formats }: Opts = {}) {
super({ locale: "ar-SA", instance });
this.moment = instance || iMoment;
this.locale = "ar-SA";
this.formats = Object.assign({}, defaultFormats, formats);
}
private toIMoment(date?: any) {
return this.moment(date ? date.clone() : undefined).locale("ar-SA");
}
public parse(value: string, format: string) {
if (value === "") {
return null;
}
return this.moment(value, format, true).locale("ar-SA");
}
public date(value?: any) {
if (value === null) {
return null;
}
return this.moment(value).locale("ar-SA");
}
public isBeforeYear(date: Moment, value: Moment) {
return date.iYear() < value.iYear();
}
public isAfterYear(date: Moment, value: Moment) {
return date.iYear() > value.iYear();
}
public getMonth(date: Moment) {
return date.iMonth();
}
public startOfMonth(date: Moment) {
return date.clone().startOf("iMonth");
}
public endOfMonth(date: Moment) {
return date.clone().endOf("iMonth");
}
public getNextMonth(date: Moment) {
return date.clone().add(1, "iMonth");
}
public getPreviousMonth(date: Moment) {
return date.clone().subtract(1, "iMonth");
}
public getYear(date: Moment) {
return date.iYear();
}
public setYear(date: Moment, year: number) {
return date.clone().iYear(year);
}
public getMeridiemText(ampm: "am" | "pm") {
return ampm === "am"
? this.toIMoment()
.hours(2)
.format("A")
: this.toIMoment()
.hours(14)
.format("A");
}
public getWeekdays() {
return [0, 1, 2, 3, 4, 5, 6].map(dayOfWeek => {
return this.toIMoment()
.weekday(dayOfWeek)
.format("dd");
});
}
public isEqual(value: any, comparing: any) {
if (value === null && comparing === null) {
return true;
}
return this.moment(value).isSame(comparing);
}
public formatNumber(num: string) {
return num.replace(/\d/g, match => symbolMap[match]).replace(/,/g, "،");
}
public getWeekArray(date: Moment) {
const start = date
.clone()
.startOf("iMonth")
.startOf("week");
const end = date
.clone()
.endOf("iMonth")
.endOf("week");
let count = 0;
let current = start;
const nestedWeeks: Moment[][] = [];
while (current.isBefore(end)) {
const weekNumber = Math.floor(count / 7);
nestedWeeks[weekNumber] = nestedWeeks[weekNumber] || [];
nestedWeeks[weekNumber].push(current);
current = current.clone().add(1, "day");
count += 1;
}
return nestedWeeks;
}
public getYearRange(start: Moment, end: Moment) {
// moment-hijri only supports dates between 1356-01-01 H and 1499-12-29 H
// We need to throw if outside min/max bounds, otherwise the while loop below will be infinite.
if (start.isBefore("1937-03-14")) {
throw new Error("min date must be on or after 1356-01-01 H (1937-03-14)");
}
if (end.isAfter("2076-11-26")) {
throw new Error("max date must be on or before 1499-12-29 H (2076-11-26)");
}
const startDate = this.moment(start).startOf("iYear");
const endDate = this.moment(end).endOf("iYear");
const years: Moment[] = [];
let current = startDate;
while (current.isBefore(endDate)) {
years.push(current);
current = current.clone().add(1, "iYear");
}
return years;
}
}