diff --git a/os/gtime/gtime_z_bench_timezone_test.go b/os/gtime/gtime_z_bench_timezone_test.go index d93b2a45f..f8ca72011 100644 --- a/os/gtime/gtime_z_bench_timezone_test.go +++ b/os/gtime/gtime_z_bench_timezone_test.go @@ -20,22 +20,22 @@ func BenchmarkTime_TimezonePreservation(b *testing.B) { gmtLocation, _ := time.LoadLocation("GMT") dbTime := time.Date(2025, 9, 15, 7, 45, 40, 0, gmtLocation) gtimeVal := gtime.NewFromTime(dbTime) - + b.ResetTimer() - + b.Run("DirectGTimeConversion", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = gconv.Time(gtimeVal) } }) - + b.Run("MapToTimeConversion", func(b *testing.B) { mapData := map[string]interface{}{"now": gtimeVal} for i := 0; i < b.N; i++ { _ = gconv.Time(mapData) } }) - + b.Run("StructsConversion", func(b *testing.B) { result := []map[string]interface{}{{"now": gtimeVal}} for i := 0; i < b.N; i++ { @@ -51,25 +51,25 @@ func BenchmarkGTime_Optimization(b *testing.B) { gmtLocation, _ := time.LoadLocation("GMT") dbTime := time.Date(2025, 9, 15, 7, 45, 40, 0, gmtLocation) gtimeVal := gtime.NewFromTime(dbTime) - + b.ResetTimer() - + b.Run("DirectGTimeToGTime", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = gconv.GTime(gtimeVal) } }) - + b.Run("TimeToGTime", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = gconv.GTime(dbTime) } }) - + b.Run("StringToGTime", func(b *testing.B) { timeStr := "2025-09-15T07:45:40Z" for i := 0; i < b.N; i++ { _ = gconv.GTime(timeStr) } }) -} \ No newline at end of file +} diff --git a/os/gtime/gtime_z_unit_timezone_issue_test.go b/os/gtime/gtime_z_unit_timezone_issue_test.go index 9be2ae766..f57092155 100644 --- a/os/gtime/gtime_z_unit_timezone_issue_test.go +++ b/os/gtime/gtime_z_unit_timezone_issue_test.go @@ -23,7 +23,7 @@ func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) { defer func() { time.Local = originalLocation }() - + shanghaiLocation, _ := time.LoadLocation("Asia/Shanghai") time.Local = shanghaiLocation @@ -37,9 +37,9 @@ func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) { originalName, originalOffset := gtimeVal.Zone() convertedName, convertedOffset := convertedTime.Zone() t.Assert(originalOffset, convertedOffset) // Offset must be preserved - t.Assert(originalOffset, 0) // GMT offset - t.Assert(convertedOffset, 0) // Converted offset should also be 0 - + t.Assert(originalOffset, 0) // GMT offset + t.Assert(convertedOffset, 0) // Converted offset should also be 0 + // Test single struct conversion (should work after fix) type TestStruct struct { Time time.Time @@ -55,16 +55,16 @@ func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) { var nowResult []time.Time err = gconv.Structs(result, &nowResult) t.AssertNil(err) - + structsTime := nowResult[0] _, structsOffset := structsTime.Zone() - + // This should now work with the optimized fix - t.Assert(structsOffset, 0) // Timezone offset should be preserved + t.Assert(structsOffset, 0) // Timezone offset should be preserved t.Assert(gtimeVal.Time.Equal(structsTime), true) // Same instant in time - + // Test edge cases for robustness - + // Test empty map emptyMapResult := []map[string]interface{}{{}} var emptyResult []time.Time @@ -72,7 +72,7 @@ func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) { t.AssertNil(err) t.Assert(len(emptyResult), 1) t.Assert(emptyResult[0].IsZero(), true) - + // Test nil gtime value nilResult := []map[string]interface{}{{"time": (*gtime.Time)(nil)}} var nilTimeResult []time.Time @@ -80,8 +80,8 @@ func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) { t.AssertNil(err) t.Assert(len(nilTimeResult), 1) t.Assert(nilTimeResult[0].IsZero(), true) - + // Note: Timezone name might change but offset preservation is critical _, _ = originalName, convertedName }) -} \ No newline at end of file +} diff --git a/util/gconv/internal/converter/converter_time.go b/util/gconv/internal/converter/converter_time.go index 22cc9b4d0..3af2c701d 100644 --- a/util/gconv/internal/converter/converter_time.go +++ b/util/gconv/internal/converter/converter_time.go @@ -30,9 +30,9 @@ func (c *Converter) Time(anyInput any, format ...string) (time.Time, error) { } return v.Time, nil } - + // Handle map inputs by extracting the first value - // This is optimized for ORM scenarios where maps like {"now": gtimeVal} + // This is optimized for ORM scenarios where maps like {"now": gtimeVal} // need to be converted to a single time.Time value if mapData, ok := anyInput.(map[string]interface{}); ok { if len(mapData) == 0 { @@ -44,7 +44,7 @@ func (c *Converter) Time(anyInput any, format ...string) (time.Time, error) { } } } - + // Fall back to GTime conversion for complex cases t, err := c.GTime(anyInput, format...) if err != nil { @@ -87,12 +87,12 @@ func (c *Converter) GTime(anyInput any, format ...string) (*gtime.Time, error) { if empty.IsNil(anyInput) { return nil, nil } - + // Check for custom interfaces first if v, ok := anyInput.(localinterface.IGTime); ok { return v.GTime(format...), nil } - + // Handle direct type matches when no format is specified if len(format) == 0 { switch v := anyInput.(type) { @@ -104,7 +104,7 @@ func (c *Converter) GTime(anyInput any, format ...string) (*gtime.Time, error) { return gtime.New(v), nil } } - + // Convert to string for parsing s, err := c.String(anyInput) if err != nil { @@ -113,7 +113,7 @@ func (c *Converter) GTime(anyInput any, format ...string) (*gtime.Time, error) { if len(s) == 0 { return gtime.New(), nil } - + // Handle format-specific conversion if len(format) > 0 { for _, item := range format { @@ -127,7 +127,7 @@ func (c *Converter) GTime(anyInput any, format ...string) (*gtime.Time, error) { } return nil, nil } - + // Handle numeric timestamps if utils.IsNumeric(s) { i, err := c.Int64(s) @@ -136,7 +136,7 @@ func (c *Converter) GTime(anyInput any, format ...string) (*gtime.Time, error) { } return gtime.NewFromTimeStamp(i), nil } - + // Parse as time string with timezone preservation return gtime.StrToTime(s) }