diff --git a/util/gconv/internal/converter/converter_builtin.go b/util/gconv/internal/converter/converter_builtin.go index 59e829dba..e864c5ddd 100644 --- a/util/gconv/internal/converter/converter_builtin.go +++ b/util/gconv/internal/converter/converter_builtin.go @@ -161,7 +161,7 @@ func (c *Converter) builtInAnyConvertFuncForGTime(from any, to reflect.Value) er // CONVERSION PATH 2: Structured Data Value Extraction // Theoretical basis: Extract semantic content from containers rather than // serializing containers themselves, which loses semantic context - case map[string]interface{}: + case map[string]any: // Common in ORM scenarios: {"column_name": gtime_value} // Instead of converting entire map to string (lossy), extract the gtime value if len(v) > 0 { diff --git a/util/gconv/internal/converter/converter_time.go b/util/gconv/internal/converter/converter_time.go index 9cb17f5a1..3fa253264 100644 --- a/util/gconv/internal/converter/converter_time.go +++ b/util/gconv/internal/converter/converter_time.go @@ -34,7 +34,10 @@ func (c *Converter) Time(anyInput any, format ...string) (time.Time, error) { // Handle map inputs by extracting the first value // 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 anyInput is a map with string keys, this block accesses its data directly. + // Timezone preservation is ensured by accessing the v.Time field directly, + // rather than converting time values to strings, which could lose timezone information. + if mapData, ok := anyInput.(map[string]any); ok { if len(mapData) == 0 { return time.Time{}, nil }