UNPKG

caldate

Version:
247 lines (227 loc) 5.64 kB
import moment from 'moment-timezone' import { toYear, toNumber, isDate, pad0 } from './utils.js' const PROPS = ['year', 'month', 'day', 'hour', 'minute', 'second'] export class CalDate { /** * constructs a new CalDate instance * @param {Object|Date} [opts] - See `set(opts)` * @example * const CalDate = require('caldate') * const caldate = new CalDate('2000-01-01 12:00:00') * caldate.year * //> 2000 * caldate.month * //> 1 */ constructor (opts) { this.set(opts) } static toYear (year) { return toYear(year) } /** * set calendar date * @param {Object|Date} [opts] - defaults to `1900-01-01` * @param {String} opts.year * @param {String} opts.month - January equals to 1, December to 12 * @param {String} opts.day * @param {String} opts.hour * @param {String} opts.minute * @param {String} opts.second * @param {String} opts.duration - defaults to 24 hours */ set (opts) { opts = opts || { year: 1900, month: 1, day: 1 } if (isDate(opts)) { this.year = opts.getFullYear() this.month = opts.getMonth() + 1 this.day = opts.getDate() this.hour = opts.getHours() this.minute = opts.getMinutes() this.second = opts.getSeconds() } else { PROPS.forEach((p) => { this[p] = toNumber(opts[p]) || 0 }) this.month = this.month || 1 this.day = this.day || 1 } this.duration = opts.duration || 24 // duration is in hours return this } /** * checks if Date is equal to `calDate` * @param {CalDate} calDate * @return {Boolean} true if date matches */ isEqualDate (calDate) { let res = true this.update() ;['year', 'month', 'day'].forEach((p) => { res &= (this[p] === calDate[p]) }) return !!res } /** * get day of week * @return {Number} day of week 0=sunday, 1=monday, ... */ getDay () { return this.toDate().getDay() } /** * set offset per unit * @param {Number} number * @param {String} [unit='d'] - Unit in days `d`, hours `h, minutes `m` * @return {Object} this */ setOffset (number, unit) { if (number) { if (typeof number === 'object') { unit = number.unit number = number.number } unit = unit || 'd' number = parseFloat(number, 10) if (isNaN(number)) { throw new Error('Number required') } const o = { day: 0 } if (unit === 'd') { o.day = number | 0 number -= o.day number *= 24 } if (unit === 'd' || unit === 'h') { o.hour = (number % 24) | 0 number -= o.hour number *= 60 } o.minute = (number % 60) | 0 number -= o.minute number *= 60 o.second = (number % 60) | 0 this.day += o.day this.hour += o.hour this.minute += o.minute this.second += o.second } this.update() return this } /** * set time per hour, minute or second while maintaining duration at midnight * @param {Number} [hour] * @param {Number} [minute] * @param {Number} [second] * @return {Object} this */ setTime (hour, minute, second) { hour = hour || 0 minute = minute || 0 second = second || 0 // the holiday usually ends at midnight - if this is not the case set different duration explicitely this.duration = 24 - (hour + minute / 60 + second / 3600) this.hour = hour this.minute = minute this.second = second this.update() return this } /** * set duration in hours * @param {Number} duration in hours * @return {Object} this */ setDuration (duration) { this.duration = duration return this } /** * update internal data to real date * @return {Object} this */ update () { if (this.year) { const d = new CalDate(this.toDate()) PROPS.forEach((p) => { this[p] = d[p] }) } return this } /** * get end date of calendar date * @return {CalDate} */ toEndDate () { const d = new CalDate(this.toDate()) d.minute += ((this.duration * 60) | 0) d.update() return d } /** * move internal date to a date in `timezone` * @param {String} timezone - e.g. 'America/New_York' * @return {Date} */ toTimezone (timezone) { if (timezone) { return new Date(moment.tz(this.toString(), timezone).format()) } else { return this.toDate() } } /** * set date from a given `timezone` * @param {Date} dateUTC - date in UTC * @param {String} [timezone] - timezone of dateUTC, e.g. 'America/New_York' * @return {CalDate} self */ fromTimezone (dateUTC, timezone) { if (timezone) { const m = moment.tz(dateUTC, timezone) this.year = m.year() this.month = m.month() + 1 this.day = m.date() this.hour = m.hours() this.minute = m.minutes() this.second = m.seconds() } else { this.set(dateUTC) } return this } /** * convert to Date * @return {Date} */ toDate () { return new Date( this.year, this.month - 1, this.day, this.hour, this.minute, this.second, 0 ) } /** * get Date in ISO format */ toISOString () { return this.toString(true) } /** * get Date as String `YYYY-MM-DD HH:MM:SS` */ toString (iso) { const d = new CalDate(this.toDate()) return ( pad0(d.year, 4) + '-' + pad0(d.month) + '-' + pad0(d.day) + (iso ? 'T' : ' ') + pad0(d.hour) + ':' + pad0(d.minute) + ':' + pad0(d.second) + (iso ? 'Z' : '') ) } }