Golang中如何解析格式错误的XML UTC DateTime值?
解决Go中XML格式错误日期的解析问题
针对XML中同时存在带时区偏移和无偏移的日期格式导致解析失败的问题,有两种实用解决方案:
方案一:自定义时间类型实现XML反序列化接口
通过自定义类型替代原生time.Time,实现xml.Unmarshaler接口来兼容两种日期格式,这是最优雅的长期解决方案。
import ( "encoding/xml" "time" ) // CustomTime 自定义时间类型,兼容带时区和无时区的XML日期格式 type CustomTime time.Time const ( rfc3339WithOffset = "2006-01-02T15:04:05Z07:00" rfc3339NoOffset = "2006-01-02T15:04:05" ) // UnmarshalXML 实现xml.Unmarshaler接口,处理两种日期格式 func (ct *CustomTime) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var dateStr string if err := d.DecodeElement(&dateStr, &start); err != nil { return err } // 先尝试解析带时区偏移的标准格式 t, err := time.Parse(rfc3339WithOffset, dateStr) if err != nil { // 解析失败则尝试无时区格式,默认视为UTC时间 t, err = time.Parse(rfc3339NoOffset, dateStr) if err != nil { return err } t = t.UTC() } *ct = CustomTime(t) return nil } // Time 将自定义类型转换为原生time.Time,方便数据库存储 func (ct CustomTime) Time() time.Time { return time.Time(ct) }
使用方式
在XML结构体中直接使用CustomTime替代time.Time:
type XMLData struct { XMLName xml.Name `xml:"data"` EventDate CustomTime `xml:"eventDate"` }
解码时会自动处理两种日期格式,错误格式会被识别为UTC时间。
方案二:临时解析为字符串后手动处理
如果仅需处理单个字段,可先将日期解析为字符串,再手动兼容两种格式:
import ( "encoding/xml" "time" ) const ( rfc3339WithOffset = "2006-01-02T15:04:05Z07:00" rfc3339NoOffset = "2006-01-02T15:04:05" ) // 临时结构体,先将日期解析为字符串 type TempXML struct { XMLName xml.Name `xml:"data"` EventDateStr string `xml:"eventDate"` } func main() { xmlContent := []byte(`<data><eventDate>2020-06-29T11:11:04</eventDate></data>`) var temp TempXML if err := xml.Unmarshal(xmlContent, &temp); err != nil { // 处理解码错误 panic(err) } // 手动解析日期字符串 var eventTime time.Time var err error eventTime, err = time.Parse(rfc3339WithOffset, temp.EventDateStr) if err != nil { // 无时区格式则追加Z后解析(或直接解析后设为UTC) eventTime, err = time.Parse(rfc3339WithOffset, temp.EventDateStr+"Z") // 或者用无时区格式解析后转UTC: // eventTime, err = time.Parse(rfc3339NoOffset, temp.EventDateStr) // eventTime = eventTime.UTC() if err != nil { panic(err) } } // 此时eventTime可直接存入数据库 _ = eventTime }
两种方案对比:方案一适合多处复用的场景,代码更简洁;方案二更灵活,适合临时处理特定字段。
内容的提问来源于stack exchange,提问作者Dust_In_The_Wind
相关产品推荐
相关产品推荐

