@@ -3,8 +3,12 @@ import { DateTime } from './date-time';
33import { abs , floor , mod } from '@tubular/math' ;
44import { ILocale } from './i-locale' ;
55import { flatten , isArray , isEqual , isNumber , isString , last , toNumber } from '@tubular/util' ;
6- import { getMeridiems , getMinDaysInWeek , getOrdinals , getStartOfWeek , getWeekend , hasIntlDateTime , normalizeLocale } from './locale-data' ;
6+ import {
7+ checkDtfOptions , getMeridiems , getMinDaysInWeek , getOrdinals , getStartOfWeek , getWeekend ,
8+ hasIntlDateTime , normalizeLocale
9+ } from './locale-data' ;
710import { Timezone } from './timezone' ;
11+ import DateTimeFormat = Intl . DateTimeFormat ;
812import DateTimeFormatOptions = Intl . DateTimeFormatOptions ;
913
1014const shortOpts = { Y : 'year' , M : 'month' , D : 'day' , w : 'weekday' , h : 'hour' , m : 'minute' , s : 'second' , z : 'timeZoneName' ,
@@ -118,7 +122,7 @@ function isCased(s: string): boolean {
118122}
119123
120124function timeMatch ( dt : DateTime , locale : ILocale ) : boolean {
121- const format = locale . dateTimeFormats . check as Intl . DateTimeFormat ;
125+ const format = locale . dateTimeFormats . check as DateTimeFormat ;
122126
123127 if ( ! format )
124128 return false ;
@@ -384,21 +388,21 @@ export function format(dt: DateTime, fmt: string, localeOverride?: string | stri
384388 break ;
385389 }
386390 else if ( hasIntlDateTime ) {
387- result . push ( Intl . DateTimeFormat ( ) . resolvedOptions ( ) . timeZone ) ;
391+ result . push ( DateTimeFormat ( ) . resolvedOptions ( ) . timeZone ) ;
388392 break ;
389393 }
390394
391395 // eslint-disable-next-line no-fallthrough
392396 case 'zzz' : // As long zone name (e.g. "Pacific Daylight Time"), if possible
393- if ( hasIntlDateTime && locale . dateTimeFormats . Z instanceof Intl . DateTimeFormat ) {
397+ if ( hasIntlDateTime && locale . dateTimeFormats . Z instanceof DateTimeFormat ) {
394398 result . push ( getDatePart ( locale . dateTimeFormats . Z , dt . utcTimeMillis , 'timeZoneName' ) ) ;
395399 break ;
396400 }
397401
398402 // eslint-disable-next-line no-fallthrough
399403 case 'zz' : // As zone acronym (e.g. EST, PDT, AEST), if possible
400404 case 'z' :
401- if ( hasIntlDateTime && locale . dateTimeFormats . z instanceof Intl . DateTimeFormat ) {
405+ if ( hasIntlDateTime && locale . dateTimeFormats . z instanceof DateTimeFormat ) {
402406 result . push ( getDatePart ( locale . dateTimeFormats . z , dt . utcTimeMillis , 'timeZoneName' ) ) ;
403407 break ;
404408 }
@@ -435,10 +439,10 @@ export function format(dt: DateTime, fmt: string, localeOverride?: string | stri
435439 result . push ( locale . eras [ ( year < 1 ? 0 : 1 ) + ( field . length === 4 ? 2 : 0 ) ] ) ;
436440 else if ( field . startsWith ( 'I' ) ) {
437441 if ( hasIntlDateTime ) {
438- let intlFormat = locale . dateTimeFormats [ field ] as Intl . DateTimeFormat ;
442+ let intlFormat = locale . dateTimeFormats [ field ] as DateTimeFormat ;
439443
440444 if ( ! intlFormat ) {
441- const options : Intl . DateTimeFormatOptions = { calendar : 'gregory' } ;
445+ const options : DateTimeFormatOptions = { calendar : 'gregory' } ;
442446 const zone = convertDigits ( dt . timezone . zoneName ) ;
443447 let $ : RegExpExecArray ;
444448
@@ -458,12 +462,12 @@ export function format(dt: DateTime, fmt: string, localeOverride?: string | stri
458462 options . timeStyle = styleOptValues [ field . charAt ( 2 ) ] ;
459463
460464 try {
461- locale . dateTimeFormats [ field ] = intlFormat = new Intl . DateTimeFormat ( localeNames , options ) ;
465+ locale . dateTimeFormats [ field ] = intlFormat = new DateTimeFormat ( localeNames , checkDtfOptions ( options ) ) ;
462466 }
463467 catch {
464468 console . warn ( 'Timezone "%s" not recognized' , options . timeZone ) ;
465469 delete options . timeZone ;
466- locale . dateTimeFormats [ field ] = intlFormat = new Intl . DateTimeFormat ( localeNames , options ) ;
470+ locale . dateTimeFormats [ field ] = intlFormat = new DateTimeFormat ( localeNames , options ) ;
467471 }
468472 }
469473
@@ -512,8 +516,8 @@ export function format(dt: DateTime, fmt: string, localeOverride?: string | stri
512516 return result . join ( '' ) ;
513517}
514518
515- function quickFormat ( localeNames : string | string [ ] , timezone : string , opts : any ) : Intl . DateTimeFormat {
516- const options : Intl . DateTimeFormatOptions = { calendar : 'gregory' } ;
519+ function quickFormat ( localeNames : string | string [ ] , timezone : string , opts : any ) : DateTimeFormat {
520+ const options : DateTimeFormatOptions = { calendar : 'gregory' } ;
517521 let $ : RegExpExecArray ;
518522
519523 localeNames = normalizeLocale ( localeNames ) ;
@@ -535,7 +539,7 @@ function quickFormat(localeNames: string | string[], timezone: string, opts: any
535539 options [ key ] = value ;
536540 } ) ;
537541
538- return new Intl . DateTimeFormat ( localeNames , options ) ;
542+ return new DateTimeFormat ( localeNames , checkDtfOptions ( options ) ) ;
539543}
540544
541545// Find the shortest case-insensitive version of each string in the array that doesn't match
@@ -568,15 +572,15 @@ function getLocaleInfo(localeNames: string | string[]): ILocale {
568572 if ( locale && Object . keys ( locale ) . length > 0 )
569573 return locale ;
570574
571- const fmt = ( opts : any ) : Intl . DateTimeFormat => quickFormat ( localeNames , 'UTC' , opts ) ;
575+ const fmt = ( opts : any ) : DateTimeFormat => quickFormat ( localeNames , 'UTC' , opts ) ;
572576
573577 locale . name = isArray ( localeNames ) ? localeNames . join ( ',' ) : localeNames ;
574578
575579 if ( hasIntlDateTime ) {
576580 locale . months = [ ] ;
577581 locale . monthsShort = [ ] ;
578582 const narrow : string [ ] = [ ] ;
579- let format : Intl . DateTimeFormat ;
583+ let format : DateTimeFormat ;
580584
581585 for ( let month = 1 ; month <= 12 ; ++ month ) {
582586 const date = Date . UTC ( 2021 , month - 1 , 1 ) ;
@@ -671,7 +675,7 @@ function getLocaleInfo(localeNames: string | string[]): ILocale {
671675}
672676
673677function generatePredefinedFormats ( locale : ILocale , timezone : string ) : void {
674- const fmt = ( opts : any ) : Intl . DateTimeFormat => quickFormat ( locale . name , timezone , opts ) ;
678+ const fmt = ( opts : any ) : DateTimeFormat => quickFormat ( locale . name , timezone , opts ) ;
675679
676680 locale . cachedTimezone = timezone ;
677681 locale . dateTimeFormats = { } ;
@@ -694,7 +698,7 @@ function generatePredefinedFormats(locale: ILocale, timezone: string): void {
694698 Object . keys ( locale . dateTimeFormats ) . forEach ( key => {
695699 if ( / ^ L / i. test ( key ) )
696700 locale . dateTimeFormats [ '_' + key ] = analyzeFormat ( locale . name . split ( ',' ) ,
697- locale . dateTimeFormats [ key ] as Intl . DateTimeFormat ) ;
701+ locale . dateTimeFormats [ key ] as DateTimeFormat ) ;
698702 } ) ;
699703 }
700704 else {
@@ -720,9 +724,9 @@ function isLocale(locale: string | string[], matcher: string): boolean {
720724 return false ;
721725}
722726
723- export function analyzeFormat ( locale : string | string [ ] , formatter : Intl . DateTimeFormat ) : string ;
727+ export function analyzeFormat ( locale : string | string [ ] , formatter : DateTimeFormat ) : string ;
724728export function analyzeFormat ( locale : string | string [ ] , dateStyle : string , timeStyle ?: string ) : string ;
725- export function analyzeFormat ( locale : string | string [ ] , dateStyleOrFormatter : string | Intl . DateTimeFormat ,
729+ export function analyzeFormat ( locale : string | string [ ] , dateStyleOrFormatter : string | DateTimeFormat ,
726730 timeStyle ?: string ) : string {
727731 const options : DateTimeFormatOptions = { timeZone : 'UTC' , calendar : 'gregory' } ;
728732 let dateStyle : string ;
@@ -745,7 +749,7 @@ export function analyzeFormat(locale: string | string[], dateStyleOrFormatter: s
745749 }
746750
747751 const sampleDate = Date . UTC ( 2233 , 3 /* 4 */ , 5 , 6 , 7 , 8 ) ;
748- const format = new Intl . DateTimeFormat ( locale , options ) ;
752+ const format = new DateTimeFormat ( locale , checkDtfOptions ( options ) ) ;
749753 const parts = format . formatToParts ( sampleDate ) ;
750754 const dateLong = ( dateStyle === 'full' || dateStyle === 'long' ) ;
751755 const monthLong = ( dateLong || ( dateStyle === 'medium' && isLocale ( locale , 'ne' ) ) ) ;
@@ -921,7 +925,8 @@ export function parse(input: string, format: string, zone?: Timezone | string, l
921925 if ( input . includes ( '₂' ) )
922926 occurrence = 2 ;
923927
924- input = convertDigits ( input . replace ( / [ ‐ ‑ ‒ – — ] / g, '-' ) . replace ( / \s + / g, ' ' ) . trim ( ) ) . replace ( / [ \u200F ₂ ] / g, '' ) ;
928+ input = convertDigits ( input . replace ( / [ \u00AD \u2010 - \u2014 \u2212 ] / g, '-' )
929+ . replace ( / \s + / g, ' ' ) . trim ( ) ) . replace ( / [ \u200F ₂ ] / g, '' ) ;
925930 format = format . trim ( ) . replace ( / \u200F / g, '' ) ;
926931 locales = ! hasIntlDateTime ? 'en' : normalizeLocale ( locales ?? DateTime . getDefaultLocale ( ) ) ;
927932
@@ -1167,10 +1172,10 @@ export function parse(input: string, format: string, zone?: Timezone | string, l
11671172 case 'z' :
11681173 trimmed = false ;
11691174
1170- if ( ( $ = / ^ ( Z | [ _ / a - z ] + ) ( [ ^ - + _ / a - z ] | $ ) / i. exec ( input ) ) ) {
1175+ if ( ! / ^ U T C ? [ - + ] / . test ( input ) && ( $ = / ^ ( Z | \b E t c \/ G M T (?: 0 | [ - + ] \d { 1 , 2 } ) | [ _ / a - z ] + ) ( [ ^ - + _ / a - z ] | $ ) / i. exec ( input ) ) ) {
11711176 let embeddedZone : string | Timezone = $ [ 1 ] ;
11721177
1173- if ( / ^ ( Z | U T | U T C | G M T ) $ / i. test ( embeddedZone ) )
1178+ if ( / ^ ( Z | U T C ? | G M T ) $ / i. test ( embeddedZone ) )
11741179 embeddedZone = 'UT' ;
11751180
11761181 embeddedZone = Timezone . from ( embeddedZone ) ;
@@ -1194,8 +1199,8 @@ export function parse(input: string, format: string, zone?: Timezone | string, l
11941199 trimmed = true ;
11951200 }
11961201 }
1197- else if ( ( $ = / ^ ( U T C | U T | G M T ) ? ( [ - + ] \d \d (?: \d { 4 } | : \d \d ( : \d \d ) ? ) ? ) / i. exec ( input ) ) ) {
1198- w . utcOffset = parseTimeOffset ( $ [ 2 ] ) * ( $ [ 1 ] === 'GMT' ? - 1 : 1 ) ;
1202+ else if ( ( $ = / ^ ( U T C ? | G M T ) ? ( [ - + ] \d \d (?: \d { 4 } | : \d \d ( : \d \d ) ? ) ? ) / i. exec ( input ) ) ) {
1203+ w . utcOffset = parseTimeOffset ( $ [ 2 ] ) ;
11991204 input = input . substr ( $ [ 0 ] . length ) . trimStart ( ) ;
12001205 trimmed = true ;
12011206 }
0 commit comments