thumbnail
thumbnail

【GO言語】13日の金曜日カレンダーを作るよ

updated 2021-8-19

なぜ13日の金曜日なの

GO言語の説明より前にこれは、思うところかもしれないですね
とある実況がありましていつも見ているのですが、そのイベント的な動画が13日の金曜日にFriday the 13thをやると言うもので
見たいんですよ...当日にね

Go言語とは

GO言語入門がてら作るんで、詳しくはないです

Webサービスとかスマホアプリとかドローン開発に使え、 Googleが開発した高速なプログラミング言語で、Youtubeとかぐるなびとかに使われているそうです C言語に書き方が似ているらしい

インストール

とりあえずコンパイルできるようにインストール

brew install go

インストール終わったら動くか確認

go version
// go1.16.6 darwin/amd64

あとVSCodeの拡張機能でGoを入れた

フレームワークの導入

シンプルなGoだけで書いてみたいところですが、今回はカレンダーというか複雑な機能がいるかも?と思い、フレームワーク使ってみます
echoっていうフレームワークです

アプリの作成

mkdir friday-the-13th
cd fryday-the-13th
// config file
go mod init friday-the-13th
// install module
go get github.com/labstack/echo/v4

公式の指示に沿ってserver.goを作成する

package main

import (
	"net/http"
	
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.Logger.Fatal(e.Start(":1323"))
}
go run server.go

ここは無事Hello World

メインページを表示させる

main.goも書き換え

func Home(c echo.Context) error {
	return c.Render(http.StatusOK, "hello", "World")
}
...
func main() {
	e := echo.New()
	e.GET("/", Home)
	e.Logger.Fatal(e.Start(":1323"))
}

public/views/home.htmlを作成する

{{ define "home" }}
<!DOCTYPE html>
<html>
    <head>
        <title>Friday the 13th</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
    </head>
    <body>
       <h1>Friday the 13th</h1>
       <ul>

       </ul>
    </body>
</html>
{{ end }}

カレンダー必要ない問題

カレンダーあっても年に1回あるかないか分からない程度のものをカレンダーにする必要があるのか...いやない とりあえず100年ごぐらいまで取得してみます

import (
    "fmt"
    "time"
    "github.com/labstack/echo/v4"
)
...
func day() {
    n := time.Now()
    // start & end
    s := time.Date(n.Year(), n.Month(), n.Day(), 0, 0, 0, 0, time.Local)
    e := time.Date(n.Year() + 10, n.Month(), n.Day(), 0, 0, 0, 0, time.Local)
    fmt.Println(s)
    fmt.Println(e)
}

同じ月の10年後まで取得した

13日の金曜日かどうか

startとendの日付を受け取ったら、time.Time方の配列で13日の金曜日を返すようにする

func fridayThe13th(s time.Time, e time.Time) []time.Time {
    array := []time.Time{}
	i := s
	for {
		if i.Day() == 13 && i.Weekday() == time.Friday {
			array = append(array, i)
			fmt.Println(i)
		}
		if i == e {
			break
		}
 		i = i.AddDate(0, 0, 1)
	}
	return array
}

これをday関数で呼び出して表示させる

func day() {
    n := time.Now()
    // start & end
    s := time.Date(n.Year(), n.Month(), n.Day(), 0, 0, 0, 0, time.Local)
    e := time.Date(n.Year() + 10, n.Month(), n.Day(), 0, 0, 0, 0, time.Local)
    days := fridayThe13th(s, e)
}

Herokuにデプロイ

Herokuのにデプロイするときはポートを自分で指定できないので、環境変数のポートを拾う必要があります
なので、port指定部分を変えます

import (
	"net/http"
	"time"
	"html/template"
	"io"
	"os"
	
	"github.com/labstack/echo/v4"
)

...

func main() {
	t := &Template{
		templates: template.Must(template.ParseGlob("views/*.html")),
	}
	port := ":5000"
	if os.Getenv("PORT") != "" {
		port = ":" + os.Getenv("PORT")
	}
	e := echo.New()
	e.Renderer = t
	e.GET("/", Home)
	e.Logger.Fatal(e.Start(port))
}

デフォルトのポートは5000で環境変数にPORTがあったら上書きしてます

デプロイ

Heroku Gitを使ってデプロイするので、remoteにherokuを追加します

heroku create アプリ名 
heroku git:remote -a アプリ名
git add .
git commit -m "[build] change port"
git push heroku master

ビルドが終わったら

heroku open -a アプリ名

作成したアプリ

スタイルはソース汚さない程度にしかいじってないのでシンプルですがデプロイまでできました
ソースはGithubに置いておきます

Github

参考

テンプレートレンダリング カレンダー作成問題の解答 Go言語編
逆引きGolang (日付と時刻)
go言語のslice操作をまとめてみた(shiftしたりpushしたり)
Go言語で今月から標準入力で受けたyyyy-mmまでの各月の月初と月末を一覧表示する簡単なコマンドラインアプリを作ってみた
golang 関数(func)の引数や戻り値で関数を指定したときの動作
Golang の echo を使う (template)
golangで環境変数扱う Gopher画像