UNPKG

navidev-date-and-time

Version:
257 lines 8.14 kB
import dateTimeFormatters from "./formatters"; import DateTimeParsers, { find as findPattern } from "./parser"; /** * Clase con utilidades de fecha y hora. * Código basado en la librería: https://github.com/knowledgecode/date-and-time, pero * adaptado para que funcione en typescript */ export default class DateUtils { constructor() { /** * Devuelve si el año es bisiesto * @param y | Año * @returns Booleano si es bisiesto */ this.isLeapYear = (y) => { return (!(y % 4) && !!(y % 100)) || !(y % 400); }; /** * Devuelve si la fecha en componentes es valida * @param dt | Fecha en componentes * @returns booleano si la fecha es valida */ this.isValid = (dt) => { let last = [ 31, (28 + Number(this.isLeapYear(dt.Y))) | 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ][dt.M - 1]; return !(dt._index < 1 || dt._length < 1 || dt._index - dt._length || dt._match < 1 || dt.Y < 1 || dt.Y > 9999 || dt.M < 1 || dt.M > 12 || dt.D < 1 || dt.D > last || dt.H < 0 || dt.H > 23 || dt.m < 0 || dt.m > 59 || dt.s < 0 || dt.s > 59 || dt.S < 0 || dt.S > 999 || dt.Z < -840 || dt.Z > 720); }; this.parsers = new DateTimeParsers(); } /** * Transforma una fecha pasada con un formato determinado a otro formato * @param dateString | Fecha * @param arg1 | formato de la fecha * @param arg2 | formato a convertir * @param utc | salida en UTC * @return fecha formateada */ transform(dateString, arg1, arg2, utc) { return this.format(this.parse(dateString, arg1), arg2, utc); } /** * formatea una fecha a string, segun el formato pasado * @param dateObj | Fecha * @param formatter | Formato * @param utc | Salida como UTC */ format(dateObj, formatter, utc) { // Patron que se aplicará let patterns = typeof formatter === "string" ? this.compile(formatter) : formatter; // Diferencia entre hora local y UTC let offset = dateObj.getTimezoneOffset(); let d = this.addMinutes(dateObj, utc ? offset : 0); let str = ""; patterns.forEach((pattern) => { str += dateTimeFormatters[pattern] ? dateTimeFormatters[pattern](d) : pattern.replace(/\[(.*)]/, "$1"); }); return str; } /** * Transforma una fecha string a objeto fecha * @param dateString Fecha * @param arg formato de la fecha * @param utc Salida en UTC * @returns Objeto fecha */ parse(dateString, arg, utc) { let dt = this.preparse(dateString, arg); let patterns = this.compile(arg); if (this.isValid(dt)) { dt.M -= dt.Y < 100 ? 22801 : 1; // 22801 = 1900 * 12 + 1 if (utc || ~findPattern(patterns, "ZZ").value) { return new Date(Date.UTC(dt.Y, dt.M, dt.D, dt.H, dt.m + dt.Z, dt.s, dt.S)); } return new Date(dt.Y, dt.M, dt.D, dt.H, dt.m, dt.s, dt.S); } return new Date(NaN); } /** * Añade o resta días a una fecha * @param dateObj | Objeto fecha * @param months | Numero de segundos * @param utc | Calculo como UTC * @returns */ addMonths(dateObj, months, utc) { var d = new Date(dateObj.getTime()); if (utc) { d.setUTCMonth(d.getUTCMonth() + months); if (d.getUTCDate() < dateObj.getUTCDate()) { return this.addDays(d, -d.getUTCDate(), utc); } } else { d.setMonth(d.getMonth() + months); if (d.getDate() < dateObj.getDate()) { return this.addDays(d, -d.getDate(), utc); } } return d; } /** * Añade o resta días a una fecha * @param dateObj | Objeto fecha * @param days | Numero de segundos * @param utc | Calculo como UTC * @returns */ addDays(dateObj, days, utc) { return this.addHours(dateObj, days * 24, utc); } /** * Añade o resta horas a una fecha * @param dateObj | Objeto fecha * @param hours | Numero de segundos * @param utc | Calculo como UTC * @returns */ addHours(dateObj, hours, utc) { return this.addMinutes(dateObj, hours * 60, utc); } /** * Añade o resta minutos a una fecha * @param dateObj | Objeto fecha * @param minutes | Numero de segundos * @param utc | Calculo como UTC * @returns */ addMinutes(dateObj, minutes, utc) { return this.addSeconds(dateObj, minutes * 60, utc); } /** * Añade o resta segundos a una fecha * @param dateObj | Objeto fecha * @param seconds | Numero de segundos * @param utc | Calculo como UTC * @returns */ addSeconds(dateObj, seconds, utc) { return this.addMilliseconds(dateObj, seconds * 1000, utc); } /** * Añade o resta milisegundos a una fecha * @param dateObj | Objeto fecha * @param milliseconds | Numero de milisegundos * @param utc | Calculo como UTC * @returns */ addMilliseconds(dateObj, milliseconds, utc) { var d = new Date(dateObj.getTime()); if (utc) { d.setUTCMilliseconds(d.getUTCMilliseconds() + milliseconds); } else { d.setMilliseconds(d.getMilliseconds() + milliseconds); } return d; } /** * Extrae las partes del formato * @param formatString | formato * @returns Array con el formato separado en un array */ compile(formatString) { let re = /\[([^[\]]|\[[^[\]]*])*]|([A-Za-z])\2+|\.{3}|./g; let keys; let pattern = []; while ((keys = re.exec(formatString))) { pattern[pattern.length] = keys[0]; } return pattern; } /** * Realiza el pre-parse de la fecha en base al formato pasado * @param dateString | Fecha * @param arg | Formato de la fecha * @returns Estructura con los datos de la fecha pasada */ preparse(dateString, arg) { // Patron que se aplicará let patterns = typeof arg === "string" ? this.compile(arg) : arg; let dt = { Y: 1970, M: 1, D: 1, H: 0, A: 0, h: 0, m: 0, s: 0, S: 0, Z: 0, _index: 0, _length: 0, _match: 0, }; let comment = /\[(.*)]/; let offset = 0; patterns.forEach((pattern) => { if (this.parsers.parser()[pattern]) { let result = this.parsers.parser()[pattern](dateString.slice(offset)); if (result.length) { offset += result.length; dt[pattern.charAt(0)] = result.value; dt._match++; } } else if (pattern === dateString.charAt(offset) || pattern === " ") { offset++; } else if (comment.test(pattern) && !dateString.slice(offset).indexOf(comment.exec(pattern)[1])) { offset += pattern.length - 2; } else if (pattern === "...") { offset = dateString.length; } }); dt.H = dt.H || this.parsers.h12(dt.h, dt.A); dt._index = offset; dt._length = dateString.length; return dt; } } //# sourceMappingURL=dateUtils.js.map