Go解析JSON时将hh:mm:ss转换为time.Time的类型匹配问题
解析含时分秒字符串的JSON到不可修改的time.Time字段
由于无法修改原SomeType结构体,我们可以通过两种实用方式完成解析:
方法一:中间结构体中转
这是最直观的方案,先将JSON解析到字段类型兼容的临时结构体,再转换为目标结构体:
- 定义临时结构体,将
time字段改为string类型以匹配JSON格式:
type TempSomeType struct { name string `json:"name"` time string `json:"someTime"` }
- 读取并解析JSON到临时结构体数组:
import ( "encoding/json" "log" "os" "time" ) func main() { // 读取JSON文件 data, err := os.ReadFile("someData.json") if err != nil { log.Fatal(err) } var tempItems []TempSomeType if err := json.Unmarshal(data, &tempItems); err != nil { log.Fatal(err) }
- 转换临时数据到目标结构体数组,同时处理时间字符串:
var items []SomeType // 指定时间格式,匹配JSON中的"HH:mm:ss" const timeLayout = "15:04:05" for _, temp := range tempItems { parsedTime, err := time.Parse(timeLayout, temp.time) if err != nil { log.Fatalf("解析时间失败: %v", err) } // 若需要指定日期,可使用time.Date拼接,示例为2024-01-01 // parsedTime = time.Date(2024, 1, 1, parsedTime.Hour(), parsedTime.Minute(), parsedTime.Second(), 0, time.UTC) items = append(items, SomeType{ name: temp.name, time: parsedTime, }) } }
方法二:直接使用JSON解码器解析
无需定义临时结构体,通过json.Decoder逐个解析数组元素,用map临时存储字段后转换:
import ( "encoding/json" "log" "os" "time" ) func main() { file, err := os.Open("someData.json") if err != nil { log.Fatal(err) } defer file.Close() var items []SomeType decoder := json.NewDecoder(file) // 跳过数组开头的'[' if _, err := decoder.Token(); err != nil { log.Fatal(err) } const timeLayout = "15:04:05" // 遍历数组内的每个对象 for decoder.More() { var rawItem map[string]interface{} if err := decoder.Decode(&rawItem); err != nil { log.Fatal(err) } name := rawItem["name"].(string) timeStr := rawItem["someTime"].(string) parsedTime, err := time.Parse(timeLayout, timeStr) if err != nil { log.Fatalf("解析时间失败: %v", err) } items = append(items, SomeType{ name: name, time: parsedTime, }) } // 跳过数组结尾的']' if _, err := decoder.Token(); err != nil { log.Fatal(err) } }
注意事项
- 时间格式字符串
"15:04:05"必须严格匹配JSON中的时间格式,其中15代表24小时制小时,04为分钟,05为秒。 - 转换后的
time.Time默认日期为0001-01-01,若业务需要指定日期,可通过time.Date方法拼接所需日期。
内容的提问来源于stack exchange,提问作者Glenn
相关产品推荐
相关产品推荐

