PHPとGoの日時指定フォーマット比較表

PHPとGoの日時指定フォーマット比較表です。

# 日時指定フォーマット

PHPはdateの引数として、goではTime.Formatの引数として使用します。

| 説明                    | PHP(date)      | golang(pkg/time) |
|:------------------------|---------------:|-----------------:|
| 年(4桁)                 | Y              | 2006             |
| 年(2桁)                 | y              | 06               |
| 月(英語表記）           | F              | January          |
| 月(短縮系）             | M              | Jan              |
| 月(数値)                | n              | 1                |
| 月(ゼロ埋め)            | m              | 01               |
| 日(数値)                | j              | 2               |
| 日(ゼロ埋め)            | d              | 02               |
| 曜日(英語表記)          | l              | Monday           |
| 曜日(短縮系)            | D              | Mon              |
| 曜日(0〜6の数値)        | w              | *1               |
| 年間の通算日            | z              | *2               |
| 月の日数                | t              | *3               |
| 週番号                  | W              | *4               |
| タイムゾーン略称        | T              | MST              |
| GMTとの時差             | O              | -7000            |
| GMTとの時差(コロンあり) | P              | -07:00           |
| 午前または午後(小文字)  | a              | pm               |
| 午前または午後(大文字)  | A              | PM               |
| 時(24時間表記)          | G              | *5               |
| 時(24時間表記 ゼロ埋め) | H              | 15               |
| 時(12時間表記)          | g              | 3                |
| 時(12時間表記 ゼロ埋め) | h              | 03               |
| 分                      |                | 4                |
| 分(ゼロ埋め)            | i              | 04               |
| 秒                      |                | 5                |
| 秒(ゼロ埋め)            | s              | 05               |


PHPもGoどちらも組み合わせた書式として使用可能です。

```PHP:PHP
// cf. https://www.php.net/manual/ja/function.date.php
echo date('Y-m-d H:i:s', 981140706); // 2001-02-03 04:05:06
```

```Go:Go
// cf. https://golang.org/src/time/format.go
t := time.Unix(981140706, 0)
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2001-02-03 04:05:06
```


## *1 曜日(0〜6の数値)

Goで曜日(0〜6の数値)を取得しようとしたらTime.Weekday()を使用する。

```Go:Gp
// cf. https://golang.org/src/time/time.go#L521
t := time.Unix(981140706, 0)
fmt.Println(int(t.Weekday())) // 6

// intにキャストしなければ英語表記
fmt.Println(t.Weekday()) // Saturday
```


## *2 年間の通算日

Goで年間の通算日を取得しようとしたらTime.YearDay()を使用する。
ただしPHPはゼロから開始の0から364が、Goでは1から365が返却される。

```PHP:PHP
// 1546300800 = 2019-01-01 09:00:00
echo date('z', 1546300800); // 0

// 1577750400 = 2019-12-31 09:00:00
echo date('z', 1577750400); // 364
```

```Go:Go
t1 := time.Unix(1546300800, 0)
fmt.Println(t1.YearDay()) // 1

t2 := time.Unix(1577750400, 0)
fmt.Println(t2.YearDay()) // 365
```



## *3 月の日数

Goで月の日数(月末日)を取得するなら、翌月の月初からAddDateを使って-1日する。

```Go:Go
t := time.Date(2020, time.March, 1, 0, 0, 0, 0, time.UTC).AddDate(0, 0, -1)
fmt.Println(t.Day()) // 29
```


定常的に月の日数を必要とするのなら配列で定義しておき取得する処理を作った方が可読性はよさそうですが…

```Go:Go
var endMonth = [...]int{
    31,
    28,
    31,
    30,
    31,
    30,
    31,
    31,
    30,
    31,
    30,
    31,
}
```

## *4 週番号

Goで週番号を取得しようとしたらTime.ISOWeek()を使用する。

```Go:Go
t := time.Date(2018, time.December, 30 , 0, 0, 0, 0, time.UTC)
_, week := t.ISOWeek()
fmt.Println(week) // 52
```

## *5 時(24時間表記)

Goでゼロ埋めされていない時刻（24時間表記）を取得するならTime.Hour()を使用する。

```Go:Go
t1 := time.Date(2019, time.March, 1, 9, 0, 0, 0, time.UTC)
fmt.Println(t1.Hour()) // 9
t2 := time.Date(2019, time.March, 1, 14, 0, 0, 0, time.UTC)
fmt.Println(t2.Hour()) // 14
```

時分秒を取得したい場合にはTime.Clock()もある。

```Go:Go
// cf. https://golang.org/src/time/time.go#L592
t := time.Date(2019, time.March, 1, 9, 6, 3, 0, time.UTC)
hour, minute, second := t.Clock()
fmt.Printf("%v:%v:%v", hour, minute, second) // 9:6:3
```

# 番外編

GoでもPHPと同じような日時指定のやりかたとして[Beego Framework](https://beego.me/)を使うという方法もあります。※Buildしたバイナリサイズが大きくなるのでオススメはしませんが…

```Go:Go
package main

import (
    "github.com/astaxie/beego"
    "time"
    "fmt"
)

func main() {
    t := time.Now()
    date := beego.Date(t, "Y-m-d D")
    fmt.Printf("date = %s\n", date)
}
```


# 最後に

内容に誤りがあれば教えて頂けたら幸いです。
ここまで読んでいただき、ありがとうございました。