Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: date related changes for go package #199

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions packages/i18nify-go/modules/dateTime/dateTime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Package dateTime provides utilities for date and time formatting, parsing, and manipulation.
package dateTime

import (
"errors"
"fmt"
"time"
)

const (
minute = time.Minute
hour = time.Hour
day = hour * 24
week = day * 7
month = day * 30
year = month * 12
)

// IntlOptions represents the options for formatting the date and time.
type IntlOptions struct {
Locale string
DateTimeMode string
Hour12 *bool
}

// DateTimeMode represents the different modes of date-time formatting
type DateTimeMode string

const (
dateTimeMode DateTimeMode = "dateTime"
dateOnlyMode DateTimeMode = "dateOnly"
timeOnlyMode DateTimeMode = "timeOnly"
)

// DateTimeOptions represents the configuration for date-time formatting
type DateTimeOptions struct {
DateTimeMode DateTimeMode
BaseDate string
IntlOptions *IntlOptions
}

// 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]
}

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("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")
}
}

// StringToDate converts a string representation of a date into a time.Time object.
func StringToDate(dateStr string) (time.Time, error) {
return convertToStandardDate(dateStr)
}
70 changes: 70 additions & 0 deletions packages/i18nify-go/modules/dateTime/dateTime_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package dateTime

import (
"testing"
"time"
)

// Additional test for date parsing functionality
func TestParseDateTime(t *testing.T) {
tests := []struct {
name string
input string
expectError bool
}{
{
name: "parses RFC3339",
input: time.Now().Format(time.RFC3339),
},
{
name: "parses ISO format",
input: "2024-01-02T15:04:05",
},
{
name: "parses date only",
input: "2024-01-02",
},
{
name: "fails on invalid format",
input: "invalid-date",
expectError: true,
},
{
name: "fails on empty string",
input: "",
expectError: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := convertToStandardDate(tt.input)
if tt.expectError && err == nil {
t.Error("expected error but got none")
}
if !tt.expectError && err != nil {
t.Errorf("unexpected error: %v", err)
}
})
}
}

func TestStringToDate(t *testing.T) {
dateStr := "2024-12-16 10:30:00"
layout := "2006-01-02 15:04:05"

// Positive case
parsedDate, err := StringToDate(dateStr)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if parsedDate.Format(layout) != dateStr {
t.Errorf("expected '%s', got '%s'", dateStr, parsedDate.Format(layout))
}

// Negative case
_, err = StringToDate("not-a-date")
if err == nil {
t.Error("expected an error for invalid date string")
}
}
73 changes: 73 additions & 0 deletions packages/i18nify-go/modules/dateTime/format_date_time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package dateTime

import (
"fmt"
"time"
)

// FormatDateTime formats a date-time string based on the provided options
func FormatDateTime(dateStr string, options *DateTimeOptions) (string, error) {
// Set default options if not provided
if options == nil {
options = &DateTimeOptions{
DateTimeMode: dateOnlyMode,
}
}

// Parse the input date
parsedTime, err := convertToStandardDate(dateStr)
if err != nil {
return "", fmt.Errorf("error parsing date: %v", err)
}

// Determine formatting based on mode
switch options.DateTimeMode {
case dateTimeMode:
return formatFullDateTime(parsedTime, options), nil
case dateOnlyMode:
return formatDateOnly(parsedTime, options), nil
case timeOnlyMode:
return formatTimeOnly(parsedTime, options), nil
default:
return formatDateOnly(parsedTime, options), nil
}
}

// formatFullDateTime handles full date and time formatting
func formatFullDateTime(t time.Time, options *DateTimeOptions) string {
// Check for 24-hour format option
hour12 := false
if options.IntlOptions != nil {
if options.IntlOptions.Hour12 != nil {
hour12 = *options.IntlOptions.Hour12
}
}

// Choose format based on 12/24 hour
if hour12 {
return t.Format("1/2/2006, 3:04:05 PM")
}
return t.Format("1/2/2006, 15:04:05")
}

// formatDateOnly handles date-only formatting
func formatDateOnly(t time.Time, options *DateTimeOptions) string {
return t.Format("1/2/2006")
}

// formatTimeOnly handles time-only formatting
func formatTimeOnly(t time.Time, options *DateTimeOptions) string {
// Check for 24-hour format option
hour12 := true
if options.IntlOptions != nil {
if options.IntlOptions.Hour12 != nil {
hour12 = *options.IntlOptions.Hour12
}
}

// Choose format based on 12/24 hour
if hour12 {
return t.Format("3:04:05 PM")
}
return t.Format("15:04:05")
}
Loading
Loading