@@ -52,4 +52,75 @@ export function sliceBlock(instuctionLines: CodeLine[], start: number): CodeLine
52
52
. findIndex ( ( cl , i ) => i > start && getLineIndent ( cl . line ) < blockLineIndent )
53
53
54
54
return instuctionLines . slice ( start , blockEndIndex > 0 ? blockEndIndex : undefined )
55
- }
55
+ }
56
+
57
+ export function parseDatetimeOrNull ( value : string | Date ) : Date | null {
58
+ if ( ! value ) { return null ; }
59
+ if ( value instanceof Date && ! isNaN ( value . valueOf ( ) ) ) { return value ; }
60
+ // only string values can be converted to Date
61
+ if ( typeof value !== 'string' ) { return null ; }
62
+
63
+ const strValue = String ( value ) ;
64
+ if ( ! strValue . length ) { return null ; }
65
+
66
+ const parseMonth = ( mm : string ) : number => {
67
+ if ( ! mm || ! mm . length ) {
68
+ return NaN ;
69
+ }
70
+
71
+ const m = parseInt ( mm , 10 ) ;
72
+ if ( ! isNaN ( m ) ) {
73
+ return m - 1 ;
74
+ }
75
+
76
+ // make sure english months are coming through
77
+ if ( mm . startsWith ( 'jan' ) ) { return 0 ; }
78
+ if ( mm . startsWith ( 'feb' ) ) { return 1 ; }
79
+ if ( mm . startsWith ( 'mar' ) ) { return 2 ; }
80
+ if ( mm . startsWith ( 'apr' ) ) { return 3 ; }
81
+ if ( mm . startsWith ( 'may' ) ) { return 4 ; }
82
+ if ( mm . startsWith ( 'jun' ) ) { return 5 ; }
83
+ if ( mm . startsWith ( 'jul' ) ) { return 6 ; }
84
+ if ( mm . startsWith ( 'aug' ) ) { return 7 ; }
85
+ if ( mm . startsWith ( 'sep' ) ) { return 8 ; }
86
+ if ( mm . startsWith ( 'oct' ) ) { return 9 ; }
87
+ if ( mm . startsWith ( 'nov' ) ) { return 10 ; }
88
+ if ( mm . startsWith ( 'dec' ) ) { return 11 ; }
89
+
90
+ return NaN ;
91
+ } ;
92
+
93
+ const correctYear = ( yy : number ) => {
94
+ if ( yy < 100 ) {
95
+ return yy < 68 ? yy + 2000 : yy + 1900 ;
96
+ } else {
97
+ return yy ;
98
+ }
99
+ } ;
100
+
101
+ const validDateOrNull =
102
+ ( yyyy : number , month : number , day : number , hours : number , mins : number , ss : number ) : Date | null => {
103
+ if ( month > 11 || day > 31 || hours >= 60 || mins >= 60 || ss >= 60 ) { return null ; }
104
+
105
+ const dd = new Date ( yyyy , month , day , hours , mins , ss , 0 ) ;
106
+ return ! isNaN ( dd . valueOf ( ) ) ? dd : null ;
107
+ } ;
108
+
109
+ const strTokens = strValue . replace ( 'T' , ' ' ) . toLowerCase ( ) . split ( / [: / - ] / ) ;
110
+ const dt = strTokens . map ( parseFloat ) ;
111
+
112
+ // try ISO first
113
+ let d = validDateOrNull ( dt [ 0 ] , dt [ 1 ] - 1 , dt [ 2 ] , dt [ 3 ] || 0 , dt [ 4 ] || 0 , dt [ 5 ] || 0 ) ;
114
+ if ( d ) { return d ; }
115
+
116
+ // then UK
117
+ d = validDateOrNull ( correctYear ( dt [ 2 ] ) , parseMonth ( strTokens [ 1 ] ) , dt [ 0 ] , dt [ 3 ] || 0 , dt [ 4 ] || 0 , dt [ 5 ] || 0 ) ;
118
+ if ( d ) { return d ; }
119
+
120
+ // then US
121
+ d = validDateOrNull ( correctYear ( dt [ 2 ] ) , parseMonth ( strTokens [ 0 ] ) , correctYear ( dt [ 1 ] ) , dt [ 3 ] || 0 , dt [ 4 ] || 0 , dt [ 5 ] || 0 ) ;
122
+ if ( d ) { return d ; }
123
+
124
+ return null ;
125
+ }
126
+
0 commit comments