この記事は J2complexed Advent Calendar 2017 の1日目の記事です。
プレミアムフライデー!
今年の流行語大賞に「プレミアムフライデー」が受賞したという話を聞きました。
http://singo.jiyu.co.jp/award/award2017.html#prize08
ところで月末金曜日って微妙じゃないですか?
なにが微妙かというと、JavaScriptで月末金曜日が何日か出すのが微妙。
やり方はいろいろあるかと思いますが、今回は日付を処理をするときに便利なライブラリ「date-fns」を使ってやってみたいと思います。
date-fns
日付処理をするときは大体の人がmoment.jsを使っていたかと思います。
公式でもmoment.jsとの違いを書いていました。
https://github.com/date-fns/date-fns/issues/275#issuecomment-264934189
要約すると、以下でしょうか。(英語も日本語も苦手です。編集リクエストお待ちしてます)
- moment.jsはmutableなので、バグが起こりやすい
- moment.jsはパフォーマンスよくない
- moment.jsはでかい
それに対してdate-fns.jsは以下だと言っています。
- date-fns.jsはImmutableだ。
- date-fns.jsは純粋な関数だから、必要なものだけ使えばいい。
(つまり、オーバーヘッドが少ないし、サイズも小さい)
いい感じですね。関数も130種類以上あるそうですよ。
興味があれば、公式を見てください。
では、実際に使ってプレミアムフライデーを出してみましょう。
準備
公式にあるように準備します。ここらへんは普通なので、コマンドと用意したファイルだけご紹介します。
※ date-fnsとは関係ないのですが、babelを入れてます。
~ $ mkdir premium-friday
~ $ premium-friday
~/premium-friday $ npm init
~/premium-friday $ npm i -D date-fns
~/premium-friday $ npm i -D babel-cli babel-preset-es2015
~/premium-friday $ vi package.json
~/premium-friday $ vi .babelrc
~/premium-friday $ mkdir src
{
"name": "premium-friday",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "babel src -d dest"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"date-fns": "^1.29.0"
}
}
{
"presets": ["es2015"]
}
できましたか?
プレミアムフライデー
で、書いてみました。
import endOfMonth from 'date-fns/end_of_month'
import isFriday from 'date-fns/is_friday'
import addWeeks from 'date-fns/add_weeks'
import lastDayOfWeek from 'date-fns/last_day_of_week'
import format from 'date-fns/format'
import isToday from 'date-fns/is_today'
const today = new Date ()
// 月末を取得
const EndOfMonth = endOfMonth (today)
let premiumFriday
// 金曜日かどうか
if (isFriday (EndOfMonth)) {
premiumFriday = EndOfMonth
} else {
// 前の週を取得
const previousWeek = addWeeks (EndOfMonth, -1)
// その周の終わりを取得(週の始まりを土曜日にする)
premiumFriday = lastDayOfWeek (previousWeek, {weekStartsOn: 6})
}
// フォーマット
const month = format (premiumFriday, 'MMMM')
const day = format (premiumFriday, 'D')
console.log (`${month} Premium Friday is ${day}!`)
// もし今日がプレミアムフライデーなら
if (isToday(premiumFriday)) {
console.log (`Today is Premium Friday! Yeah!`)
}
以下のようにコマンドを叩けば実行できます
~/premium-friday $ npm run build
> babel src -d dest
src/index.js -> dest/index.js
~/premium-friday $ node dest
December Premium Friday is 29!
Premium Friday! Yeah!
プレミアムフライデーできましたでしょうか?
ちなみにdest/index.jsのファイルサイズは2KBでした。小さい。
まとめ
date-fnsを使って、複雑な日付の処理を簡単に書けました。
もし機会があれば、いつものmoment.jsではなくdate-fns.jsを使ってみてはいかがでしょうか。
ところで、今月のプレミアムフライデーって29日なんですね。。。
微妙。
参考
- ドキュメント
https://date-fns.org/ - Github
https://github.com/date-fns/date-fns