225 lines
6.4 KiB
JavaScript
225 lines
6.4 KiB
JavaScript
import { titleCase, zeroPad, ordinal } from '../../fns.js'
|
|
import { short } from '../../data/months.js'
|
|
import { short as _short } from '../../data/days.js'
|
|
import { useTitleCase } from '../../data/caseFormat.js'
|
|
import isoOffset from './_offset.js'
|
|
|
|
const applyCaseFormat = (str) => {
|
|
if (useTitleCase()) {
|
|
return titleCase(str)
|
|
}
|
|
return str
|
|
}
|
|
|
|
// iso-year padding
|
|
const padYear = (num) => {
|
|
if (num >= 0) {
|
|
return zeroPad(num, 4)
|
|
} else {
|
|
num = Math.abs(num)
|
|
return '-' + zeroPad(num, 4)
|
|
}
|
|
}
|
|
|
|
const format = {
|
|
day: (s) => applyCaseFormat(s.dayName()),
|
|
'day-short': (s) => applyCaseFormat(_short()[s.day()]),
|
|
'day-number': (s) => s.day(),
|
|
'day-ordinal': (s) => ordinal(s.day()),
|
|
'day-pad': (s) => zeroPad(s.day()),
|
|
|
|
date: (s) => s.date(),
|
|
'date-ordinal': (s) => ordinal(s.date()),
|
|
'date-pad': (s) => zeroPad(s.date()),
|
|
|
|
month: (s) => applyCaseFormat(s.monthName()),
|
|
'month-short': (s) => applyCaseFormat(short()[s.month()]),
|
|
'month-number': (s) => s.month(),
|
|
'month-ordinal': (s) => ordinal(s.month()),
|
|
'month-pad': (s) => zeroPad(s.month()),
|
|
'iso-month': (s) => zeroPad(s.month() + 1), //1-based months
|
|
|
|
year: (s) => {
|
|
let year = s.year()
|
|
if (year > 0) {
|
|
return year
|
|
}
|
|
year = Math.abs(year)
|
|
return year + ' BC'
|
|
},
|
|
'year-short': (s) => {
|
|
let year = s.year()
|
|
if (year > 0) {
|
|
return `'${String(s.year()).substr(2, 4)}`
|
|
}
|
|
year = Math.abs(year)
|
|
return year + ' BC'
|
|
},
|
|
'iso-year': (s) => {
|
|
const year = s.year()
|
|
const isNegative = year < 0
|
|
let str = zeroPad(Math.abs(year), 4) //0-padded
|
|
if (isNegative) {
|
|
//negative years are for some reason 6-digits ('-00008')
|
|
str = zeroPad(str, 6)
|
|
str = '-' + str
|
|
}
|
|
return str
|
|
},
|
|
|
|
time: (s) => s.time(),
|
|
'time-24': (s) => `${s.hour24()}:${zeroPad(s.minute())}`,
|
|
|
|
hour: (s) => s.hour12(),
|
|
'hour-pad': (s) => zeroPad(s.hour12()),
|
|
'hour-24': (s) => s.hour24(),
|
|
'hour-24-pad': (s) => zeroPad(s.hour24()),
|
|
|
|
minute: (s) => s.minute(),
|
|
'minute-pad': (s) => zeroPad(s.minute()),
|
|
second: (s) => s.second(),
|
|
'second-pad': (s) => zeroPad(s.second()),
|
|
millisecond: (s) => s.millisecond(),
|
|
'millisecond-pad': (s) => zeroPad(s.millisecond(), 3),
|
|
|
|
ampm: (s) => s.ampm(),
|
|
AMPM: (s) => s.ampm().toUpperCase(),
|
|
quarter: (s) => 'Q' + s.quarter(),
|
|
season: (s) => s.season(),
|
|
era: (s) => s.era(),
|
|
json: (s) => s.json(),
|
|
timezone: (s) => s.timezone().name,
|
|
offset: (s) => isoOffset(s),
|
|
|
|
numeric: (s) => `${s.year()}/${zeroPad(s.month() + 1)}/${zeroPad(s.date())}`, // yyyy/mm/dd
|
|
'numeric-us': (s) => `${zeroPad(s.month() + 1)}/${zeroPad(s.date())}/${s.year()}`, // mm/dd/yyyy
|
|
'numeric-uk': (s) => `${zeroPad(s.date())}/${zeroPad(s.month() + 1)}/${s.year()}`, //dd/mm/yyyy
|
|
'mm/dd': (s) => `${zeroPad(s.month() + 1)}/${zeroPad(s.date())}`, //mm/dd
|
|
|
|
// ... https://en.wikipedia.org/wiki/ISO_8601 ;(((
|
|
iso: (s) => {
|
|
const year = s.format('iso-year')
|
|
const month = zeroPad(s.month() + 1) //1-based months
|
|
const date = zeroPad(s.date())
|
|
const hour = zeroPad(s.h24())
|
|
const minute = zeroPad(s.minute())
|
|
const second = zeroPad(s.second())
|
|
const ms = zeroPad(s.millisecond(), 3)
|
|
const offset = isoOffset(s)
|
|
return `${year}-${month}-${date}T${hour}:${minute}:${second}.${ms}${offset}` //2018-03-09T08:50:00.000-05:00
|
|
},
|
|
'iso-short': (s) => {
|
|
const month = zeroPad(s.month() + 1) //1-based months
|
|
const date = zeroPad(s.date())
|
|
const year = padYear(s.year())
|
|
return `${year}-${month}-${date}` //2017-02-15
|
|
},
|
|
'iso-utc': (s) => {
|
|
return new Date(s.epoch).toISOString() //2017-03-08T19:45:28.367Z
|
|
},
|
|
'iso-full': (s) => {
|
|
let iso = s.format('iso')
|
|
const iana = s.timezone().name
|
|
if (iana) {
|
|
iso += `[${iana}]`
|
|
}
|
|
return iso
|
|
},
|
|
|
|
sql: (s) => {
|
|
const year = s.format('iso-year')
|
|
const month = zeroPad(s.month() + 1) //1-based months
|
|
const date = zeroPad(s.date())
|
|
const hour = zeroPad(s.h24())
|
|
const minute = zeroPad(s.minute())
|
|
const second = zeroPad(s.second())
|
|
return `${year}-${month}-${date} ${hour}:${minute}:${second}` //2017-03-08 19:45:28
|
|
},
|
|
|
|
//i made these up
|
|
nice: (s) => `${short()[s.month()]} ${ordinal(s.date())}, ${s.time()}`,
|
|
'nice-24': (s) =>
|
|
`${short()[s.month()]} ${ordinal(s.date())}, ${s.hour24()}:${zeroPad(
|
|
s.minute()
|
|
)}`,
|
|
'nice-year': (s) => `${short()[s.month()]} ${ordinal(s.date())}, ${s.year()}`,
|
|
'nice-day': (s) =>
|
|
`${_short()[s.day()]} ${applyCaseFormat(short()[s.month()])} ${ordinal(
|
|
s.date()
|
|
)}`,
|
|
'nice-full': (s) =>
|
|
`${s.dayName()} ${applyCaseFormat(s.monthName())} ${ordinal(s.date())}, ${s.time()}`,
|
|
'nice-full-24': (s) =>
|
|
`${s.dayName()} ${applyCaseFormat(s.monthName())} ${ordinal(
|
|
s.date()
|
|
)}, ${s.hour24()}:${zeroPad(s.minute())}`
|
|
}
|
|
//aliases
|
|
const aliases = {
|
|
'day-name': 'day',
|
|
'month-name': 'month',
|
|
'iso 8601': 'iso',
|
|
'iso 9075': 'sql',
|
|
'time-h24': 'time-24',
|
|
'time-12': 'time',
|
|
'time-h12': 'time',
|
|
tz: 'timezone',
|
|
iana: 'timezone',
|
|
'day-num': 'day-number',
|
|
'month-num': 'month-number',
|
|
'month-iso': 'iso-month',
|
|
'year-iso': 'iso-year',
|
|
'nice-short': 'nice',
|
|
'nice-short-24': 'nice-24',
|
|
mdy: 'numeric-us',
|
|
dmy: 'numeric-uk',
|
|
ymd: 'numeric',
|
|
'yyyy/mm/dd': 'numeric',
|
|
'mm/dd/yyyy': 'numeric-us',
|
|
'dd/mm/yyyy': 'numeric-us',
|
|
'little-endian': 'numeric-uk',
|
|
'big-endian': 'numeric',
|
|
'day-nice': 'nice-day'
|
|
}
|
|
Object.keys(aliases).forEach((k) => (format[k] = format[aliases[k]]))
|
|
|
|
const printFormat = (s, str = '') => {
|
|
//don't print anything if it's an invalid date
|
|
if (s.isValid() !== true) {
|
|
return ''
|
|
}
|
|
//support .format('month')
|
|
if (format.hasOwnProperty(str)) {
|
|
let out = format[str](s) || ''
|
|
if (str !== 'json') {
|
|
out = String(out)
|
|
if (str.toLowerCase() !== 'ampm') {
|
|
out = applyCaseFormat(out)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
//support '{hour}:{minute}' notation
|
|
if (str.indexOf('{') !== -1) {
|
|
const sections = /\{(.+?)\}/g
|
|
str = str.replace(sections, (_, fmt) => {
|
|
fmt = fmt.trim()
|
|
if (fmt !== 'AMPM') {
|
|
fmt = fmt.toLowerCase()
|
|
}
|
|
if (format.hasOwnProperty(fmt)) {
|
|
const out = String(format[fmt](s))
|
|
if (fmt.toLowerCase() !== 'ampm') {
|
|
return applyCaseFormat(out)
|
|
}
|
|
return out
|
|
}
|
|
return ''
|
|
})
|
|
return str
|
|
}
|
|
|
|
return s.format('iso-short')
|
|
}
|
|
export default printFormat
|