Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

moment-parseformat

Package Overview
Dependencies
Maintainers
2
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

moment-parseformat - npm Package Compare versions

Comparing version 3.1.1 to 4.0.0

262

dist/moment-parseformat.js

@@ -17,4 +17,5 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.momentParseformat = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){

var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var timezoneNames = ['ACDT', 'ACST', 'ACWT', 'ADT', 'ACT', 'AEDT', 'AEST', 'AFT', 'AKDT', 'AKST', 'ALMT', 'AMT', 'AMST', 'ANAT', 'ANAST', 'AQTT', 'ART', 'AST', 'AWDT', 'AWST', 'AZOT', 'AZOST', 'AZT', 'AZST', 'BNT', 'BDT', 'BOT', 'BRT', 'BRST', 'BST', 'BTT', 'B', 'CAST', 'CAT', 'CCT', 'CDT', 'CEDT', 'CEST', 'CET', 'CHADT', 'CHAST', 'CHOT', 'CHOST', 'CHsT', 'CHUT', 'CIT', 'CKT', 'CLST', 'CLT', 'COT', 'CST', 'CVT', 'CWST', 'CXT', 'C', 'DAVT', 'DDUT', 'DST', 'EASST', 'EAST', 'EAT', 'ECT', 'EDT', 'EEDT', 'EEST', 'EET', 'EGT', 'EGST', 'EST', 'E', 'EIT', 'FET', 'FJT', 'FJST', 'FKST', 'FKT', 'FNT', 'F', 'GALT', 'GAMT', 'GET', 'GFT', 'GILT', 'GMT', 'GST', 'GYT', 'G', 'HADT', 'HAST', 'HKT', 'HOVT', 'HOVST', 'HST', 'ICT', 'IDT', 'IOT', 'IRDT', 'IRKT', 'IRKST', 'IRST', 'IST', 'JST', 'KGT', 'KOST', 'KRAT', 'KRAST', 'KST', 'KUYT', 'LHDT', 'LHST', 'LINT', 'L', 'MAGT', 'MAGST', 'MART', 'MAWT', 'MDT', 'MeST', 'MHT', 'MIST', 'MMT', 'MSD', 'MSK', 'MST', 'MUT', 'MVT', 'MYT', 'NCT', 'NDT', 'NFT', 'N', 'NOVT', 'NOVST', 'NPT', 'NRT', 'NST', 'NT', 'NUT', 'NZDT', 'NZST', 'OMST', 'OMSST', 'ORAT', 'O', 'PDT', 'PET', 'PETT', 'PETST', 'PGT', 'PHT', 'PHOT', 'PKT', 'PMDT', 'PMST', 'PONT', 'PST', 'PWT', 'PYT', 'PYST', 'P', 'QYZT', 'RET', 'ROTT', 'R', 'SAKT', 'SAMT', 'SAST', 'SBT', 'SCT', 'SGT', 'SRT', 'SLT', 'SLST', 'SRET', 'SST', 'SYOT', 'TAHT', 'TFT', 'TJT', 'TKT', 'TLT', 'TMT', 'TOT', 'TRUT', 'TVT', 'T', 'ULAT', 'ULAST', 'UTC', 'UYST', 'UYT', 'UZT', 'U', 'VET', 'VLAT', 'VLAST', 'VOLT', 'VUT', 'V', 'WAKT', 'WAT', 'WAST', 'WDT', 'WEDT', 'WEST', 'WET', 'WFT', 'WGT', 'WGST', 'WIB', 'WIT', 'WITA', 'WST', 'WT', 'YAKT', 'YAKST', 'YAP', 'YEK', 'YEKS']
var abbreviatedMonthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
var regexDayNames = new RegExp(dayNames.join('|'), 'i')

@@ -25,2 +26,3 @@ var regexAbbreviatedDayNames = new RegExp(abbreviatedDayNames.join('|'), 'i')

var regexAbbreviatedMonthNames = new RegExp(abbreviatedMonthNames.join('|'), 'i')
var regexTimezoneNames = new RegExp('\\b(' + timezoneNames.join('|') + ')\\b', 'i')

@@ -30,4 +32,4 @@ var regexFirstSecondThirdFourth = /(\d+)(st|nd|rd|th)\b/i

var regexTimezoneOneZ = /((\+|-)\d\d:\d\d)$/
var regexTimezoneTwoZ = /((\+|-)\d\d\d\d)$/
var regexTimezone = /((\+|-)(12:00|11:00|10:00|09:30|09:00|08:00|07:00|06:00|05:00|04:00|03:30|03:00|02:00|01:00|00:00|01:00|02:00|03:00|03:30|04:00|04:30|05:00|05:30|05:45|06:00|06:30|07:00|08:00|08:45|09:00|09:30|10:00|10:30|11:00|12:00|12:45|13:00|14:00))$/
var regexTimezoneNaked = /((\+|-)(1200|1100|1000|0930|0900|0800|0700|0600|0500|0400|0330|0300|0200|0100|0000|0100|0200|0300|0330|0400|0430|0500|0530|0545|0600|0630|0700|0800|0845|0900|0930|1000|1030|1100|1200|1245|1300|1400))$/

@@ -41,18 +43,37 @@ var amOrPm = '(' + ['AM?', 'PM?'].join('|') + ')'

var regexHoursAmPm = new RegExp('\\d{1,2}(\\s*)' + amOrPm, 'i')
var regexHours = new RegExp('\\d{1,2}')
var regexMonthNameYearShort = new RegExp(monthNames.join('|') + '-\\d{2}', 'i')
var regexMonthNameAbbreviatedYearShort = new RegExp(abbreviatedMonthNames.join('|') + '-\\d{2}', 'i')
// Various forms of (D|DD)<SEP>(MMM|MMMM)<SEP>('?YY|YYYY)
var regexDayMonthNameYear = new RegExp('(\\d{1,2})(\\D+)(' + monthNames.join('|') + '|' + abbreviatedMonthNames.join('|') + ')(\\2)(\'?\\d{2,4})')
var regexISO8601HoursWithLeadingZeroMinutesSecondsMilliseconds = /\d{2}:\d{2}:\d{2}\.\d{3}/
var regexISO8601HoursWithLeadingZeroMinutesSecondsCentiSeconds = /\d{2}:\d{2}:\d{2}\.\d{2}/
var regexISO8601HoursWithLeadingZeroMinutesSecondsDeciSeconds = /\d{2}:\d{2}:\d{2}\.\d{1}/
var regexISO8601HoursWithLeadingZeroMinutesSeconds = /T\d{2}:\d{2}:\d{2}/ // Weird test case - format don't usually come like this, but one of ours does.
var regexHoursWithLeadingZeroMinutesSeconds = /0\d:\d{2}:\d{2}/
var regexHoursWithLeadingZeroMinutes = /0\d:\d{2}/
var regexHoursMinutesSeconds = /\d{1,2}:\d{2}:\d{2}/
var regexHoursMinutesSecondsMilliseconds = /\d{1,2}:\d{2}:\d{2}\.\d{3}/
var regexHoursMinutesSecondsCentiSeconds = /\d{1,2}:\d{2}:\d{2}\.\d{2}/
var regexHoursMinutesSecondsDeciSeconds = /\d{1,2}:\d{2}:\d{2}\.\d{1}/
var regexHoursMinutes = /\d{1,2}:\d{2}/
var regexHoursMinutesSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}/
var regexHoursMinutesSecondsMilliseconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{3}/
var regexHoursMinutesSecondsCentiSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{2}/
var regexHoursMinutesSecondsDeciSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{1}/
var regexHoursMinutes = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]/
var regexExtended24HoursMinutesSeconds = /24:00:\d{2}/
var regexExtended24HoursMinutesSecondsMilliseconds = /24:00:\d{2}\.\d{3}/
var regexExtended24HoursMinutesSecondsCentiSeconds = /24:00:\d{2}\.\d{2}/
var regexExtended24HoursMinutesSecondsDeciSeconds = /24:00:\d{2}\.\d{1}/
var regexExtended24HoursMinutes = /24:00/
var regexYearLong = /\d{4}/
var regexYearShort = /\d{2}/
var regexYearShortApostrophe = /'\d{2}/
var regexDayLeadingZero = /0\d/
var regexDay = /\d{1,2}/
var regexYearShort = /\d{2}/
var regexMonthLeadingZero = /0\d/
var regexMonth = /\d{1,2}/
var regexDayShortMonthShort = /^([1-9])\/([1-9]|0[1-9])$/

@@ -63,7 +84,18 @@ var regexDayShortMonth = /^([1-9])\/(1[012])$/

var regexMonthShortYearShort = /^([1-9])\/([1-9][0-9])$/
var regexMonthYearShort = /^(0[1-9]|1[012])\/([1-9][0-9])$/
var regexMonthShortYearShort = /^([1-9])(\D)([1-9][0-9])$/
var regexMonthShortDay = /^([1-9])(\D)([0][0-9])$/
var regexMonthYearShort = /^(0[1-9]|1[012])(\D)([1-9][0-9])$/
var regexMonthDay = /^(0[1-9]|1[012])(\D)([0][0-9])$/
var formatIncludesMonth = /([/][M]|[M][/]|[MM]|[MMMM])/
var formatIncludesNumericDay = /(D)/
var formatIncludesYear = /(Y)/
var formatHasMultipleRemainingSegments = /\d+\D.+$/
var formatOnlyHasTerminatingNumbers = /\D+(\d+)($|Z)/
var formatHasDayAfterMonthSegment = /M\s*\d{1,2}\b.+$/
var formatHasDayWithLeadingZeroAfterMonthSegment = /M\D+(0[1-9])\b.+$/
var formatHasTimeAfterRemainingDigits = /\d+\s+(H|h|k)/
var regexFillingWords = /\b(at)\b/i

@@ -86,2 +118,3 @@

options = options || {}
options.preferredOrder = options.preferredOrder || defaultOrder

@@ -97,2 +130,38 @@

if (format.match(regexDayMonthNameYear)) {
const [, daySegment, sep1, monthSegment, sep2, yearSegment] = format.match(regexDayMonthNameYear)
const parts = []
// Handle Day segment
if ((daySegment.length === 2 && daySegment[0] === '0') || options.preferLongFormat) {
parts.push('DD')
} else {
parts.push('D')
}
// Handle day/month seperator
parts.push(sep1)
// Handle Month segment
if (monthSegment.match(monthNames)) {
parts.push('MMMM')
} else if (monthSegment.match(abbreviatedMonthNames)) {
parts.push('MMM')
} else {
parts.push(monthSegment)
}
// Handle month/year seperator
parts.push(sep2)
// Handle year segment
if (yearSegment[0] === "'") {
parts.push("'YY")
} else if (yearSegment.length === 2) {
parts.push('YY')
} else if (yearSegment.length === 4) {
parts.push('YYYY')
} else {
parts.push('YYYY')
}
var dayMonthNameYearFormat = parts.join('')
format = format.replace(regexDayMonthNameYear, dayMonthNameYearFormat)
}
// DAYS

@@ -120,6 +189,10 @@

// timezone name GMT ☛ [GMT]
format = format.replace(regexTimezoneNames, a => '[' + a + ']')
// timezone +02:00 ☛ Z
format = format.replace(regexTimezone, 'Z')
// timezone 0200 ☛ Z
format = format.replace(regexTimezoneNaked, 'ZZ')
// TIME
// timezone +02:00 ☛ Z, timezone +0200 ☛ ZZ
format = regexTimezoneOneZ.test(format) ? format.replace(regexTimezoneOneZ, 'Z') : format.replace(regexTimezoneTwoZ, 'ZZ')
// 23:39:43.331 ☛ 'HH:mm:ss.SSS'

@@ -131,2 +204,4 @@ format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSecondsMilliseconds, 'HH:mm:ss.SSS')

format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSecondsDeciSeconds, 'HH:mm:ss.S')
// 23:39:43 ☛ 'HH:mm:ss'
format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSeconds, 'THH:mm:ss')
function replaceWithAmPm (timeFormat) {

@@ -153,8 +228,16 @@ return function (match, whitespace, amPm) {

format = format.replace(regexHoursMinutesSecondsMilliseconds, 'H:mm:ss.SSS')
// 24:00:00.000 ☛ k:mm:ss.SSS|kk:mm:ss.SSS
format = format.replace(regexExtended24HoursMinutesSecondsMilliseconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.SSS')
// 5:30:20.22 ☛ H:mm:ss.SS
format = format.replace(regexHoursMinutesSecondsCentiSeconds, 'H:mm:ss.SS')
// 24:00:00.00 ☛ k:mm:ss.SS|kk:mm:ss.SS
format = format.replace(regexExtended24HoursMinutesSecondsCentiSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.SS')
// 5:30:20.2 ☛ H:mm:ss.S
format = format.replace(regexHoursMinutesSecondsDeciSeconds, 'H:mm:ss.S')
// 24:00:00.0 ☛ k:mm:ss.S|kk:mm:ss.S
format = format.replace(regexExtended24HoursMinutesSecondsDeciSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.S')
// 10:30:20 ☛ H:mm:ss
format = format.replace(regexHoursMinutesSeconds, 'H:mm:ss')
// 24:00:00 ☛ k:mm:ss||kk:mm:ss
format = format.replace(regexExtended24HoursMinutesSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss')
// 05:30 ☛ H:mm

@@ -164,8 +247,17 @@ format = format.replace(regexHoursWithLeadingZeroMinutes, 'HH:mm')

format = format.replace(regexHoursMinutes, 'H:mm')
// 24:00 ☛ k:mm|kk:mm
format = format.replace(regexExtended24HoursMinutes, (options.preferLongFormat ? 'kk' : 'k') + ':mm')
// do we still have numbers left?
//
//
// Lets check for 4 digits first, these are years for sure
format = format.replace(regexYearLong, 'YYYY')
format = format.replace(regexYearShortApostrophe, '\'YY')
// Check for (MMM|MMMM)-(YY|YYYY) formats
format = format.replace(regexMonthNameYearShort, 'MMMM-YY')
format = format.replace(regexMonthNameAbbreviatedYearShort, 'MMM-YY')
// check if both numbers are < 13, then it must be D/M

@@ -184,11 +276,17 @@ format = format.replace(regexDayShortMonthShort, 'D/M')

// check if first < 10 && last > 12, then it must be M/YY
format = format.replace(regexMonthShortYearShort, 'M/YY')
format = format.replace(regexMonthShortYearShort, 'M$2YY')
// check if first < 13 && last > 12, then it must be MM/YY
format = format.replace(regexMonthYearShort, 'MM/YY')
format = format.replace(regexMonthYearShort, 'MM$2YY')
//
// check if first < 10 && last < 10, then it must be M/DD
format = format.replace(regexMonthShortDay, 'M$2DD')
// check if first < 13 && last < 10, then it must be MM/DD
format = format.replace(regexMonthDay, 'MM$2DD')
// to prevent 9.20 gets formated to D.Y, we format the complete date first, then go for the time
if (format.match(formatIncludesMonth)) {
var regexHoursDotWithLeadingZeroOrDoubleDigitMinutes = /0\d.\d{2}|\d{2}.\d{2}/
var regexHoursDotMinutes = /\d{1}.\d{2}/
var regexHoursDotWithLeadingZeroOrDoubleDigitMinutes = /0\d\.\d{2}|\d{2}\.\d{2}/
var regexHoursDotMinutes = /\d{1}\.\d{2}/

@@ -199,9 +297,50 @@ format = format.replace(regexHoursDotWithLeadingZeroOrDoubleDigitMinutes, 'H.mm')

// now, the next number, if existing, must be a day
format = format.replace(regexDayLeadingZero, 'DD')
format = format.replace(regexDay, 'D')
// If the format includes a year format segment, but no month segment, then those numbers are a month
// last but not least, there could still be a year left
format = format.replace(regexYearShort, 'YY')
if (!format.match(formatIncludesMonth) && format.match(formatIncludesYear)) {
format = format.replace(regexMonthLeadingZero, 'MM')
}
if (!format.match(formatIncludesMonth) && format.match(formatIncludesYear)) {
format = format.replace(regexMonth, options.preferLongFormat ? 'MM' : 'M')
}
// Check for some odd cases, such as MMMM <some number that is a DAY> <more of the format>
if (format.match(formatHasDayWithLeadingZeroAfterMonthSegment) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDayLeadingZero, 'DD')
}
if (format.match(formatHasDayAfterMonthSegment) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDay, options.preferLongFormat ? 'DD' : 'D')
}
// now, the next number, if existing, must be a day IF it is the last set of numbers in the format
if (!format.match(formatIncludesNumericDay) && format.match(formatHasMultipleRemainingSegments) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDayLeadingZero, 'DD')
}
if (!format.match(formatIncludesNumericDay) && format.match(formatHasMultipleRemainingSegments) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDay, options.preferLongFormat ? 'DD' : 'D')
}
// there could still be a year left
if (!format.match(formatIncludesYear)) {
format = format.replace(regexYearShort, 'YY')
}
// if there are still numbers, it might be an odd naked hour that wasn't picked up earlier by the time checks
if (format.match(formatOnlyHasTerminatingNumbers)) {
var hour = format.match(formatOnlyHasTerminatingNumbers)[1]
var replacement
if (hour === '00') {
replacement = 'HH'
} else if (hour === '24') {
replacement = options.preferLongFormat ? 'kk' : 'k'
} else if (hour > 12) {
replacement = options.preferLongFormat ? 'HH' : 'H'
} else if (hour[0] === '0') {
replacement = options.preferLongFormat ? 'hh' : 'h'
} else {
replacement = options.preferLongFormat ? 'hh' : 'k'
}
format = format.replace(regexHours, replacement)
}
if (format.length < 1) {

@@ -219,4 +358,23 @@ format = undefined

var parts
var hasSingleDigit = Math.min(first.length, second.length, third.length) === 1
var hasQuadDigit = Math.max(first.length, second.length, third.length) === 4
var FIRST = 0
var SECOND = 1
var THIRD = 2
var isSingleDigitMap = [
first.length === 1,
second.length === 1,
third.length === 1
]
var startsWithZeroMap = [
first[0] === '0',
second[0] === '0',
third[0] === '0'
]
var firstHasQuadDigit = first.length === 4
var secondHasQuadDigit = second.length === 4
var thirdHasQuadDigit = third.length === 4
var preferredOrder = typeof options.preferredOrder === 'string' ? options.preferredOrder : options.preferredOrder[separator]

@@ -230,16 +388,36 @@

var inferSingleDigitStatus = function (a, b) {
if (isSingleDigitMap[a] !== isSingleDigitMap[b]) {
if (!startsWithZeroMap[a] && !startsWithZeroMap[b]) {
isSingleDigitMap[a] = true
isSingleDigitMap[b] = true
}
}
}
// If first is a year, order will always be Year-Month-Day
if (first > 31) {
parts[0] = hasQuadDigit ? 'YYYY' : 'YY'
parts[1] = hasSingleDigit ? 'M' : 'MM'
parts[2] = hasSingleDigit ? 'D' : 'DD'
inferSingleDigitStatus(SECOND, THIRD)
parts[0] = firstHasQuadDigit ? 'YYYY' : 'YY'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
parts[2] = isSingleDigitMap[THIRD] ? 'D' : 'DD'
return parts.join(separator)
}
// If first is a month, then the order will be Day-Month-Year
if (first > 12) {
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'D' : 'DD'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'
return parts.join(separator)
}
// Second will never be the year. And if it is a day,
// the order will always be Month-Day-Year
if (second > 12) {
parts[0] = hasSingleDigit ? 'M' : 'MM'
parts[1] = hasSingleDigit ? 'D' : 'DD'
parts[2] = hasQuadDigit ? 'YYYY' : 'YY'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'M' : 'MM'
parts[1] = isSingleDigitMap[SECOND] ? 'D' : 'DD'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'
return parts.join(separator)

@@ -250,3 +428,3 @@ }

if (third > 31) {
parts[2] = hasQuadDigit ? 'YYYY' : 'YY'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'

@@ -256,16 +434,22 @@ // ... try to find day in first and second.

if (preferredOrder[0] === 'M' && first < 13) {
parts[0] = hasSingleDigit ? 'M' : 'MM'
parts[1] = hasSingleDigit ? 'D' : 'DD'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'M' : 'MM'
parts[1] = isSingleDigitMap[SECOND] ? 'D' : 'DD'
return parts.join(separator)
}
parts[0] = hasSingleDigit ? 'D' : 'DD'
parts[1] = hasSingleDigit ? 'M' : 'MM'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'D' : 'DD'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
return parts.join(separator)
}
const hasQuadDigit = [firstHasQuadDigit, secondHasQuadDigit, thirdHasQuadDigit]
// if we had no luck until here, we use the preferred order
parts[preferredOrder.indexOf('D')] = hasSingleDigit ? 'D' : 'DD'
parts[preferredOrder.indexOf('M')] = hasSingleDigit ? 'M' : 'MM'
parts[preferredOrder.indexOf('Y')] = hasQuadDigit ? 'YYYY' : 'YY'
inferSingleDigitStatus(preferredOrder.indexOf('D'), preferredOrder.indexOf('M'))
parts[preferredOrder.indexOf('D')] = isSingleDigitMap[preferredOrder.indexOf('D')] ? 'D' : 'DD'
parts[preferredOrder.indexOf('M')] = isSingleDigitMap[preferredOrder.indexOf('M')] ? 'M' : 'MM'
parts[preferredOrder.indexOf('Y')] = hasQuadDigit[preferredOrder.indexOf('Y')] ? 'YYYY' : 'YY'
return parts.join(separator)

@@ -272,0 +456,0 @@ }

@@ -7,4 +7,5 @@ module.exports = parseFormat

var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var timezoneNames = ['ACDT', 'ACST', 'ACWT', 'ADT', 'ACT', 'AEDT', 'AEST', 'AFT', 'AKDT', 'AKST', 'ALMT', 'AMT', 'AMST', 'ANAT', 'ANAST', 'AQTT', 'ART', 'AST', 'AWDT', 'AWST', 'AZOT', 'AZOST', 'AZT', 'AZST', 'BNT', 'BDT', 'BOT', 'BRT', 'BRST', 'BST', 'BTT', 'B', 'CAST', 'CAT', 'CCT', 'CDT', 'CEDT', 'CEST', 'CET', 'CHADT', 'CHAST', 'CHOT', 'CHOST', 'CHsT', 'CHUT', 'CIT', 'CKT', 'CLST', 'CLT', 'COT', 'CST', 'CVT', 'CWST', 'CXT', 'C', 'DAVT', 'DDUT', 'DST', 'EASST', 'EAST', 'EAT', 'ECT', 'EDT', 'EEDT', 'EEST', 'EET', 'EGT', 'EGST', 'EST', 'E', 'EIT', 'FET', 'FJT', 'FJST', 'FKST', 'FKT', 'FNT', 'F', 'GALT', 'GAMT', 'GET', 'GFT', 'GILT', 'GMT', 'GST', 'GYT', 'G', 'HADT', 'HAST', 'HKT', 'HOVT', 'HOVST', 'HST', 'ICT', 'IDT', 'IOT', 'IRDT', 'IRKT', 'IRKST', 'IRST', 'IST', 'JST', 'KGT', 'KOST', 'KRAT', 'KRAST', 'KST', 'KUYT', 'LHDT', 'LHST', 'LINT', 'L', 'MAGT', 'MAGST', 'MART', 'MAWT', 'MDT', 'MeST', 'MHT', 'MIST', 'MMT', 'MSD', 'MSK', 'MST', 'MUT', 'MVT', 'MYT', 'NCT', 'NDT', 'NFT', 'N', 'NOVT', 'NOVST', 'NPT', 'NRT', 'NST', 'NT', 'NUT', 'NZDT', 'NZST', 'OMST', 'OMSST', 'ORAT', 'O', 'PDT', 'PET', 'PETT', 'PETST', 'PGT', 'PHT', 'PHOT', 'PKT', 'PMDT', 'PMST', 'PONT', 'PST', 'PWT', 'PYT', 'PYST', 'P', 'QYZT', 'RET', 'ROTT', 'R', 'SAKT', 'SAMT', 'SAST', 'SBT', 'SCT', 'SGT', 'SRT', 'SLT', 'SLST', 'SRET', 'SST', 'SYOT', 'TAHT', 'TFT', 'TJT', 'TKT', 'TLT', 'TMT', 'TOT', 'TRUT', 'TVT', 'T', 'ULAT', 'ULAST', 'UTC', 'UYST', 'UYT', 'UZT', 'U', 'VET', 'VLAT', 'VLAST', 'VOLT', 'VUT', 'V', 'WAKT', 'WAT', 'WAST', 'WDT', 'WEDT', 'WEST', 'WET', 'WFT', 'WGT', 'WGST', 'WIB', 'WIT', 'WITA', 'WST', 'WT', 'YAKT', 'YAKST', 'YAP', 'YEK', 'YEKS']
var abbreviatedMonthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
var regexDayNames = new RegExp(dayNames.join('|'), 'i')

@@ -15,2 +16,3 @@ var regexAbbreviatedDayNames = new RegExp(abbreviatedDayNames.join('|'), 'i')

var regexAbbreviatedMonthNames = new RegExp(abbreviatedMonthNames.join('|'), 'i')
var regexTimezoneNames = new RegExp('\\b(' + timezoneNames.join('|') + ')\\b', 'i')

@@ -20,4 +22,4 @@ var regexFirstSecondThirdFourth = /(\d+)(st|nd|rd|th)\b/i

var regexTimezoneOneZ = /((\+|-)\d\d:\d\d)$/
var regexTimezoneTwoZ = /((\+|-)\d\d\d\d)$/
var regexTimezone = /((\+|-)(12:00|11:00|10:00|09:30|09:00|08:00|07:00|06:00|05:00|04:00|03:30|03:00|02:00|01:00|00:00|01:00|02:00|03:00|03:30|04:00|04:30|05:00|05:30|05:45|06:00|06:30|07:00|08:00|08:45|09:00|09:30|10:00|10:30|11:00|12:00|12:45|13:00|14:00))$/
var regexTimezoneNaked = /((\+|-)(1200|1100|1000|0930|0900|0800|0700|0600|0500|0400|0330|0300|0200|0100|0000|0100|0200|0300|0330|0400|0430|0500|0530|0545|0600|0630|0700|0800|0845|0900|0930|1000|1030|1100|1200|1245|1300|1400))$/

@@ -31,18 +33,37 @@ var amOrPm = '(' + ['AM?', 'PM?'].join('|') + ')'

var regexHoursAmPm = new RegExp('\\d{1,2}(\\s*)' + amOrPm, 'i')
var regexHours = new RegExp('\\d{1,2}')
var regexMonthNameYearShort = new RegExp(monthNames.join('|') + '-\\d{2}', 'i')
var regexMonthNameAbbreviatedYearShort = new RegExp(abbreviatedMonthNames.join('|') + '-\\d{2}', 'i')
// Various forms of (D|DD)<SEP>(MMM|MMMM)<SEP>('?YY|YYYY)
var regexDayMonthNameYear = new RegExp('(\\d{1,2})(\\D+)(' + monthNames.join('|') + '|' + abbreviatedMonthNames.join('|') + ')(\\2)(\'?\\d{2,4})')
var regexISO8601HoursWithLeadingZeroMinutesSecondsMilliseconds = /\d{2}:\d{2}:\d{2}\.\d{3}/
var regexISO8601HoursWithLeadingZeroMinutesSecondsCentiSeconds = /\d{2}:\d{2}:\d{2}\.\d{2}/
var regexISO8601HoursWithLeadingZeroMinutesSecondsDeciSeconds = /\d{2}:\d{2}:\d{2}\.\d{1}/
var regexISO8601HoursWithLeadingZeroMinutesSeconds = /T\d{2}:\d{2}:\d{2}/ // Weird test case - format don't usually come like this, but one of ours does.
var regexHoursWithLeadingZeroMinutesSeconds = /0\d:\d{2}:\d{2}/
var regexHoursWithLeadingZeroMinutes = /0\d:\d{2}/
var regexHoursMinutesSeconds = /\d{1,2}:\d{2}:\d{2}/
var regexHoursMinutesSecondsMilliseconds = /\d{1,2}:\d{2}:\d{2}\.\d{3}/
var regexHoursMinutesSecondsCentiSeconds = /\d{1,2}:\d{2}:\d{2}\.\d{2}/
var regexHoursMinutesSecondsDeciSeconds = /\d{1,2}:\d{2}:\d{2}\.\d{1}/
var regexHoursMinutes = /\d{1,2}:\d{2}/
var regexHoursMinutesSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}/
var regexHoursMinutesSecondsMilliseconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{3}/
var regexHoursMinutesSecondsCentiSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{2}/
var regexHoursMinutesSecondsDeciSeconds = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]:\d{2}\.\d{1}/
var regexHoursMinutes = /\b([01]?[0-9]|2[0-3]):[0-5][0-9]/
var regexExtended24HoursMinutesSeconds = /24:00:\d{2}/
var regexExtended24HoursMinutesSecondsMilliseconds = /24:00:\d{2}\.\d{3}/
var regexExtended24HoursMinutesSecondsCentiSeconds = /24:00:\d{2}\.\d{2}/
var regexExtended24HoursMinutesSecondsDeciSeconds = /24:00:\d{2}\.\d{1}/
var regexExtended24HoursMinutes = /24:00/
var regexYearLong = /\d{4}/
var regexYearShort = /\d{2}/
var regexYearShortApostrophe = /'\d{2}/
var regexDayLeadingZero = /0\d/
var regexDay = /\d{1,2}/
var regexYearShort = /\d{2}/
var regexMonthLeadingZero = /0\d/
var regexMonth = /\d{1,2}/
var regexDayShortMonthShort = /^([1-9])\/([1-9]|0[1-9])$/

@@ -53,7 +74,18 @@ var regexDayShortMonth = /^([1-9])\/(1[012])$/

var regexMonthShortYearShort = /^([1-9])\/([1-9][0-9])$/
var regexMonthYearShort = /^(0[1-9]|1[012])\/([1-9][0-9])$/
var regexMonthShortYearShort = /^([1-9])(\D)([1-9][0-9])$/
var regexMonthShortDay = /^([1-9])(\D)([0][0-9])$/
var regexMonthYearShort = /^(0[1-9]|1[012])(\D)([1-9][0-9])$/
var regexMonthDay = /^(0[1-9]|1[012])(\D)([0][0-9])$/
var formatIncludesMonth = /([/][M]|[M][/]|[MM]|[MMMM])/
var formatIncludesNumericDay = /(D)/
var formatIncludesYear = /(Y)/
var formatHasMultipleRemainingSegments = /\d+\D.+$/
var formatOnlyHasTerminatingNumbers = /\D+(\d+)($|Z)/
var formatHasDayAfterMonthSegment = /M\s*\d{1,2}\b.+$/
var formatHasDayWithLeadingZeroAfterMonthSegment = /M\D+(0[1-9])\b.+$/
var formatHasTimeAfterRemainingDigits = /\d+\s+(H|h|k)/
var regexFillingWords = /\b(at)\b/i

@@ -76,2 +108,3 @@

options = options || {}
options.preferredOrder = options.preferredOrder || defaultOrder

@@ -87,2 +120,38 @@

if (format.match(regexDayMonthNameYear)) {
const [, daySegment, sep1, monthSegment, sep2, yearSegment] = format.match(regexDayMonthNameYear)
const parts = []
// Handle Day segment
if ((daySegment.length === 2 && daySegment[0] === '0') || options.preferLongFormat) {
parts.push('DD')
} else {
parts.push('D')
}
// Handle day/month seperator
parts.push(sep1)
// Handle Month segment
if (monthSegment.match(monthNames)) {
parts.push('MMMM')
} else if (monthSegment.match(abbreviatedMonthNames)) {
parts.push('MMM')
} else {
parts.push(monthSegment)
}
// Handle month/year seperator
parts.push(sep2)
// Handle year segment
if (yearSegment[0] === "'") {
parts.push("'YY")
} else if (yearSegment.length === 2) {
parts.push('YY')
} else if (yearSegment.length === 4) {
parts.push('YYYY')
} else {
parts.push('YYYY')
}
var dayMonthNameYearFormat = parts.join('')
format = format.replace(regexDayMonthNameYear, dayMonthNameYearFormat)
}
// DAYS

@@ -110,6 +179,10 @@

// timezone name GMT ☛ [GMT]
format = format.replace(regexTimezoneNames, a => '[' + a + ']')
// timezone +02:00 ☛ Z
format = format.replace(regexTimezone, 'Z')
// timezone 0200 ☛ Z
format = format.replace(regexTimezoneNaked, 'ZZ')
// TIME
// timezone +02:00 ☛ Z, timezone +0200 ☛ ZZ
format = regexTimezoneOneZ.test(format) ? format.replace(regexTimezoneOneZ, 'Z') : format.replace(regexTimezoneTwoZ, 'ZZ')
// 23:39:43.331 ☛ 'HH:mm:ss.SSS'

@@ -121,2 +194,4 @@ format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSecondsMilliseconds, 'HH:mm:ss.SSS')

format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSecondsDeciSeconds, 'HH:mm:ss.S')
// 23:39:43 ☛ 'HH:mm:ss'
format = format.replace(regexISO8601HoursWithLeadingZeroMinutesSeconds, 'THH:mm:ss')
function replaceWithAmPm (timeFormat) {

@@ -143,8 +218,16 @@ return function (match, whitespace, amPm) {

format = format.replace(regexHoursMinutesSecondsMilliseconds, 'H:mm:ss.SSS')
// 24:00:00.000 ☛ k:mm:ss.SSS|kk:mm:ss.SSS
format = format.replace(regexExtended24HoursMinutesSecondsMilliseconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.SSS')
// 5:30:20.22 ☛ H:mm:ss.SS
format = format.replace(regexHoursMinutesSecondsCentiSeconds, 'H:mm:ss.SS')
// 24:00:00.00 ☛ k:mm:ss.SS|kk:mm:ss.SS
format = format.replace(regexExtended24HoursMinutesSecondsCentiSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.SS')
// 5:30:20.2 ☛ H:mm:ss.S
format = format.replace(regexHoursMinutesSecondsDeciSeconds, 'H:mm:ss.S')
// 24:00:00.0 ☛ k:mm:ss.S|kk:mm:ss.S
format = format.replace(regexExtended24HoursMinutesSecondsDeciSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss.S')
// 10:30:20 ☛ H:mm:ss
format = format.replace(regexHoursMinutesSeconds, 'H:mm:ss')
// 24:00:00 ☛ k:mm:ss||kk:mm:ss
format = format.replace(regexExtended24HoursMinutesSeconds, (options.preferLongFormat ? 'kk' : 'k') + ':mm:ss')
// 05:30 ☛ H:mm

@@ -154,8 +237,17 @@ format = format.replace(regexHoursWithLeadingZeroMinutes, 'HH:mm')

format = format.replace(regexHoursMinutes, 'H:mm')
// 24:00 ☛ k:mm|kk:mm
format = format.replace(regexExtended24HoursMinutes, (options.preferLongFormat ? 'kk' : 'k') + ':mm')
// do we still have numbers left?
//
//
// Lets check for 4 digits first, these are years for sure
format = format.replace(regexYearLong, 'YYYY')
format = format.replace(regexYearShortApostrophe, '\'YY')
// Check for (MMM|MMMM)-(YY|YYYY) formats
format = format.replace(regexMonthNameYearShort, 'MMMM-YY')
format = format.replace(regexMonthNameAbbreviatedYearShort, 'MMM-YY')
// check if both numbers are < 13, then it must be D/M

@@ -174,11 +266,17 @@ format = format.replace(regexDayShortMonthShort, 'D/M')

// check if first < 10 && last > 12, then it must be M/YY
format = format.replace(regexMonthShortYearShort, 'M/YY')
format = format.replace(regexMonthShortYearShort, 'M$2YY')
// check if first < 13 && last > 12, then it must be MM/YY
format = format.replace(regexMonthYearShort, 'MM/YY')
format = format.replace(regexMonthYearShort, 'MM$2YY')
//
// check if first < 10 && last < 10, then it must be M/DD
format = format.replace(regexMonthShortDay, 'M$2DD')
// check if first < 13 && last < 10, then it must be MM/DD
format = format.replace(regexMonthDay, 'MM$2DD')
// to prevent 9.20 gets formated to D.Y, we format the complete date first, then go for the time
if (format.match(formatIncludesMonth)) {
var regexHoursDotWithLeadingZeroOrDoubleDigitMinutes = /0\d.\d{2}|\d{2}.\d{2}/
var regexHoursDotMinutes = /\d{1}.\d{2}/
var regexHoursDotWithLeadingZeroOrDoubleDigitMinutes = /0\d\.\d{2}|\d{2}\.\d{2}/
var regexHoursDotMinutes = /\d{1}\.\d{2}/

@@ -189,9 +287,50 @@ format = format.replace(regexHoursDotWithLeadingZeroOrDoubleDigitMinutes, 'H.mm')

// now, the next number, if existing, must be a day
format = format.replace(regexDayLeadingZero, 'DD')
format = format.replace(regexDay, 'D')
// If the format includes a year format segment, but no month segment, then those numbers are a month
// last but not least, there could still be a year left
format = format.replace(regexYearShort, 'YY')
if (!format.match(formatIncludesMonth) && format.match(formatIncludesYear)) {
format = format.replace(regexMonthLeadingZero, 'MM')
}
if (!format.match(formatIncludesMonth) && format.match(formatIncludesYear)) {
format = format.replace(regexMonth, options.preferLongFormat ? 'MM' : 'M')
}
// Check for some odd cases, such as MMMM <some number that is a DAY> <more of the format>
if (format.match(formatHasDayWithLeadingZeroAfterMonthSegment) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDayLeadingZero, 'DD')
}
if (format.match(formatHasDayAfterMonthSegment) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDay, options.preferLongFormat ? 'DD' : 'D')
}
// now, the next number, if existing, must be a day IF it is the last set of numbers in the format
if (!format.match(formatIncludesNumericDay) && format.match(formatHasMultipleRemainingSegments) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDayLeadingZero, 'DD')
}
if (!format.match(formatIncludesNumericDay) && format.match(formatHasMultipleRemainingSegments) && !format.match(formatHasTimeAfterRemainingDigits)) {
format = format.replace(regexDay, options.preferLongFormat ? 'DD' : 'D')
}
// there could still be a year left
if (!format.match(formatIncludesYear)) {
format = format.replace(regexYearShort, 'YY')
}
// if there are still numbers, it might be an odd naked hour that wasn't picked up earlier by the time checks
if (format.match(formatOnlyHasTerminatingNumbers)) {
var hour = format.match(formatOnlyHasTerminatingNumbers)[1]
var replacement
if (hour === '00') {
replacement = 'HH'
} else if (hour === '24') {
replacement = options.preferLongFormat ? 'kk' : 'k'
} else if (hour > 12) {
replacement = options.preferLongFormat ? 'HH' : 'H'
} else if (hour[0] === '0') {
replacement = options.preferLongFormat ? 'hh' : 'h'
} else {
replacement = options.preferLongFormat ? 'hh' : 'k'
}
format = format.replace(regexHours, replacement)
}
if (format.length < 1) {

@@ -209,4 +348,23 @@ format = undefined

var parts
var hasSingleDigit = Math.min(first.length, second.length, third.length) === 1
var hasQuadDigit = Math.max(first.length, second.length, third.length) === 4
var FIRST = 0
var SECOND = 1
var THIRD = 2
var isSingleDigitMap = [
first.length === 1,
second.length === 1,
third.length === 1
]
var startsWithZeroMap = [
first[0] === '0',
second[0] === '0',
third[0] === '0'
]
var firstHasQuadDigit = first.length === 4
var secondHasQuadDigit = second.length === 4
var thirdHasQuadDigit = third.length === 4
var preferredOrder = typeof options.preferredOrder === 'string' ? options.preferredOrder : options.preferredOrder[separator]

@@ -220,16 +378,36 @@

var inferSingleDigitStatus = function (a, b) {
if (isSingleDigitMap[a] !== isSingleDigitMap[b]) {
if (!startsWithZeroMap[a] && !startsWithZeroMap[b]) {
isSingleDigitMap[a] = true
isSingleDigitMap[b] = true
}
}
}
// If first is a year, order will always be Year-Month-Day
if (first > 31) {
parts[0] = hasQuadDigit ? 'YYYY' : 'YY'
parts[1] = hasSingleDigit ? 'M' : 'MM'
parts[2] = hasSingleDigit ? 'D' : 'DD'
inferSingleDigitStatus(SECOND, THIRD)
parts[0] = firstHasQuadDigit ? 'YYYY' : 'YY'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
parts[2] = isSingleDigitMap[THIRD] ? 'D' : 'DD'
return parts.join(separator)
}
// If first is a month, then the order will be Day-Month-Year
if (first > 12) {
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'D' : 'DD'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'
return parts.join(separator)
}
// Second will never be the year. And if it is a day,
// the order will always be Month-Day-Year
if (second > 12) {
parts[0] = hasSingleDigit ? 'M' : 'MM'
parts[1] = hasSingleDigit ? 'D' : 'DD'
parts[2] = hasQuadDigit ? 'YYYY' : 'YY'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'M' : 'MM'
parts[1] = isSingleDigitMap[SECOND] ? 'D' : 'DD'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'
return parts.join(separator)

@@ -240,3 +418,3 @@ }

if (third > 31) {
parts[2] = hasQuadDigit ? 'YYYY' : 'YY'
parts[2] = thirdHasQuadDigit ? 'YYYY' : 'YY'

@@ -246,17 +424,23 @@ // ... try to find day in first and second.

if (preferredOrder[0] === 'M' && first < 13) {
parts[0] = hasSingleDigit ? 'M' : 'MM'
parts[1] = hasSingleDigit ? 'D' : 'DD'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'M' : 'MM'
parts[1] = isSingleDigitMap[SECOND] ? 'D' : 'DD'
return parts.join(separator)
}
parts[0] = hasSingleDigit ? 'D' : 'DD'
parts[1] = hasSingleDigit ? 'M' : 'MM'
inferSingleDigitStatus(FIRST, SECOND)
parts[0] = isSingleDigitMap[FIRST] ? 'D' : 'DD'
parts[1] = isSingleDigitMap[SECOND] ? 'M' : 'MM'
return parts.join(separator)
}
const hasQuadDigit = [firstHasQuadDigit, secondHasQuadDigit, thirdHasQuadDigit]
// if we had no luck until here, we use the preferred order
parts[preferredOrder.indexOf('D')] = hasSingleDigit ? 'D' : 'DD'
parts[preferredOrder.indexOf('M')] = hasSingleDigit ? 'M' : 'MM'
parts[preferredOrder.indexOf('Y')] = hasQuadDigit ? 'YYYY' : 'YY'
inferSingleDigitStatus(preferredOrder.indexOf('D'), preferredOrder.indexOf('M'))
parts[preferredOrder.indexOf('D')] = isSingleDigitMap[preferredOrder.indexOf('D')] ? 'D' : 'DD'
parts[preferredOrder.indexOf('M')] = isSingleDigitMap[preferredOrder.indexOf('M')] ? 'M' : 'MM'
parts[preferredOrder.indexOf('Y')] = hasQuadDigit[preferredOrder.indexOf('Y')] ? 'YYYY' : 'YY'
return parts.join(separator)
}

2

package.json

@@ -57,3 +57,3 @@ {

},
"version": "3.1.1"
"version": "4.0.0"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc