import { DateTime as LuxonDatetime , Info } from 'luxon' ; import { DateObject } from './date-object' ; import { Duration } from './duration' ; import { StringUnitLength } from './string-unit-length' ; import { InfoOptions } from './info-options' ; export class Datetime { static now ( ) { return new Datetime ( LuxonDatetime . local ( ) . setZone ( 'utc' ) ) ; } static new ( year ? , month ? , day ? , hour ? , minute ? , second ? , millisecond ? ) ; static new ( dateObject ) ; static new ( dateObject = 1970 , month = 1 , day = 1 , hour = 0 , minute = 0 , second = 0 , millisecond = 0 ) { if ( typeof dateObject === 'object' ) { const defaultDateObject = { year : 1970 , month : 1 , day : 1 , hour : 0 , minute : 0 , second : 0 , millisecond : 0 , ... dateObject } ; return new Datetime ( LuxonDatetime . fromObject ( defaultDateObject ) ) ; } return new Datetime ( LuxonDatetime . fromObject ( { year : dateObject , month , day , hour , minute , second , millisecond } ) ) ; } param isoString static fromIsoString ( isoString ) { return new Datetime ( LuxonDatetime . fromISO ( isoString ) ) ; } static fromJsDate ( date ) { return new Datetime ( LuxonDatetime . fromJSDate ( date ) ) ; } param value param format param options static fromFormat ( value , format , options = { locale : 'es-ES' } ) { return new Datetime ( LuxonDatetime . fromFormat ( value , format , options ) ) ; } static months ( length ? , options ? ) { return Info . months ( length , options ) ; } static weekdays ( length ? , options ? ) { return Info . weekdays ( length , options ) ; } constructor ( private readonly _value , isLocal = false ) { if ( isLocal ) { this . _value = _value ; } else { this . _value = this . _value . setZone ( 'utc' ) ; } } get jsDate ( ) : Date { return this . _value . toJSDate ( ) ; } get daysInMonth ( ) : number { return this . _value . daysInMonth ; } get year ( ) : number { return this . _value . year ; } get month ( ) : number { return this . _value . month ; } get day ( ) : number { return this . _value . day ; } get hour ( ) : number { return this . _value . hour ; } get minute ( ) : number { return this . _value . minute ; } get second ( ) : number { return this . _value . second ; } get millisecond ( ) : number { return this . _value . millisecond ; } get weekday ( ) { return this . _value . weekday ; } clone ( ) { return new Datetime ( this . _value ) ; } add ( dateObject ) { if ( Duration . isDuration ( dateObject ) ) { return new Datetime ( this . _value . plus ( dateObject . value ) ) ; } return new Datetime ( this . _value . plus ( { day : dateObject . day , year : dateObject . year , month : dateObject . month , hour : dateObject . hour , minute : dateObject . minute , second : dateObject . second , millisecond : dateObject . millisecond } ) ) ; } difference ( datetime ) { const iso8601 = this . _value . diff ( datetime . _value ) . toISO ( ) ; return Duration . fromIso ( iso8601 ) ; } toIso ( ) { const date = [ this . _value . year , this . _value . month , this . _value . day ] . map ( this . addPadStart ) ; const time = [ this . _value . hour , this . _value . minute , this . _value . second ] . map ( this . addPadStart ) ; return `${ date . join ( '-' ) }T${ time . join ( ':' ) }Z` ; } toLocal ( ) { return new Datetime ( this . _value . toLocal ( ) , true ) ; } toMillis ( ) { return this . _value . toMillis ( ) ; } asLocal ( ) { return new Datetime ( this . _value . setZone ( 'local' , { keepLocalTime : true } ) , true ) ; } isValid ( ) { return this . _value . isValid ; } set ( { year , month , day , hour , minute , second , millisecond } ) { return new Datetime ( this . _value . set ( { year , month , day , hour , minute , second , millisecond } ) ) ; } format ( value , options ? ) { return this . _value . toFormat ( value , options ) ; } equals ( datetimeToCompare ) { return + this === + datetimeToCompare ; } valueOf ( ) { return this . jsDate . getTime ( ) ; } toString ( ) { return this . toIso ( ) ; } private addPadStart ( number ) { return number . toString ( ) . padStart ( 2 , '0' ) ; } }