Add direct *gtime.Time handling in Time converter

Co-authored-by: houseme <4829346+houseme@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-09-16 08:41:47 +00:00
parent 09eadcaa9e
commit 18dc6c2da1
2 changed files with 65 additions and 0 deletions

View File

@ -0,0 +1,61 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gtime_test
import (
"testing"
"time"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
)
// Test for issue #4429: gtime timezone preservation during struct conversion
func TestTime_Issue4429_TimezonePreservation(t1 *testing.T) {
gtest.C(t1, func(t *gtest.T) {
// Set local timezone to simulate the issue environment
originalLocation := time.Local
defer func() {
time.Local = originalLocation
}()
shanghaiLocation, _ := time.LoadLocation("Asia/Shanghai")
time.Local = shanghaiLocation
// Create a time with GMT timezone (like database result)
gmtLocation, _ := time.LoadLocation("GMT")
dbTime := time.Date(2025, 9, 15, 7, 45, 40, 0, gmtLocation)
gtimeVal := gtime.NewFromTime(dbTime)
// Simulate ORM Result.Structs() conversion
result := []map[string]interface{}{{"now": gtimeVal}}
var nowResult []time.Time
err := gconv.Structs(result, &nowResult)
t.AssertNil(err)
convertedTime := nowResult[0]
// The key assertion: timezone offset should be preserved
originalName, originalOffset := gtimeVal.Zone()
convertedName, convertedOffset := convertedTime.Zone()
// Offset must be preserved (this is the critical fix)
t.Assert(originalOffset, convertedOffset)
// Times should represent the same instant
t.Assert(gtimeVal.Time.Equal(convertedTime), true)
// Both should have 0 offset (GMT/UTC)
t.Assert(originalOffset, 0)
t.Assert(convertedOffset, 0)
// Note: Timezone name might change (GMT->UTC) but that's acceptable as long as offset is preserved
_ = originalName
_ = convertedName
})
}

View File

@ -22,6 +22,10 @@ func (c *Converter) Time(anyInput any, format ...string) (time.Time, error) {
if v, ok := anyInput.(time.Time); ok {
return v, nil
}
// Handle *gtime.Time directly to preserve timezone
if v, ok := anyInput.(*gtime.Time); ok {
return v.Time, nil
}
}
t, err := c.GTime(anyInput, format...)
if err != nil {