@@ -342,6 +342,26 @@ func fixTimeStamp(dateTimeStr string) (time.Time, error) {
342342 )
343343 }
344344
345+ // If the year is a leap year and the date is 29th of February, we
346+ // need to change it to 28th of February. Otherwise, the time.Parse
347+ // function will fail, as a non-leap year cannot have 29th of February.
348+ day , month , err := extractDayAndMonth (dateTimeStr )
349+ if err != nil {
350+ return time.Time {}, fmt .Errorf ("unable to parse timestamp day " +
351+ "and month %v: %v" , dateTimeStr , err )
352+ }
353+
354+ if ! isLeapYear (thisYear ) &&
355+ month == 2 && day == 29 {
356+
357+ dateTimeStr = strings .Replace (
358+ dateTimeStr ,
359+ fmt .Sprintf ("%d-02-29" , thisYear ),
360+ fmt .Sprintf ("%d-02-28" , thisYear ),
361+ 1 ,
362+ )
363+ }
364+
345365 parsedTime , err := parseLayouts (defaultLayouts (), dateTimeStr )
346366 if err != nil {
347367 return time.Time {}, fmt .Errorf ("unable to parse timestamp %v: %v" ,
@@ -403,3 +423,38 @@ func getTimeStampYear(dateTimeStr string) (int, error) {
403423
404424 return year , nil
405425}
426+
427+ // extractDayAndMonth extracts the day and month from a date string.
428+ func extractDayAndMonth (dateStr string ) (int , int , error ) {
429+ // Split the date string into parts using various delimiters.
430+ parts := strings .FieldsFunc (dateStr , func (r rune ) bool {
431+ return r == '-' || r == ' ' || r == 'T' || r == ':' || r == '+' || r == 'Z'
432+ })
433+
434+ if len (parts ) < 3 {
435+ return 0 , 0 , fmt .Errorf ("Invalid date format: %s" , dateStr )
436+ }
437+
438+ // Extract year, month, and day from the parts.
439+ _ , err := strconv .Atoi (parts [0 ])
440+ if err != nil {
441+ return 0 , 0 , err
442+ }
443+
444+ month , err := strconv .Atoi (parts [1 ])
445+ if err != nil {
446+ return 0 , 0 , err
447+ }
448+
449+ day , err := strconv .Atoi (parts [2 ])
450+ if err != nil {
451+ return 0 , 0 , err
452+ }
453+
454+ return day , month , nil
455+ }
456+
457+ // isLeapYear returns true if the year is a leap year.
458+ func isLeapYear (year int ) bool {
459+ return (year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0 )
460+ }
0 commit comments