@@ -4,6 +4,7 @@ import weekday from 'dayjs/plugin/weekday';
44import localeData from 'dayjs/plugin/localeData' ;
55import weekOfYear from 'dayjs/plugin/weekOfYear' ;
66import weekYear from 'dayjs/plugin/weekYear' ;
7+ import quarterOfYear from 'dayjs/plugin/quarterOfYear' ;
78import advancedFormat from 'dayjs/plugin/advancedFormat' ;
89import customParseFormat from 'dayjs/plugin/customParseFormat' ;
910import type { GenerateConfig } from '.' ;
@@ -15,6 +16,7 @@ dayjs.extend(weekday);
1516dayjs . extend ( localeData ) ;
1617dayjs . extend ( weekOfYear ) ;
1718dayjs . extend ( weekYear ) ;
19+ dayjs . extend ( quarterOfYear ) ;
1820
1921dayjs . extend ( ( _o , c ) => {
2022 // todo support Wo (ISO week)
@@ -105,6 +107,58 @@ const parseNoMatchNotice = () => {
105107 noteOnce ( false , 'Not match any format. Please help to fire a issue about this.' ) ;
106108} ;
107109
110+ const advancedFormatRegex = / \[ ( [ ^ \] ] + ) ] | Q | w o | w w | w | W W | W | z z z | z | g g g g | G G G G | k { 1 , 2 } | S / g;
111+
112+ function findTargetStr ( val : string , index : number , segmentation : string ) {
113+ const items = [ ...new Set ( val . split ( segmentation ) ) ] ;
114+ let idx = 0 ;
115+ for ( let i = 0 ; i < items . length ; i ++ ) {
116+ const item = items [ i ] ;
117+ idx += item . length ;
118+ if ( idx > index ) {
119+ return item ;
120+ }
121+ idx += segmentation . length ;
122+ }
123+ }
124+
125+ const toDateWithValueFormat = ( val : string | Dayjs , valueFormat : string ) => {
126+ if ( dayjs . isDayjs ( val ) ) {
127+ return val ;
128+ }
129+ const matchs = valueFormat . matchAll ( advancedFormatRegex ) ;
130+ let baseDate = dayjs ( val , valueFormat ) ;
131+ if ( matchs === null ) {
132+ return baseDate ;
133+ }
134+ for ( const match of matchs ) {
135+ const origin = match [ 0 ] ;
136+ const index = match [ 'index' ] ;
137+
138+ if ( origin === 'Q' ) {
139+ const segmentation = val . slice ( index - 1 , index ) ;
140+ const quarterStr = findTargetStr ( val , index , segmentation ) . match ( / \d + / ) [ 0 ] ;
141+ baseDate = baseDate . quarter ( parseInt ( quarterStr ) ) ;
142+ }
143+
144+ if ( origin . toLowerCase ( ) === 'wo' ) {
145+ const segmentation = val . slice ( index - 1 , index ) ;
146+ const weekStr = findTargetStr ( val , index , segmentation ) . match ( / \d + / ) [ 0 ] ;
147+ baseDate = baseDate . week ( parseInt ( weekStr ) ) ;
148+ }
149+
150+ if ( origin . toLowerCase ( ) === 'ww' ) {
151+ baseDate = baseDate . week ( parseInt ( val . slice ( index , index + origin . length ) ) ) ;
152+ }
153+
154+ if ( origin . toLowerCase ( ) === 'w' ) {
155+ baseDate = baseDate . week ( parseInt ( val . slice ( index , index + origin . length + 1 ) ) ) ;
156+ }
157+ }
158+
159+ return baseDate ;
160+ } ;
161+
108162const generateConfig : GenerateConfig < Dayjs > = {
109163 // get
110164 getNow : ( ) => dayjs ( ) ,
@@ -177,13 +231,9 @@ const generateConfig: GenerateConfig<Dayjs> = {
177231
178232 toDate : ( value , valueFormat ) => {
179233 if ( Array . isArray ( value ) ) {
180- return value . map ( ( val : any ) =>
181- typeof val === 'string' && val ? dayjs ( val , valueFormat ) : val || null ,
182- ) as Dayjs [ ] ;
234+ return value . map ( ( val : any ) => toDateWithValueFormat ( val , valueFormat ) ) as Dayjs [ ] ;
183235 } else {
184- return (
185- typeof value === 'string' && value ? dayjs ( value , valueFormat ) : value || null
186- ) as Dayjs ;
236+ return toDateWithValueFormat ( value , valueFormat ) as Dayjs ;
187237 }
188238 } ,
189239 toString : ( value , valueFormat ) => {
0 commit comments