import { int , pad } from '.' ; import { Locale } from '../types/locale' ; export type token = 'D' | 'F' | 'G' | 'H' | 'J' | 'K' | 'M' | 'S' | 'U' | 'W' | 'Y' | 'Z' | 'd' | 'h' | 'i' | 'j' | 'l' | 'm' | 'n' | 's' | 'u' | 'w' | 'y' ; const doNothing = ( ) : undefined => undefined ; export const monthToStr = ( monthNumber , shorthand , locale ) : string => locale . months [ shorthand ? 'shorthand' : 'longhand' ] [ monthNumber ] ; export type RevFormatFn = ( date : Date , data : string , locale : Locale ) => Date | void | undefined ; export type RevFormat = Record < string , RevFormatFn > ; export const revFormat = { D : doNothing , F ( dateObj , monthName , locale ) { dateObj . setMonth ( locale . months . longhand . indexOf ( monthName ) ) ; } , G : ( dateObj , hour ) => { dateObj . setHours ( parseFloat ( hour ) ) ; } , H : ( dateObj , hour ) => { dateObj . setHours ( parseFloat ( hour ) ) ; } , J : ( dateObj , day ) => { dateObj . setDate ( parseFloat ( day ) ) ; } , K : ( dateObj , amPM , locale ) => { dateObj . setHours ( ( dateObj . getHours ( ) % 12 ) + 12 * int ( new RegExp ( locale . amPM [ 1 ] , 'i' ) . test ( amPM ) ) ) ; } , M ( dateObj , shortMonth , locale ) { dateObj . setMonth ( locale . months . shorthand . indexOf ( shortMonth ) ) ; } , S : ( dateObj , seconds ) => { dateObj . setSeconds ( parseFloat ( seconds ) ) ; } , U : ( _ , unixSeconds ) => new Date ( parseFloat ( unixSeconds ) * 1000 ) , W ( dateObj , weekNum , locale ) { const weekNumber = parseInt ( weekNum , 10 ) ; const date = new Date ( dateObj . getFullYear ( ) , 0 , 2 + ( weekNumber - 1 ) * 7 , 0 , 0 , 0 , 0 ) ; date . setDate ( date . getDate ( ) - date . getDay ( ) + locale . firstDayOfWeek ) ; return date ; } , Y : ( dateObj , year ) => { dateObj . setFullYear ( parseFloat ( year ) ) ; } , Z : ( _ , ISODate ) => new Date ( ISODate ) , d : ( dateObj , day ) => { dateObj . setDate ( parseFloat ( day ) ) ; } , h : ( dateObj , hour ) => { dateObj . setHours ( parseFloat ( hour ) ) ; } , i : ( dateObj , minutes ) => { dateObj . setMinutes ( parseFloat ( minutes ) ) ; } , j : ( dateObj , day ) => { dateObj . setDate ( parseFloat ( day ) ) ; } , l : doNothing , m : ( dateObj , month ) => { dateObj . setMonth ( parseFloat ( month ) - 1 ) ; } , n : ( dateObj , month ) => { dateObj . setMonth ( parseFloat ( month ) - 1 ) ; } , s : ( dateObj , seconds ) => { dateObj . setSeconds ( parseFloat ( seconds ) ) ; } , u : ( _ , unixMillSeconds ) => new Date ( parseFloat ( unixMillSeconds ) ) , w : doNothing , y : ( dateObj , year ) => { dateObj . setFullYear ( 2000 + parseFloat ( year ) ) ; } , } ; export type TokenRegex = { [ k in token ] : string ; } ; export const tokenRegex = { D : '(\\w+)' , F : '(\\w+)' , G : '(\\d\\d|\\d)' , H : '(\\d\\d|\\d)' , J : '(\\d\\d|\\d)\\w+' , K : '' , M : '(\\w+)' , S : '(\\d\\d|\\d)' , U : '(.+)' , W : '(\\d\\d|\\d)' , Y : '(\\d{4})' , Z : '(.+)' , d : '(\\d\\d|\\d)' , h : '(\\d\\d|\\d)' , i : '(\\d\\d|\\d)' , j : '(\\d\\d|\\d)' , l : '(\\w+)' , m : '(\\d\\d|\\d)' , n : '(\\d\\d|\\d)' , s : '(\\d\\d|\\d)' , u : '(.+)' , w : '(\\d\\d|\\d)' , y : '(\\d{2})' , } ; export type Formats = Record < token , ( date : Date , locale : Locale ) => string | number > ; export const formats = { Z : ( date ) => date . toISOString ( ) , D ( date , locale ) { return locale . weekdays . shorthand [ formats . w ( date , locale ) as number ] ; } , F ( date , locale ) { return monthToStr ( ( formats . n ( date , locale ) as number ) - 1 , false , locale ) ; } , G ( date , locale ) { return pad ( formats . h ( date , locale ) ) ; } , H : ( date ) => pad ( date . getHours ( ) ) , J ( date , locale ) { return locale . ordinal !== undefined ? date . getDate ( ) + locale . ordinal ( date . getDate ( ) ) : date . getDate ( ) ; } , K : ( date , locale ) => locale . amPM [ int ( date . getHours ( ) > 11 ) ] , M ( date , locale ) { return monthToStr ( date . getMonth ( ) , true , locale ) ; } , S : ( date ) => pad ( date . getSeconds ( ) ) , U : ( date ) => date . getTime ( ) / 1000 , W ( givenDate ) { const date = new Date ( givenDate . getTime ( ) ) ; date . setHours ( 0 , 0 , 0 , 0 ) ; date . setDate ( date . getDate ( ) + 3 - ( ( date . getDay ( ) + 6 ) % 7 ) ) ; const week1 = new Date ( date . getFullYear ( ) , 0 , 4 ) ; return ( 1 + Math . round ( ( ( date . getTime ( ) - week1 . getTime ( ) ) / 86400000 - 3 + ( ( week1 . getDay ( ) + 6 ) % 7 ) ) / 7 ) ) ; } , Y : ( date ) => pad ( date . getFullYear ( ) , 4 ) , d : ( date ) => pad ( date . getDate ( ) ) , h : ( date ) => ( date . getHours ( ) % 12 ? date . getHours ( ) % 12 : 12 ) , i : ( date ) => pad ( date . getMinutes ( ) ) , j : ( date ) => date . getDate ( ) , l ( date , locale ) { return locale . weekdays . longhand [ date . getDay ( ) ] ; } , m : ( date ) => pad ( date . getMonth ( ) + 1 ) , n : ( date ) => date . getMonth ( ) + 1 , s : ( date ) => date . getSeconds ( ) , u : ( date ) => date . getTime ( ) , w : ( date ) => date . getDay ( ) , y : ( date ) => String ( date . getFullYear ( ) ) . substring ( 2 ) , } ;