Skip to content

Instantly share code, notes, and snippets.

@nin-jin
Last active March 2, 2021 12:16
Show Gist options
  • Save nin-jin/1ec7cba8119f86113ffe8fe3cb21573a to your computer and use it in GitHub Desktop.
Save nin-jin/1ec7cba8119f86113ffe8fe3cb21573a to your computer and use it in GitHub Desktop.

Date API

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Current engines supports Date API, that:

  • Date instances are mutable. It's bad practivce for value type.
  • It has bloat inconsistent API.
  • It represents only time moments, but doesn't support other time types declared in ISO8601.
  • It doesn't support parsing and serializing by custom pattern.
  • It doesn't support conversion between different time zones.

Temporal API

https://tc39.es/proposal-temporal/docs/index.html

Some engines supports new proposal, but:

  • It has a hard to remember and use API with tons of classes and methods.
  • It doesn't support parsing and serializing by custom pattern.
  • It hasn't full ISO8601 support (like "hour+minute" or "year+weaknumber").
  • It doesn't support time intervals.

Time API

I propose API like $mol_time, that:

  • Very simple.
  • Easy to remember.
  • Consistent.
  • Supports time moments, durations and intervals.
  • Represents all ISO8601 variants.
  • Supports parsing and serializing by custom pattern.

TimeMoment

Immutable iso8601 time moment representation.

type TimeMomentConfig =
| number
| string
| Date
| TimeMoment
| {
	year?: number
	month?: number
	day?: number
	hour?: number
	minute?: number
	second?: number
	offset?: TimeDurationConfig
}

interface TimeMoment {
    
    year?: number
    month?: number // [ 0 .. 12 ]
    day?: number // [ 0 .. 31 ]
    hour?: number // [ 0 .. 24 ]
    minute?: number // [ 0 .. 59 ]
    second?: number // [ 0 .. 59.999 ]
    offset?: TimeDuration
    
    /**
     * Current time in current time zone:
     * 
     *      new TimeMoment()
     * 
     * By timestamp
     * 
     *      new TimeMoment( 1437316165000 )
     * 
     * By Date:
     * 
     *      new TimeMoment( new Date )
     * 
     * By iso8601 string:
     * 
     *      new TimeMoment( '2015-07-19T17:27:58.065+03:00' ) // full time
     *      new TimeMoment( '2015-07-19T17:27:58.065' ) // time without offset (non local!)
     *      new TimeMoment( '2015-07-19' ) // date without time (non 00:00:00)
     *      new TimeMoment( 'T17:27' ) // time without date and seconds
     *      // etc
     * 
     * By components:
     * 
     *      new TimeMoment({
     *      	year: 2015,
     *      	month: 6,
     *      	day: 18,
     *      	hour: 17,
     *      	minute: 27,
     *      	second: 58.65,
     *      	offset: {
     *      		hour: 3,
     *      		minute: 0,
     *      	},
     *      })
     */
    constructor( config?: TimeMomentConfig ): TimeMoment

    /**
     * Day of week
     * 0 - monday
     * 6 - sunday
     */
    weekday: number

    // Timestamp, count of milliseconds from unix epoch
    valueOf(): number

    /**
     * Iso8601 string by default.
     * 
     * Mnemonics:
     * 
     * - single letter for numbers: `M` - month number, `D` - day of month.
     * - uppercase letters for dates, lowercase for times: `M` - month number , `m` - minutes number
     * - repeated letters for define register count: `YYYY` - full year, `YY` - shot year, `MM` - padded month number
     * - words for word representation: `Month` - month name, `WeekDay` - day of week name
     * - shortcuts: `WD` - short day of week, `Mon` - short month name.
     * 
     * Exampes:
     * 
     *      // "2015-07-20 07:22 (monday)"
     *      moment.toString( 'YYYY-MM-DD hh:mm (WeekDay)' )
     */
    toString( pattern?: string ): string
    
    /**
     * Iso8601 string
     */
    toJSON(): string
    
    /**
     * Creates moment by merge one moment with another component by component
     */
    merge( config: TimeMomentConfig ): TimeMoment

    /**
     * Creates moment by shift one by TimeDurationConfig
     */
    shift( config: TimeDurationConfig ): TimeMoment

    /**
     * Creates moment by recalc one to another offset
     */
    toOffset( config: TimeDurationConfig ): TimeMoment

}

Conversion to Date:

new Date( moment )

TimeDuration

Immutable iso8601 time duration representation.

type TimeDurationConfig =
| number
| string
| TimeDuration
| {
	year?: number
	month?: number
	day?: number
	hour?: number
	minute?: number
	second?: number
}

interface TimeDuration {
    
    year?: number
    month?: number
    day?: number
    hour?: number
    minute?: number
    second?: number
    
    /** Is duration positive or negative*/
    positive: boolean
    
    /**
     * Zero duration:
     * 
     *      new TimeDuration()
     *  
     * By milliseconds count:
     * 
     *      new TimeDuration( 60000 ) // 60 seconds (non 1 minute!)
     *  
     * By iso8601 string:
     * 
     *      new TimeDuration( 'P1Y2M3DT4H5M6.7S' ) // all components are optional
     *      new TimeDuration( 'PT' ) // zero duration
     *  
     * By components:
     * 
     *      new TimeDuration({
     *          year: 1 ,
     *          month: 2 ,
     *          day: 3 ,
     *          hour: 4 ,
     *          minute: 5 ,
     *          second: 6.7 ,
     *      })
     */
    constructor( config?: TimeDurationConfig ): TimeDuration
    
    // Duration in milliseconds
    valueOf(): number

    /**
     * Iso8601 string by default.
     * 
     * Mnemonics:
     * 
     * - single letter for numbers: `M` - month number, `D` - day of month.
     * - uppercase letters for dates, lowercase for times: `M` - month number , `m` - minutes number
     * - repeated letters for define register count: `YYYY` - full year, `YY` - shot year, `MM` - padded month number
     * - words for word representation: `Month` - plural months, `Hour` - plural hours
     * 
     * Exampes:
     * 
     *      // "05 days"
     *      duration.toString( 'DD Day' )
     */
    toString( pattern?: string ): string
    
    /**
     * Iso8601 string
     */
    toJSON(): string
    
    /**
     * Creates duration as summ of one with another
     */
    summ( config: TimeDurationConfig ): TimeDuration

    /**
     * Create duration as multiply of one to multiplier
     * Attention! Can produce negative values that is not compatible with iso8601
     */
    multiply( multiplier: number ): TimeDuration

    /**
     * Count of another durations in this
     * 
     * Exmaples:
     * 
     *      new TimeDuration( 'PT1h' ).count( 'PT1s' ) // 3600
     */
    count( config: TimeDurationConfig )

}

TimeInterval

Immutable iso8601 time interval representation.

type TimeIntervalConfig =
| string
| TimeInterval
| {
    start: TimeMomentConfig
    end: TimeMomentConfig
}
| {
    start: TimeMomentConfig
    duration: TimeDurationConfig
}
| {
    duration: TimeDurationConfig
    end: TimeMomentConfig
}

interface TimeDuration {
    
    // Component value (third are calculated by defined two)
    start?: TimeMoment
    duration?: TimeDuration
    end?: TimeMoment
    
    /**
     * By iso8601 string
     * 
     *      new TimeInterval( '2015-07-19/2015-08-02' ) // by two moments
     *      new TimeInterval( '2015-07-19/P14D' ) // by start moment and duration
     *      new TimeInterval( 'P14D/2015-08-02' ) // by end moment and duration
     *      new TimeInterval( '2015-07-19/' ) // by start moment and now
     *      new TimeInterval( '/2015-08-02' ) // by now and end moment
     * 
     * By components
     * 
     *      new TimeInterval({
     * 	        start : '2015-07-19',
     * 	        end : '2015-08-02',
     *      })
     *      new TimeInterval({
     *      	start : '2015-07-19',
     *      	duration : 'P14D',
     *      })
     *      new TimeInterval({
     *      	duration : 'P14D',
     *      	end : '2015-08-02',
     *      })
     */
    constructor( config?: TimeDurationConfig ): TimeDuration
    
    /**
     * Iso8601 string
     */
    toString(): string
    
    /**
     * Iso8601 string
     */
    toJSON(): string
    
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment