@@ -528,7 +528,7 @@ addToLibrary({
528
528
529
529
var yday = ydayFromDate ( date ) | 0 ;
530
530
{ { { makeSetValue ( 'tmPtr' , C_STRUCTS . tm . tm_yday , 'yday' , 'i32' ) } } } ;
531
- { { { makeSetValue ( 'tmPtr' , C_STRUCTS . tm . tm_gmtoff , '-(date.getTimezoneOffset() * 60)' , 'i32 ' ) } } } ;
531
+ { { { makeSetValue ( 'tmPtr' , C_STRUCTS . tm . tm_gmtoff , '-(date.getTimezoneOffset() * 60)' , '* ' ) } } } ;
532
532
533
533
// Attention: DST is in December in South, and some regions don't have DST at all.
534
534
var start = new Date ( date . getFullYear ( ) , 0 , 1 ) ;
@@ -711,7 +711,7 @@ addToLibrary({
711
711
tm_wday : { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_wday , 'i32' ) } } } ,
712
712
tm_yday : { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_yday , 'i32' ) } } } ,
713
713
tm_isdst : { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_isdst , 'i32' ) } } } ,
714
- tm_gmtoff : { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_gmtoff , 'i32 ' ) } } } ,
714
+ tm_gmtoff : { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_gmtoff , '* ' ) } } } ,
715
715
tm_zone : tm_zone ? UTF8ToString ( tm_zone ) : ''
716
716
} ;
717
717
@@ -965,64 +965,64 @@ addToLibrary({
965
965
966
966
// reduce number of matchers
967
967
var EQUIVALENT_MATCHERS = {
968
- '% A' : '%a' ,
969
- '% B' : '%b' ,
970
- '% c' : '%a %b %d %H:%M:%S %Y' ,
971
- '% D' : '%m\\/%d\\/%y' ,
972
- '% e' : '%d' ,
973
- '% F' : '%Y-%m-%d' ,
974
- '% h' : '%b' ,
975
- '% R' : '%H\\:%M' ,
976
- '% r' : '%I\\:%M\\:%S\\s%p' ,
977
- '% T' : '%H\\:%M\\:%S' ,
978
- '% x' : '%m\\/%d\\/(?:%y|%Y)' ,
979
- '% X' : '%H\\:%M\\:%S'
968
+ 'A' : '%a' ,
969
+ 'B' : '%b' ,
970
+ 'c' : '%a %b %d %H:%M:%S %Y' ,
971
+ 'D' : '%m\\/%d\\/%y' ,
972
+ 'e' : '%d' ,
973
+ 'F' : '%Y-%m-%d' ,
974
+ 'h' : '%b' ,
975
+ 'R' : '%H\\:%M' ,
976
+ 'r' : '%I\\:%M\\:%S\\s%p' ,
977
+ 'T' : '%H\\:%M\\:%S' ,
978
+ 'x' : '%m\\/%d\\/(?:%y|%Y)' ,
979
+ 'X' : '%H\\:%M\\:%S'
980
980
} ;
981
- for ( var matcher in EQUIVALENT_MATCHERS ) {
982
- pattern = pattern . replace ( matcher , EQUIVALENT_MATCHERS [ matcher ] ) ;
983
- }
984
-
985
981
// TODO: take care of locale
986
982
987
983
var DATE_PATTERNS = {
988
- /* weeday name */ '% a' : '(?:Sun(?:day)?)|(?:Mon(?:day)?)|(?:Tue(?:sday)?)|(?:Wed(?:nesday)?)|(?:Thu(?:rsday)?)|(?:Fri(?:day)?)|(?:Sat(?:urday)?)' ,
989
- /* month name */ '% b' : '(?:Jan(?:uary)?)|(?:Feb(?:ruary)?)|(?:Mar(?:ch)?)|(?:Apr(?:il)?)|May|(?:Jun(?:e)?)|(?:Jul(?:y)?)|(?:Aug(?:ust)?)|(?:Sep(?:tember)?)|(?:Oct(?:ober)?)|(?:Nov(?:ember)?)|(?:Dec(?:ember)?)' ,
990
- /* century */ '% C' : '\\d\\d' ,
991
- /* day of month */ '% d' : '0[1-9]|[1-9](?!\\d)|1\\d|2\\d|30|31' ,
992
- /* hour (24hr) */ '% H' : '\\d(?!\\d)|[0,1]\\d|20|21|22|23' ,
993
- /* hour (12hr) */ '% I' : '\\d(?!\\d)|0\\d|10|11|12' ,
994
- /* day of year */ '% j' : '00[1-9]|0?[1-9](?!\\d)|0?[1-9]\\d(?!\\d)|[1,2]\\d\\d|3[0-6]\\d' ,
995
- /* month */ '% m' : '0[1-9]|[1-9](?!\\d)|10|11|12' ,
996
- /* minutes */ '% M' : '0\\d|\\d(?!\\d)|[1-5]\\d' ,
997
- /* whitespace */ '% n' : '\\s ' ,
998
- /* AM/PM */ '% p' : 'AM|am|PM|pm|A\\.M\\.|a\\.m\\.|P\\.M\\.|p\\.m\\.' ,
999
- /* seconds */ '% S' : '0\\d|\\d(?!\\d)|[1-5]\\d|60' ,
1000
- /* week number */ '% U' : '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53' ,
1001
- /* week number */ '% W' : '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53' ,
1002
- /* weekday number */ '% w' : '[0-6]' ,
1003
- /* 2-digit year */ '% y' : '\\d\\d' ,
1004
- /* 4-digit year */ '% Y' : '\\d\\d\\d\\d' ,
1005
- /* % */ '%% ' : '% ' ,
1006
- /* whitespace */ '%t ' : '\\s' ,
984
+ /* weekday name */ ' a' : '(?:Sun(?:day)?)|(?:Mon(?:day)?)|(?:Tue(?:sday)?)|(?:Wed(?:nesday)?)|(?:Thu(?:rsday)?)|(?:Fri(?:day)?)|(?:Sat(?:urday)?)' ,
985
+ /* month name */ 'b' : '(?:Jan(?:uary)?)|(?:Feb(?:ruary)?)|(?:Mar(?:ch)?)|(?:Apr(?:il)?)|May|(?:Jun(?:e)?)|(?:Jul(?:y)?)|(?:Aug(?:ust)?)|(?:Sep(?:tember)?)|(?:Oct(?:ober)?)|(?:Nov(?:ember)?)|(?:Dec(?:ember)?)' ,
986
+ /* century */ 'C' : '\\d\\d' ,
987
+ /* day of month */ 'd' : '0[1-9]|[1-9](?!\\d)|1\\d|2\\d|30|31' ,
988
+ /* hour (24hr) */ 'H' : '\\d(?!\\d)|[0,1]\\d|20|21|22|23' ,
989
+ /* hour (12hr) */ 'I' : '\\d(?!\\d)|0\\d|10|11|12' ,
990
+ /* day of year */ 'j' : '00[1-9]|0?[1-9](?!\\d)|0?[1-9]\\d(?!\\d)|[1,2]\\d\\d|3[0-6]\\d' ,
991
+ /* month */ 'm' : '0[1-9]|[1-9](?!\\d)|10|11|12' ,
992
+ /* minutes */ 'M' : '0\\d|\\d(?!\\d)|[1-5]\\d' ,
993
+ /* whitespace */ 'n' : ' ' ,
994
+ /* AM/PM */ 'p' : 'AM|am|PM|pm|A\\.M\\.|a\\.m\\.|P\\.M\\.|p\\.m\\.' ,
995
+ /* seconds */ 'S' : '0\\d|\\d(?!\\d)|[1-5]\\d|60' ,
996
+ /* week number */ 'U' : '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53' ,
997
+ /* week number */ 'W' : '0\\d|\\d(?!\\d)|[1-4]\\d|50|51|52|53' ,
998
+ /* weekday number */ 'w' : '[0-6]' ,
999
+ /* 2-digit year */ 'y' : '\\d\\d' ,
1000
+ /* 4-digit year */ 'Y' : '\\d\\d\\d\\d' ,
1001
+ /* whitespace */ 't ' : ' ' ,
1002
+ /* time zone */ 'z ' : 'Z|(?:[\\+\\-]\\d\\d:?(?:\\d\\d)?)'
1007
1003
} ;
1008
1004
1009
1005
var MONTH_NUMBERS = { JAN : 0 , FEB : 1 , MAR : 2 , APR : 3 , MAY : 4 , JUN : 5 , JUL : 6 , AUG : 7 , SEP : 8 , OCT : 9 , NOV : 10 , DEC : 11 } ;
1010
1006
var DAY_NUMBERS_SUN_FIRST = { SUN : 0 , MON : 1 , TUE : 2 , WED : 3 , THU : 4 , FRI : 5 , SAT : 6 } ;
1011
1007
var DAY_NUMBERS_MON_FIRST = { MON : 0 , TUE : 1 , WED : 2 , THU : 3 , FRI : 4 , SAT : 5 , SUN : 6 } ;
1012
1008
1013
- for ( var datePattern in DATE_PATTERNS ) {
1014
- pattern = pattern . replace ( datePattern , '(' + datePattern + DATE_PATTERNS [ datePattern ] + ')' ) ;
1015
- }
1016
-
1017
- // take care of capturing groups
1018
1009
var capture = [ ] ;
1019
- for ( var i = pattern . indexOf ( '%' ) ; i >= 0 ; i = pattern . indexOf ( '%' ) ) {
1020
- capture . push ( pattern [ i + 1 ] ) ;
1021
- pattern = pattern . replace ( new RegExp ( '\\%' + pattern [ i + 1 ] , 'g' ) , '' ) ;
1022
- }
1010
+ var pattern_out = pattern
1011
+ . replace ( / % ( .) / g, ( m , c ) => EQUIVALENT_MATCHERS [ c ] || m )
1012
+ . replace ( / % ( .) / g, ( _ , c ) => {
1013
+ let pat = DATE_PATTERNS [ c ] ;
1014
+ if ( pat ) {
1015
+ capture . push ( c ) ;
1016
+ return `(${ pat } )` ;
1017
+ } else {
1018
+ return c ;
1019
+ }
1020
+ } )
1021
+ . replace ( // any number of space or tab characters match zero or more spaces
1022
+ / \s + / g, '\\s*'
1023
+ ) ;
1023
1024
1024
- var matches = new RegExp ( '^' + pattern , "i" ) . exec ( UTF8ToString ( buf ) )
1025
- // out(UTF8ToString(buf)+ ' is matched by '+((new RegExp('^'+pattern)).source)+' into: '+JSON.stringify(matches));
1025
+ var matches = new RegExp ( '^' + pattern_out , "i" ) . exec ( UTF8ToString ( buf ) )
1026
1026
1027
1027
function initDate ( ) {
1028
1028
function fixup ( value , min , max ) {
@@ -1034,7 +1034,8 @@ addToLibrary({
1034
1034
day : fixup ( { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_mday , 'i32' ) } } } , 1 , 31 ) ,
1035
1035
hour : fixup ( { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_hour , 'i32' ) } } } , 0 , 23 ) ,
1036
1036
min : fixup ( { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_min , 'i32' ) } } } , 0 , 59 ) ,
1037
- sec : fixup ( { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_sec , 'i32' ) } } } , 0 , 59 )
1037
+ sec : fixup ( { { { makeGetValue ( 'tm' , C_STRUCTS . tm . tm_sec , 'i32' ) } } } , 0 , 59 ) ,
1038
+ gmtoff : 0
1038
1039
} ;
1039
1040
} ;
1040
1041
@@ -1161,6 +1162,20 @@ addToLibrary({
1161
1162
}
1162
1163
}
1163
1164
1165
+ // time zone
1166
+ if ( ( value = getMatch ( 'z' ) ) ) {
1167
+ // GMT offset as either 'Z' or +-HH:MM or +-HH or +-HHMM
1168
+ if ( value . toLowerCase ( ) === 'z' ) {
1169
+ date . gmtoff = 0 ;
1170
+ } else {
1171
+ var match = value . match ( / ^ ( (?: \- | \+ ) \d \d ) : ? ( \d \d ) ? / ) ;
1172
+ date . gmtoff = match [ 1 ] * 3600 ;
1173
+ if ( match [ 2 ] ) {
1174
+ date . gmtoff += date . gmtoff > 0 ? match [ 2 ] * 60 : - match [ 2 ] * 60
1175
+ }
1176
+ }
1177
+ }
1178
+
1164
1179
/*
1165
1180
tm_sec int seconds after the minute 0-61*
1166
1181
tm_min int minutes after the hour 0-59
@@ -1171,6 +1186,7 @@ addToLibrary({
1171
1186
tm_wday int days since Sunday 0-6
1172
1187
tm_yday int days since January 1 0-365
1173
1188
tm_isdst int Daylight Saving Time flag
1189
+ tm_gmtoff long offset from GMT (seconds)
1174
1190
*/
1175
1191
1176
1192
var fullDate = new Date ( date . year , date . month , date . day , date . hour , date . min , date . sec , 0 ) ;
@@ -1183,7 +1199,8 @@ addToLibrary({
1183
1199
{ { { makeSetValue ( 'tm' , C_STRUCTS . tm . tm_wday , 'fullDate.getDay()' , 'i32' ) } } } ;
1184
1200
{ { { makeSetValue ( 'tm' , C_STRUCTS . tm . tm_yday , 'arraySum(isLeapYear(fullDate.getFullYear()) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, fullDate.getMonth()-1)+fullDate.getDate()-1' , 'i32' ) } } } ;
1185
1201
{ { { makeSetValue ( 'tm' , C_STRUCTS . tm . tm_isdst , '0' , 'i32' ) } } } ;
1186
-
1202
+ { { { makeSetValue ( 'tm' , C_STRUCTS . tm . tm_gmtoff , 'date.gmtoff' , '*' ) } } } ;
1203
+
1187
1204
// we need to convert the matched sequence into an integer array to take care of UTF-8 characters > 0x7F
1188
1205
// TODO: not sure that intArrayFromString handles all unicode characters correctly
1189
1206
return buf + intArrayFromString ( matches [ 0 ] ) . length - 1 ;
0 commit comments