LoginSignup
1
1

More than 5 years have passed since last update.

Go言語 xml.Unmarshal で string→time.Timeに変換する方法

Posted at

必要な場面

xmlのデータ上はstringな公開日時のようなパラメータを、Unmarshalしたらtime.Timeとしてあつかいたいとき。

unmarshal_test.go
import(
    "testing"
    "encoding/xml"
    "time"
)

// Item の定義
type Item struct {
    Title string            `xml:"title"`
    Link string             `xml:"link"`
    PublishedAt time.Time
}

// xml.Unmarshal 時にcallされるメソッドを独自実装
func (item *Item) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    // 生XMLを扱うための定義. PublishedAt は string であること
    raw := struct {
        Title string        `xml:"title"`
        Link string         `xml:"link"`
        PublishedAt string  `xml:"publishedAt"`
    }{}

    // デコード
    if err := d.DecodeElement(&raw, &start); err != nil {
        return err
    }

    // string to time.Time の変換処理
    timePub, err := time.Parse(time.RFC1123Z, raw.PublishedAt)
    if  err != nil {
        return err
    }

    // Itemを構築して返す
    *item = Item {
        raw.Title,
        raw.Link,
        timePub,
   }
    return nil
}

// テスト
func TestUnmarshalSelf(t *testing.T) {
    xmlData := `
    <item>
        <title>そうだ京都に行こう</title>
        <link>http://go-kyoto.com/</link>
        <publishedAt>Tue, 15 Mar 2016 11:08:00 +0900</publishedAt>
    </item>
    `

    item := Item{}
    err := xml.Unmarshal([]byte(xmlData), &item)
    if err != nil{
        t.Error("パースに失敗してるよ!")
    }

    if item.PublishedAt.IsZero() {
        t.Error("パースエラーだ!")
    }

    if item.PublishedAt.Year() != 2016 {
        t.Error("パースエラーだ!")
    }
}

日付処理については、Big Sky :: Go言語で日付処理が参考になりました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1