帰ってきた「しっぽのさきっちょ」

「プレミアムフライデー」を求めるパッケージを作ってみた — プログラミング言語 Go

そういえば先月の「プレミアムフライデー」,皆様はいかがお過ごしでしたか。 私は3時間も残業してしまいましたよ(笑)

ちうわけで,以下を真似して「プレミアムフライデー」を求めるパッケージを考えてみる。 もちろん息抜きである。 潤いは大事。 でも実用性はないと思われ。

まずはパッケージ分割しないでベタに書いてみる1

package main

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"
)

//GetPremiumFriday returns day of premium friday
func GetPremiumFriday(y int, m time.Month) (int, error) {
	//引数のチェック
    if y < 2017 || m < time.January || m > time.December {
		return 0, os.ErrInvalid
	}
	if y == 2017 && m < time.February { //2017年1月は実施前なのでエラー
		return 0, os.ErrInvalid
	}

	//指定月末(翌月0日)で初期化する
    tm := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC) //時差は影響しないので,とりあえず UTC で

    w := tm.Weekday() - time.Friday
	if w < 0 {
		w += 7
	}
	return tm.Day() - (int)(w), nil
}

func main() {
	flag.Parse()
	argsStr := flag.Args()
	if len(argsStr) < 2 {
		fmt.Fprintln(os.Stderr, "年月を指定してください")
		return
	}
	args := make([]int, 2)
	for i := 0; i < 2; i++ {
		num, err := strconv.Atoi(argsStr[i])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
		args[i] = num
	}
	d, err := GetPremiumFriday(args[0], time.Month(args[1]))
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	fmt.Println(d)
}

指定月末を求めるのに「翌月0日」で初期化するのがポイント(つか,ここしかポイントになるものがないw)。 実行結果は以下の通り。

$ go run pf.go 2017 2
24

期待通りの値が得られた。

関数1個だけなんでパッケージにするのもどうかと思うけど折角なのでパッケージ化してみた。

内容は GetPremiumFriday() 関数を切り出しただけ。

package pf

import (
	"os"
	"time"
)

//GetPremiumFriday returns day of premium friday
func GetPremiumFriday(y int, m time.Month) (int, error) {
	//引数のチェック
    if y < 2017 || m < time.January || m > time.December {
		return 0, os.ErrInvalid
	}
	if y == 2017 && m < time.February { //2017年1月は実施前なのでエラー
		return 0, os.ErrInvalid
	}

	//指定月末(翌月0日)で初期化する
    tm := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC) //時差は影響しないので,とりあえず UTC で

    w := tm.Weekday() - time.Friday
	if w < 0 {
		w += 7
	}
	return tm.Day() - (int)(w), nil
}

したがって main() 関数はこうなる。

package main

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/spiegel-im-spiegel/pf"
)

func main() {
	flag.Parse()
	argsStr := flag.Args()
	if len(argsStr) < 2 {
		fmt.Fprintln(os.Stderr, "年月を指定してください")
		return
	}
	args := make([]int, 2)
	for i := 0; i < 2; i++ {
		num, err := strconv.Atoi(argsStr[i])
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
		args[i] = num
	}
	d, err := pf.GetPremiumFriday(args[0], time.Month(args[1]))
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	fmt.Println(d)
}

まぁこんなもんかな。 遊んだ遊んだ。

ブックマーク

参考図書

photo
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
Alan A.A. Donovan Brian W. Kernighan 柴田 芳樹
丸善出版 2016-06-20
評価

スターティングGo言語 (CodeZine BOOKS) Go言語によるWebアプリケーション開発 Kotlinスタートブック -新しいAndroidプログラミング Docker実戦活用ガイド グッド・マス ギークのための数・論理・計算機科学

著者のひとりは(あの「バイブル」とも呼ばれる)通称 “K&R” の K のほうである。

reviewed by Spiegel on 2016-07-13 (powered by G-Tools)


  1. 元記事のコードがループさせてたんでこっちもついループさせちゃったけど,考えてみれば(いや考えるまでもなく)ループを回す必要はなかった。 [return]