From e6bbbbef7aa1db7fffdf27deeb2e68a07b4e8de3 Mon Sep 17 00:00:00 2001 From: gezimbll Date: Wed, 7 May 2025 17:37:22 +0200 Subject: [PATCH] added *localtime dataconverter --- utils/consts.go | 1 + utils/dataconverter.go | 36 +++++++++++++++++++++++++++++++++ utils/dataconverter_test.go | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/utils/consts.go b/utils/consts.go index 72d3a00f9..18b93d8d6 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -742,6 +742,7 @@ const ( MetaDurationFormat = "*durfmt" MetaLibPhoneNumber = "*libphonenumber" MetaTimeString = "*time_string" + MetaLocalTime = "*localtime" MetaIP2Hex = "*ip2hex" MetaString2Hex = "*string2hex" MetaUnixTime = "*unixtime" diff --git a/utils/dataconverter.go b/utils/dataconverter.go index 103bf9270..9fe55cd91 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -125,6 +125,13 @@ func NewDataConverter(params string) (conv DataConverter, err error) { layout = params[len(MetaTimeString)+1:] } return NewTimeStringConverter(layout), nil + + case strings.HasPrefix(params, MetaLocalTime): + timezone := "Local" + if len(params) > len(MetaLocalTime) { + timezone = params[len(MetaLocalTime)+1:] + } + return NewLocalTimeConverter(timezone) case strings.HasPrefix(params, MetaRandom): if len(params) == len(MetaRandom) { // no extra params, defaults implied return NewRandomConverter(EmptyString) @@ -816,3 +823,32 @@ func (mS *DurationMinutesConverter) Convert(in any) ( out = inDur.Minutes() return } + +type LocalTimeConverter struct { + loc *time.Location +} + +func NewLocalTimeConverter(locStr string) (DataConverter, error) { + loc, err := time.LoadLocation(locStr) + if err != nil { + return nil, err + } + return LocalTimeConverter{loc: loc}, nil +} +func (lt LocalTimeConverter) Convert(in any) (out any, err error) { + var tm time.Time + switch val := in.(type) { + case string: + tm, err = ParseTimeDetectLayout(val, EmptyString) + if err != nil { + return nil, err + } + case time.Time: + tm = val + default: + return nil, fmt.Errorf("*localtime converter: unsupported input") + } + tm = tm.In(lt.loc) + return tm.Format(time.DateTime), nil + +} diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index d71d79d44..ea6635dfd 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -2001,3 +2001,43 @@ func TestDurationMinutesConverter(t *testing.T) { }) } } + +func TestLocalTimeDurationConverter(t *testing.T) { + testCases := []struct { + name string + input any + params string + expectValue string + expectedErr error + }{ + {name: "Convert to CEST timezone", input: "2025-05-07T14:25:08Z", params: "*localtime:Europe/Berlin", expectValue: "2025-05-07 16:25:08"}, + {name: "Convert to UTC timezone", input: "2025-05-07T16:25:08+02:00", params: "*localtime:UTC", expectValue: "2025-05-07 14:25:08"}, + {name: "Convert to UTC+01:00 timezone", input: "2025-05-07T14:25:08Z", params: "*localtime:Europe/Dublin", expectValue: "2025-05-07 15:25:08"}, + {name: "Convert to UTC+03:00 timezone", input: time.Date(2025, 5, 5, 15, 5, 0, 0, time.UTC), params: "*localtime:Europe/Istanbul", expectValue: "2025-05-05 18:05:00"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + converter, err := NewDataConverter(tc.params) + if err != nil { + t.Fatal(err) + } + val, err := converter.Convert(tc.input) + if tc.expectedErr != nil { + if err == nil { + t.Fatalf("Expected an error containing '%s', but got nil", tc.expectedErr.Error()) + } + if !strings.Contains(err.Error(), tc.expectedErr.Error()) { + t.Errorf("Expected error message to contain '%s', but got: %v", tc.expectedErr.Error(), err) + } + return + } + if err != nil { + t.Fatalf("Expected no error, but got: %v", err) + } + if tc.expectValue != val { + t.Errorf("Expected output %s, but got %s", tc.expectValue, val) + } + }) + } +}