Skip to content

Commit ede4fbe

Browse files
authored
Merge pull request #704 from devlights:add-calc-nextmonth-example
Add time_calc_nextmonth.go
2 parents 1529c3c + 6e83f97 commit ede4fbe

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

examples/basic/times/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222
|time\_format\_datetime.go|time\_format\_datetime|Go1.20で追加された time.DateTime フォーマット書式についてのサンプルです|
2323
|time\_format\_dateonly.go|time\_format\_dateonly|Go1.20で追加された time.DateOnly フォーマット書式についてのサンプルです|
2424
|time\_format\_timeonly.go|time\_format\_timeonly|Go1.20で追加された time.TimeOnly フォーマット書式についてのサンプルです|
25+
|time\_calc\_nextmonth.go|time\_calc\_nextmonth|翌月の日付を求めるサンプルです|

examples/basic/times/examples.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ func (r *register) Regist(m mapping.ExampleMapping) {
3232
m["time_format_datetime"] = FormatDateTime
3333
m["time_format_dateonly"] = FormatDateOnly
3434
m["time_format_timeonly"] = FormatTimeOnly
35+
m["time_calc_nextmonth"] = CalcNextMonth
3536
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package times
2+
3+
import (
4+
"time"
5+
6+
"github.com/devlights/gomy/output"
7+
)
8+
9+
// CalcNextMonth は、翌月の日付を求めるサンプルです。
10+
//
11+
// # REFERENCES
12+
// - https://pkg.go.dev/time@go1.21.4
13+
func CalcNextMonth() error {
14+
//
15+
// 日付が範囲外の存在しない値になったとき、Goはその値を存在する日付に変換する。
16+
// この変換を「正規化」という。なので、翌月を求める際に元の値によっては
17+
// 翌々月となってしまうことがある。
18+
//
19+
20+
const (
21+
LOC = "Asia/Tokyo"
22+
)
23+
24+
var (
25+
jst, _ = time.LoadLocation(LOC)
26+
original = time.Date(2023, 10, 31, 0, 0, 0, 0, jst)
27+
)
28+
29+
output.Stdoutl("[original]", original.Format(time.RFC3339))
30+
31+
//
32+
// 11月には31日が存在しないため
33+
// そのままAddDateすると、正規化されて12月02日となってしまう。
34+
//
35+
36+
var (
37+
nextMonth1 = original.AddDate(0, 1, 1)
38+
)
39+
40+
output.Stdoutl("[nextmonth1]", nextMonth1.Format(time.RFC3339))
41+
42+
//
43+
// ちゃんと計算して求めるやり方 (書籍「実用 GO言語」)
44+
// 年月日以外の部分(時分秒とナノ秒)は面倒なので0固定
45+
//
46+
47+
var (
48+
year, month, day = original.Date() // 元の日付
49+
first = time.Date(year, month, 1, 0, 0, 0, 0, jst) // 元の日付の月初
50+
year2, month2, _ = first.AddDate(0, 1, 0).Date() // 月初の値を使って翌月の年と月を取得
51+
nextMonth2 = time.Date(year2, month2, day, 0, 0, 0, 0, jst) // 元の日付の日を当てて翌月値を仮作成
52+
)
53+
54+
if month2 != nextMonth2.Month() {
55+
// 正規化が発生して翌々月になってるので調整
56+
// - 2月進めて1日戻すと翌月の末日になる
57+
nextMonth2 = first.AddDate(0, 2, -1)
58+
}
59+
60+
output.Stdoutl("[nextmonth1]", nextMonth2.Format(time.RFC3339))
61+
62+
return nil
63+
}

0 commit comments

Comments
 (0)