Golangで日付のフォーマット

Category:
Last Updated: 2022/02/09 03:25:35

Go言語の time パッケージのフォーマットの扱いには少し慣れが必要なので、こちらでまとめておく。


# 日付を文字列にフォーマットする

# 基本的なフォーマットの仕方

日付を文字列にする際、Go言語の場合は下記のように、2006-01-02 15:04:05 -07:00(MST) の場合の具体的な日付でフォーマットの指定を行う。

package main

import (
	"fmt"
	"time"
)
func main() {
	t := time.Now()
	fmt.Println(string(t.Format("2006-01-02 15:04:05")),"\n") // 2022-01-05 14:57:24 
}
1
2
3
4
5
6
7
8
9
10

なぜこのような日付なのかというと、アメリカ式の下記のフォーマットで1,2,3と順番に数値を当てはめていったらこうなった、ということのようである。

Layout      = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
1

# 使えるフォーマットの種類

time/format.go (opens new window)にはさまざまなフォーマットの指定があるのでそちらを読むのがわかりやすいと思うが、それでも個人的には少しわかりにくい気がしているので、ここでざっくりとまとめておく。

フォーマット 説明
2006 年。4桁の数字。
06 年。下2桁の数字。
1 月。数字。先頭にゼロをつけない。
01 月。数字。先頭にゼロをつける。
Jan 月。3文字。
January 月。フルスペル。
2 日。先頭にゼロをつけない。
02 日。先頭にゼロをつける。
_2 日。1桁の場合は先頭にスペース追加
曜日 Mon 曜日。3文字。
Monday 曜日。フルスペル。
Monday 曜日。フルスペル。
15 時間。24時間表記。先頭にゼロをつける。
03 時間。12時間表記。先頭にゼロをつける。
3 時間。12時間表記。先頭にゼロをつけない。
PM 午前ならAM、午後ならPM
pm 午前ならam、午後ならpm
04 分。先頭にゼロをつける。
4 分。先頭にゼロをつけない。
05 秒。先頭にゼロをつける。
5 秒。先頭にゼロをつけない。
タイムゾーン MST タイムゾーンの名前。日本の場合は(Asia/Tokyoではなく)JST
Z0700 時差表記。日本の場合、"+0900" だが、UTCの場合は"Z"となる。
Z07:00 時差表記。日本の場合、"+09:00" だが、UTCの場合は"Z"となる。
-07:00 タイムゾーン。日本の場合、"+09:00"
-0700 タイムゾーン。日本の場合、"+0900"
-07 タイムゾーン。日本の場合、"+09"

ちなみに24時間における0時の場合12 AMとなり、12時の場合12 PMという扱いになるので、日本人の(少なくとも私自身の)直感とは微妙に異なっている気がする。(個人的には0〜12時はAMのほうが自然な感じがするが、そうなるとAMに該当する時間は13時間、PMに該当する時間は11時間になってしまうので、それはそれで微妙かも知れない)


# 定型フォーマット

実際には定型的なフォーマットはtime/format.go (opens new window)に定義されているので、極力、こちらを使うほうがミスがなくてわかりやすいような気がする。

const (
	Layout      = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
	ANSIC       = "Mon Jan _2 15:04:05 2006"
	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
	RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
	RFC822      = "02 Jan 06 15:04 MST"
	RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
	RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
	RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
	RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
	RFC3339     = "2006-01-02T15:04:05Z07:00"
	RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
	Kitchen     = "3:04PM"
	// Handy time stamps.
	Stamp      = "Jan _2 15:04:05"
	StampMilli = "Jan _2 15:04:05.000"
	StampMicro = "Jan _2 15:04:05.000000"
	StampNano  = "Jan _2 15:04:05.000000000"
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

例えばデータベースへの保存、取得であれば自分でフォーマットを書くよりも、下記のように機会的に RFC3339 に変換するのがよさそうである。

t := time.Now()
fmt.Println(string(t.Format(time.RFC3339)),"\n") // 2022-01-05T15:42:15+09:00
1
2

# フォーマット文字列をtime.Time変数に変換する

Go言語では文字列を日付として読み込むにはtime.Parse関数を使う。

t, err := time.Parse("2006-01-02 15:04:05", "2022-01-05 15:42:15")
if err != nil {
	panic(err)
}
fmt.Println(t) // 2022-01-05 15:42:15 +0000 UTC
1
2
3
4
5

実際にはすでに説明したように、RFC3339など主要な日付フォーマットはtimeパッケージ内に定義されているので、それをそのまま使うのがよいと思う。

t, err := time.Parse(time.RFC3339, "2022-01-05T15:42:15+09:00")
if err != nil {
	panic(err)
}
fmt.Println(t) // 2022-01-05 15:42:15 +0900 JST
1
2
3
4
5

time.Parse は末尾にスペースが入っていたり日付の桁数が少しでも違ったりするとうまくいかないので、実際には自分でフォーマットの指定は一切行わずにすべて定数のみを使うほうが安全な気がする。

# おまけ: Golangで自由にフォーマットする

time.Parse は個人的にあまり使いやすくはないので、自前で日付処理用のライブラリを作成した。

go-timeparser (opens new window)

import "github.com/kaz-yamam0t0/go-timeparser/timeparser"

// tdata, _ := Now()
// tdata, _ := New("2022-01-31 11:22:33.123456789")

// tdata, _ := NewAsUTC("2022-01-31 11:22:33.123456789")
tdata, _ := NewAsUTC("31st Jan 2022 11:22:33.123456789")

// 
// If you want to adjust the timezone offset difference from your local env, 
// first create a variable with `New()` and then convert it to UTC with `SetUTC()`
// 
// tdata, _ := New("2022-01-31 11:22:33.123456789")
// tdata.SetUTC()

fmt.Println(tdata.GetYear())        // 2022
fmt.Println(tdata.GetMonth())       // 1
fmt.Println(tdata.GetDay())         // 31
fmt.Println(tdata.GetHour())        // 11
fmt.Println(tdata.GetMinute())      // 22
fmt.Println(tdata.GetSecond())      // 33
fmt.Println(tdata.GetMillisecond()) // 123
fmt.Println(tdata.GetMicrosecond()) // 123456
fmt.Println(tdata.GetNanosecond())  // 123456789

// 
// Format
// 
fmt.Println(tdata.String()) // 2022-01-31T11:22:33+00:00
fmt.Println(tdata.Format("l jS \\of F Y h:i:s A")) // Monday 31st of January 2022 06:22:33 PM

// 
// Setter methods
// 
tdata.SetYear(2022)
tdata.SetMonth(1)
tdata.SetDay(31)
tdata.SetHour(11)
tdata.SetMinute(22)
tdata.SetSecond(33)

// 
// Difference 
// 
tm, _ := NewAsUTC("2020-12-31 11:22:33.123456789")
fmt.Println(tdata.DiffYears(tm))   // 1
fmt.Println(tdata.DiffMonths(tm))  // 13
fmt.Println(tdata.DiffDays(tm))    // 396
fmt.Println(tdata.DiffHours(tm))   // 9504
fmt.Println(tdata.DiffMinutes(tm)) // 570240
fmt.Println(tdata.DiffSeconds(tm)) // 34214400
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

Category:
Last Updated: 2022/02/09 03:25:35
Copyright © Web Ninja All Rights Reserved.