@@ -81,3 +81,45 @@ export function isDateString(value: unknown, strictDatePattern?: boolean): value
8181 }
8282 return false ;
8383}
84+
85+ /** parse ISO 8601 date string to standard Date type, if month and date is missing, will use new Date(01-01)
86+ * Reference: https://www.cl.cam.ac.uk/~mgk25/iso-time.html
87+ * 将日期字符串转为标准 Date 类型,如果没有月日,只有时间信息,会默认为 01-01
88+ */
89+ export function parseIsoDateString ( value : string , strictDatePattern : boolean = false ) : Date | null {
90+ const isoDateAndTimeRegs = getIsoDateAndTimeRegs ( strictDatePattern ) ;
91+ for ( let i = 0 ; i < isoDateAndTimeRegs . length ; i += 1 ) {
92+ const reg = isoDateAndTimeRegs [ i ] ;
93+ if ( reg . test ( value . trim ( ) ) ) {
94+ const matches = value . trim ( ) . match ( reg ) ;
95+ if ( matches . groups ) {
96+ const { year, month, day, week, weekday, hour, minute, second, millisecond, yearDay, offset } =
97+ matches . groups || { } ;
98+ const yearNum = parseInt ( year , 10 ) ;
99+ if ( yearDay ) {
100+ return new Date ( yearNum , 0 , parseInt ( yearDay , 10 ) ) ;
101+ }
102+
103+ if ( week ) {
104+ const weekNum = parseInt ( week , 10 ) ;
105+ const weekDayNum = weekday ? parseInt ( weekday , 10 ) : 1 ;
106+ const firstDayOfYear = new Date ( yearNum , 0 , 1 ) ;
107+ // 给定年份的第一天是周几
108+ const firstDayOfYearDayOfWeek = firstDayOfYear . getDay ( ) === 0 ? 7 : firstDayOfYear . getDay ( ) ;
109+ // 计算第一周的第一天相对 firstDayOfYear 的偏移量
110+ const firstWeekStartDayOffset = firstDayOfYearDayOfWeek === 1 ? 1 : 1 - firstDayOfYearDayOfWeek ;
111+ // 目标日期偏移量
112+ const targetDateOffset = ( weekNum - 1 ) * 7 + ( weekDayNum + firstWeekStartDayOffset ) ;
113+ return new Date ( yearNum , 0 , targetDateOffset ) ;
114+ }
115+
116+ const formattedDateString = [ year , month ?? '01' , day ?? '01' ] . join ( '-' ) ;
117+ const formattedTimeString = `${ [ hour ?? '00' , minute ?? '00' , second ?? '00' ] . join ( ':' ) } .${
118+ millisecond ?? '000'
119+ } ${ offset ?? '' } `;
120+ return new Date ( `${ formattedDateString } ${ formattedTimeString } ` ) ;
121+ }
122+ }
123+ }
124+ return null ;
125+ }
0 commit comments