Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@Hiraku

Goで今月の第4土曜日を計算する

More than 1 year has passed since last update.

PHPerだったので、これで済んでいた計算をGoに置き換えようとして、ぱっとライブラリが無さそうだったので真面目に実装した。

<?php
echo date_create("fourth saturday of this month")->format("c");

使う素材は公式のtimeパッケージのみとする。

考えたアルゴリズム

  1. 今月の1日を取得する
  2. 1日の曜日を調べて、土曜日までの日数を出す
  3. 最初の土曜日を計算
  4. 7日 * 3 = 21日うしろが第4土曜日のはず
package main

import (
    "errors"
    "fmt"
    "time"
)

func main() {
    jst := time.FixedZone("Asia/Tokyo", 9*60*60)
    fmt.Println(NthSaturday(4, jst))
}

func NthSaturday(n int, loc *time.Location) (time.Time, error) {
    now := time.Now().In(loc)

    if n <= 0 || 4 < n {
        return now, errors.New("there is no 5th saturday.")
    }

    year, month, _ := now.Date()
    firstDay := time.Date(year, month, 1, 0, 0, 0, 0, loc)
    firstSaturday := int(time.Saturday-firstDay.Weekday()) + 1
    nthSaturday := firstSaturday + (n-1)*7

    return time.Date(year, month, nthSaturday, 0, 0, 0, 0, loc), nil
}

汎用化して、任意の曜日で計算できるようにすると、こんな感じかな。

package main

import (
    "errors"
    "fmt"
    "time"
)

func main() {
    jst := time.FixedZone("Asia/Tokyo", 9*60*60)
    fmt.Println(NthWeekday(4, time.Monday, jst))
}

func NthWeekday(n int, wd time.Weekday, loc *time.Location) (time.Time, error) {
    now := time.Now().In(loc)

    if n <= 0 || 4 < n {
        return now, errors.New("there is no 5th weekday.")
    }

    year, month, _ := now.Date()
    firstDay := time.Date(year, month, 1, 0, 0, 0, 0, loc)
    first := int(wd-firstDay.Weekday()) + 1
    if first <= 0 {
        first += 7
    }
    nth := first + (n-1)*7

    return time.Date(year, month, nth, 0, 0, 0, 0, loc), nil
}

第5曜日を計算しようと思ったら、月によっては存在しない可能性があるので、エラーチェックがもう少し必要になる。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Hiraku
PHP, Go界隈をうろうろしています。最近はgRPCと戦ってる。 特に明示していなければ、記事中のソースコード片は `CC-0 1.0` とします。出典表示無しで自由にコピペして頂いて構いません。 ただ、記事自体をコピペされるのは嫌なので、ソースコード部分以外の文章は通常通り全ての著作権を私が保持するものとします。 引用を超える範囲のコピペは止めて下さい。
mercari
フリマアプリ「メルカリ」を、グローバルで開発しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?