Go言語の日付操作について解説
Go言語で日付を操作する方法について簡単に説明します。
組み込みパッケージtimeを使って日付の取得やフォーマット、パースなどの基本操作を実践します。
実際に手を動かしながら学べるため、すでに開発環境が整っている方にも役立つ内容です。
timeパッケージと基本
timeパッケージの概要
Go言語の標準ライブラリに含まれるtimeパッケージは、日付や時刻の操作を簡単に実現できるように設計されています。
このパッケージでは、現在時刻の取得、日付のフォーマット、タイムゾーンの操作、時間の計算などが可能です。
シンプルなAPIでありながら多機能なため、幅広い場面で活用することができます。
主要な型と基本メソッド
timeパッケージで中心となる型はtime.Timeです。
この型は日付情報を保持しており、年、月、日、時、分、秒などの情報にアクセス可能です。
また、time.Duration型は時間の長さを表現するために利用され、例えばタイマーやスリープ処理などで活用されます。
以下は、基本的な型やメソッドの使用例です。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在の時刻を取得
	currentTime := time.Now()
	// 現在の年、月、日、時、分、秒を取得して表示するサンプル
	fmt.Println("現在時刻:", currentTime.Format("2006-01-02 15:04:05"))
	// 1時間のDurationを生成し、現在時刻に加算する
	duration := time.Hour
	futureTime := currentTime.Add(duration)
	fmt.Println("1時間後:", futureTime.Format("2006-01-02 15:04:05"))
}現在時刻: 2023-10-01 14:30:00
1時間後: 2023-10-01 15:30:00日付の取得方法
現在の日付と時刻の取得
Go言語では、time.Now()を利用して現在の日時を取得することができます。
この関数はシステムのローカルタイムゾーンに基づいたtime.Time型の値を返します。
以下はサンプルコードです。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在の日付と時刻を取得する
	currentTime := time.Now()
	// デフォルトのフォーマットで表示
	fmt.Println("現在の日時:", currentTime)
}現在の日時: 2023-10-01 14:30:00.123456789 +0900 JSTタイムゾーンの設定と調整
Goでは、タイムゾーンの設定や調整も柔軟に行うことができます。
time.LoadLocationを用いることで、指定した地域のタイムゾーン情報を取得し、time.Timeの表示や計算に反映させることが可能です。
ローカルタイムとUTCの違い
ローカルタイムはシステムや指定したタイムゾーンに基づいた時刻を表現します。
一方、UTCは協定世界時で、タイムゾーンに依存しない標準時刻です。
例えば、ローカルタイムをUTCに変換する場合、UTC()メソッドを用います。
以下は変換例です。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在のローカル時刻を取得する
	currentTime := time.Now()
	fmt.Println("ローカル時刻:", currentTime)
	// ローカル時刻をUTCに変換する
	utcTime := currentTime.UTC()
	fmt.Println("UTC時刻:", utcTime)
}ローカル時刻: 2023-10-01 14:30:00.123456789 +0900 JST
UTC時刻: 2023-10-01 05:30:00.123456789 +0000 UTCUnix時間との連携
Unix時間とは、1970年1月1日00:00:00 UTCからの経過秒数を指します。
Goでは、time.Unix(sec, nsec int64)を用いてUnix時間からtime.Timeオブジェクトを生成したり、Time.Unix()メソッドでUnix時間を取得することができます。
以下にサンプルコードを示します。
package main
import (
	"fmt"
	"time"
)
func main() {
	// Unixタイムスタンプを用いてtime.Timeを生成する
	sec := int64(1696141800) // 例: 2023-10-01 14:30:00 UTC
	timeFromUnix := time.Unix(sec, 0)
	fmt.Println("Unixから生成した時刻:", timeFromUnix)
	// 現在時刻のUnixタイムスタンプを取得する
	currentTime := time.Now()
	unixTime := currentTime.Unix()
	fmt.Println("現在時刻のUnixタイムスタンプ:", unixTime)
}Unixから生成した時刻: 2023-10-01 14:30:00 +0000 UTC
現在時刻のUnixタイムスタンプ: 1696165800日付のフォーマット
フォーマット形式とレイアウト
レイアウトパターンの指定方法
Go言語では、フォーマットのために特定のレイアウトパターンを使用します。
レイアウトパターンは、リファレンスタイムである
Mon Jan 2 15:04:05 MST 2006
の各要素の並びを基に指定します。
例えば、2006-01-02 15:04:05は「年-月-日 時:分:秒」という形式です。
RFC3339やUnix形式の使用例
timeパッケージには、あらかじめ定義された定数が用意されています。
たとえば、time.RFC3339を指定すると、RFC3339形式のフォーマットが適用されます。
以下にサンプルコードを示します。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在時刻を取得する
	currentTime := time.Now()
	// RFC3339形式で出力
	rfc3339Formatted := currentTime.Format(time.RFC3339)
	fmt.Println("RFC3339形式:", rfc3339Formatted)
	// Unix形式(秒数)で出力
	unixFormatted := fmt.Sprintf("%d", currentTime.Unix())
	fmt.Println("Unix形式:", unixFormatted)
}RFC3339形式: 2023-10-01T14:30:00+09:00
Unix形式: 1696165800カスタマイズした出力例
必要に応じて、独自のレイアウト文字列を指定することで、カスタマイズしたフォーマットも可能です。
下記の例では、YYYY年MM月DD日 HH時MM分SS秒の形式に変換しています。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在時刻を取得する
	currentTime := time.Now()
	// カスタムレイアウトを指定してフォーマット
	customLayout := "2006年01月02日 15時04分05秒"
	formattedTime := currentTime.Format(customLayout)
	fmt.Println("カスタムフォーマット:", formattedTime)
}カスタムフォーマット: 2023年10月01日 14時30分00秒文字列から日付への変換(パース)
パースの基本手順
文字列からtime.Time型に変換するには、time.Parse関数を用います。
この関数は、レイアウトと変換対象の文字列を受け取り、正しく解析できた場合にtime.Time型の値を返します。
以下は基本的なパース例です。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 日付文字列とレイアウトを指定して解析する
	const layout = "2006-01-02 15:04:05"
	dateString := "2023-10-01 14:30:00"
	parsedTime, err := time.Parse(layout, dateString)
	if err != nil {
		fmt.Println("パースエラー:", err)
		return
	}
	fmt.Println("パースした時刻:", parsedTime)
}パースした時刻: 2023-10-01 14:30:00 +0000 UTC独自フォーマットのパース方法
独自に定義したフォーマットの日付文字列を解析する場合も、同様にtime.Parseを利用します。
レイアウト文字列でリファレンスタイムの値を基に指定する必要があります。
以下のサンプルでは、カスタムレイアウトを用いてパースを行っています。
package main
import (
	"fmt"
	"time"
)
func main() {
	// カスタムフォーマットのレイアウトを指定する
	customLayout := "2006年01月02日 15時04分05秒"
	dateString := "2023年10月01日 14時30分00秒"
	// 日付文字列をパースする
	parsedTime, err := time.Parse(customLayout, dateString)
	if err != nil {
		fmt.Println("パースエラー:", err)
		return
	}
	fmt.Println("パースした時刻:", parsedTime)
}パースした時刻: 2023-10-01 14:30:00 +0000 UTC日付計算と操作
日付の加算・減算
time.Time型の値に対して、Addメソッドでtime.Durationを加算または減算することで、日付の計算が可能です。
プラスのDurationを指定すれば未来の日付、マイナスのDurationで過去の日付を取得します。
以下は加算と減算のサンプルです。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 現在時刻を取得する
	currentTime := time.Now()
	// 2日後を計算する
	twoDaysAfter := currentTime.Add(48 * time.Hour)
	fmt.Println("2日後:", twoDaysAfter.Format("2006-01-02 15:04:05"))
	// 3時間前を計算する
	threeHoursBefore := currentTime.Add(-3 * time.Hour)
	fmt.Println("3時間前:", threeHoursBefore.Format("2006-01-02 15:04:05"))
}2日後: 2023-10-03 14:30:00
3時間前: 2023-10-01 11:30:00期間の差分計算
2つの日付間の差分は、Subメソッドを用いることで求めることができます。
このメソッドは、2つの日付の差分をtime.Duration型で返します。
ここで得たDurationは、秒、分、時間など様々な単位に変換可能です。
下記は差分計算の例です。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 基準となる2つの日付を定義する
	time1 := time.Date(2023, 10, 01, 14, 30, 00, 0, time.UTC)
	time2 := time.Date(2023, 10, 03, 14, 30, 00, 0, time.UTC)
	// 差分を計算する(Duration型で返される)
	duration := time2.Sub(time1)
	fmt.Println("期間の差分(時間):", duration.Hours())
}期間の差分(時間): 48日付の比較方法
日付の大小比較には、Before、After、Equalの各メソッドを利用することができます。
Before: 指定した日付より前の日付かどうかを判定するAfter: 指定した日付より後の日付かどうかを判定するEqual: 2つの日付が等しいかどうかを判定する
以下は比較のサンプルコードです。
package main
import (
	"fmt"
	"time"
)
func main() {
	// 2つの時刻を定義する
	timeA := time.Date(2023, 10, 01, 10, 00, 00, 0, time.UTC)
	timeB := time.Date(2023, 10, 01, 12, 00, 00, 0, time.UTC)
	// timeAがtimeBより前かどうかを判定する
	if timeA.Before(timeB) {
		fmt.Println("timeAはtimeBより前の日付です。")
	}
	// timeBがtimeAより後かどうかを判定する
	if timeB.After(timeA) {
		fmt.Println("timeBはtimeAより後の日付です。")
	}
	// 等しいかどうかを判定する
	if timeA.Equal(timeA) {
		fmt.Println("timeAとtimeAは同じ日付です。")
	}
}timeAはtimeBより前の日付です。
timeBはtimeAより後の日付です。
timeAとtimeAは同じ日付です。まとめ
この記事では、Go言語のtimeパッケージの概要や各種日付操作について具体例を用いて解説しましたでした。
各セクションでは、取得、フォーマット、パース、計算、比較などの操作方法をコード例で示し、直感的に把握できる内容にまとめています。
ぜひ、実際にコードを動かして、操作方法を試してみてください。