Skip to content

Commit

Permalink
add: supported_date_times.go
Browse files Browse the repository at this point in the history
  • Loading branch information
rzp-Piyush committed Dec 17, 2024
1 parent 0daf5df commit b3fb336
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 30 deletions.
64 changes: 40 additions & 24 deletions packages/i18nify-go/modules/dateTime/dateTime.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package dateTime

import (
"errors"
"fmt"
"time"
)
Expand Down Expand Up @@ -38,23 +39,47 @@ type DateTimeOptions struct {
IntlOptions *IntlOptions
}

// parseDateTime handles parsing various date string formats
func parseDateTime(dateStr string) (time.Time, error) {
formats := []string{
time.RFC3339,
"2006-01-02T15:04:05",
"2006-01-02",
"1/2/2006",
}
// stringToDate converts a date string into a Go time.Time object.
func stringToDate(dateString string) (time.Time, error) {
for _, format := range SupportedDateFormats {
if format.Regex != nil {
// Handle custom regex formats
if matches := format.Regex.FindStringSubmatch(dateString); matches != nil {
year := matches[format.YearIndex]
month := matches[format.MonthIndex]
day := matches[format.DayIndex]
hour, minute, second := "00", "00", "00"

if format.HourIndex > 0 {
hour = matches[format.HourIndex]
minute = matches[format.MinuteIndex]
second = matches[format.SecondIndex]
}

for _, format := range formats {
parsed, err := time.Parse(format, dateStr)
if err == nil {
return parsed, nil
combined := fmt.Sprintf("%s-%s-%sT%s:%s:%sZ", year, month, day, hour, minute, second)
return time.Parse(time.RFC3339, combined)
}
} else if format.Format != "" {
// Handle Go's standard layouts
if parsedTime, err := time.Parse(format.Format, dateString); err == nil {
return parsedTime, nil
}
}
}

return time.Time{}, fmt.Errorf("invalid date format, please pass one of these formats %v", formats)
return time.Time{}, fmt.Errorf("date format not recognized: %s", dateString)
}

// convertToStandardDate converts a date input (string or time.Time) into a standardized time.Time object.
func convertToStandardDate(dateInput interface{}) (time.Time, error) {
switch date := dateInput.(type) {
case string:
return stringToDate(date)
case time.Time:
return date, nil
default:
return time.Time{}, errors.New("unsupported date input type")
}
}

// GetWeekdays returns an array of weekday names starting from Sunday.
Expand All @@ -68,16 +93,7 @@ func GetWeekdays() []string {
return weekdays
}

// ParseDateTime parses a date string and returns its components.
func ParseDateTime(dateStr, layout string) (time.Time, error) {
parsedDate, err := time.Parse(layout, dateStr)
if err != nil {
return time.Time{}, fmt.Errorf("failed to parse date: %w", err)
}
return parsedDate, nil
}

// StringToDate converts a string representation of a date into a time.Time object.
func StringToDate(dateStr string, layout string) (time.Time, error) {
return ParseDateTime(dateStr, layout)
func StringToDate(dateStr string) (time.Time, error) {
return convertToStandardDate(dateStr)
}
6 changes: 3 additions & 3 deletions packages/i18nify-go/modules/dateTime/dateTime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestParseDateTime(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := parseDateTime(tt.input)
_, err := convertToStandardDate(tt.input)
if tt.expectError && err == nil {
t.Error("expected error but got none")
}
Expand All @@ -65,7 +65,7 @@ func TestStringToDate(t *testing.T) {
layout := "2006-01-02 15:04:05"

// Positive case
parsedDate, err := StringToDate(dateStr, layout)
parsedDate, err := StringToDate(dateStr)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
Expand All @@ -74,7 +74,7 @@ func TestStringToDate(t *testing.T) {
}

// Negative case
_, err = StringToDate("not-a-date", layout)
_, err = StringToDate("not-a-date")
if err == nil {
t.Error("expected an error for invalid date string")
}
Expand Down
2 changes: 1 addition & 1 deletion packages/i18nify-go/modules/dateTime/format_date_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func FormatDateTime(dateStr string, options *DateTimeOptions) (string, error) {
}

// Parse the input date
parsedTime, err := parseDateTime(dateStr)
parsedTime, err := convertToStandardDate(dateStr)
if err != nil {
return "", fmt.Errorf("error parsing date: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/i18nify-go/modules/dateTime/get_relative_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import "fmt"

// GetRelativeTime calculates the relative time string (e.g., "2 hours ago" or "in 2 hours").
func GetRelativeTime(dateStr string, options DateTimeOptions) (string, error) {
date, err := parseDateTime(dateStr)
date, err := convertToStandardDate(dateStr)
if err != nil {
return "", err
}
baseDate, err := parseDateTime(options.BaseDate)
baseDate, err := convertToStandardDate(options.BaseDate)
if err != nil {
return "", err
}
Expand Down
63 changes: 63 additions & 0 deletions packages/i18nify-go/modules/dateTime/supported_date_times.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dateTime

import (
"regexp"
"time"
)

// DateFormat defines the structure of supported date formats
type DateFormat struct {
Regex *regexp.Regexp
YearIndex int
MonthIndex int
DayIndex int
HourIndex int
MinuteIndex int
SecondIndex int
Format string
}

// SupportedDateFormats holds all globally supported date formats
var SupportedDateFormats = []DateFormat{
// Date formats
{regexp.MustCompile(`^(\d{4})/(0[1-9]|1[0-2])/(\d{2})$`), 1, 2, 3, 0, 0, 0, "YYYY/MM/DD"},
{regexp.MustCompile(`^(\d{2})/(0[1-9]|1[0-2])/(\d{4})$`), 3, 2, 1, 0, 0, 0, "DD/MM/YYYY"},
{regexp.MustCompile(`^(\d{4})\.(0[1-9]|1[0-2])\.(\d{2})$`), 1, 2, 3, 0, 0, 0, "YYYY.MM.DD"},
{regexp.MustCompile(`^(\d{2})-(0[1-9]|1[0-2])-(\d{4})$`), 3, 2, 1, 0, 0, 0, "DD-MM-YYYY"},
{regexp.MustCompile(`^(0[1-9]|1[0-2])/(\d{2})/(\d{4})$`), 3, 1, 2, 0, 0, 0, "MM/DD/YYYY"},
{regexp.MustCompile(`^(\d{4})-(0[1-9]|1[0-2])-(\d{2})$`), 1, 2, 3, 0, 0, 0, "YYYY-MM-DD"},
{regexp.MustCompile(`^(\d{4})\.\s*(0[1-9]|1[0-2])\.\s*(\d{2})\.\s*$`), 1, 2, 3, 0, 0, 0, "YYYY. MM. DD."},
{regexp.MustCompile(`^(\d{2})\.(0[1-9]|1[0-2])\.(\d{4})$`), 3, 2, 1, 0, 0, 0, "DD.MM.YYYY"},
{regexp.MustCompile(`^(0[1-9]|1[0-2])\.(\d{2})\.(\d{4})$`), 3, 1, 2, 0, 0, 0, "MM.DD.YYYY"},

// Timestamp formats
{regexp.MustCompile(`^(\d{4})/(0[1-9]|1[0-2])/(\d{2}) (\d{2}):(\d{2}):(\d{2})$`), 1, 2, 3, 4, 5, 6, "YYYY/MM/DD HH:MM:SS"},
{regexp.MustCompile(`^(\d{2})/(0[1-9]|1[0-2])/(\d{4}) (\d{2}):(\d{2}):(\d{2})$`), 3, 2, 1, 4, 5, 6, "DD/MM/YYYY HH:MM:SS"},
{regexp.MustCompile(`^(\d{4})-(0[1-9]|1[0-2])-(\d{2}) (\d{2}):(\d{2}):(\d{2})$`), 1, 2, 3, 4, 5, 6, "YYYY-MM-DD HH:MM:SS"},
{regexp.MustCompile(`^(\d{2})-(0[1-9]|1[0-2])-(\d{4}) (\d{2}):(\d{2}):(\d{2})$`), 3, 2, 1, 4, 5, 6, "DD-MM-YYYY HH:MM:SS"},
{regexp.MustCompile(`^(\d{4})\.(0[1-9]|1[0-2])\.(\d{2}) (\d{2}):(\d{2}):(\d{2})$`), 1, 2, 3, 4, 5, 6, "YYYY.MM.DD HH:MM:SS"},
{regexp.MustCompile(`^(\d{2})\.(0[1-9]|1[0-2])\.(\d{4}) (\d{2}):(\d{2}):(\d{2})$`), 3, 2, 1, 4, 5, 6, "DD.MM.YYYY HH:MM:SS"},

// ISO 8601 Timestamp
{regexp.MustCompile(`^(\d{4})-(0[1-9]|1[0-2])-(\d{2})T(\d{2}):(\d{2}):(\d{2})$`), 1, 2, 3, 4, 5, 6, "YYYY-MM-DDTHH:MM:SS"},
// Standard Go
{nil, 0, 0, 0, 0, 0, 0, time.Layout}, // "01/02 03:04:05PM '06 -0700"
{nil, 0, 0, 0, 0, 0, 0, time.ANSIC}, // "Mon Jan _2 15:04:05 2006"
{nil, 0, 0, 0, 0, 0, 0, time.UnixDate}, // "Mon Jan _2 15:04:05 MST 2006"
{nil, 0, 0, 0, 0, 0, 0, time.RubyDate}, // "Mon Jan 02 15:04:05 -0700 2006"
{nil, 0, 0, 0, 0, 0, 0, time.RFC822}, // "02 Jan 06 15:04 MST"
{nil, 0, 0, 0, 0, 0, 0, time.RFC822Z}, // "02 Jan 06 15:04 -0700"
{nil, 0, 0, 0, 0, 0, 0, time.RFC850}, // "Monday, 02-Jan-06 15:04:05 MST"
{nil, 0, 0, 0, 0, 0, 0, time.RFC1123}, // "Mon, 02 Jan 2006 15:04:05 MST"
{nil, 0, 0, 0, 0, 0, 0, time.RFC1123Z}, // "Mon, 02 Jan 2006 15:04:05 -0700"
{nil, 0, 0, 0, 0, 0, 0, time.RFC3339}, // "2006-01-02T15:04:05Z07:00"
{nil, 0, 0, 0, 0, 0, 0, time.RFC3339Nano}, // "2006-01-02T15:04:05.999999999Z07:00"
{nil, 0, 0, 0, 0, 0, 0, time.Kitchen}, // "3:04PM"
{nil, 0, 0, 0, 0, 0, 0, time.Stamp}, // "Jan _2 15:04:05"
{nil, 0, 0, 0, 0, 0, 0, time.StampMilli}, // "Jan _2 15:04:05.000"
{nil, 0, 0, 0, 0, 0, 0, time.StampMicro}, // "Jan _2 15:04:05.000000"
{nil, 0, 0, 0, 0, 0, 0, time.StampNano}, // "Jan _2 15:04:05.000000000"
{nil, 0, 0, 0, 0, 0, 0, "2006-01-02 15:04:05"}, // DateTime
{nil, 0, 0, 0, 0, 0, 0, "2006-01-02"}, // DateOnly
{nil, 0, 0, 0, 0, 0, 0, "15:04:05"}, // TimeOnly
}

0 comments on commit b3fb336

Please sign in to comment.