元となるソースはGitHub上にあります。
共通
共通的に必要となる定義を示します。フォーマット変換するので、プラグインを入れるのがポイントです。
const dayjs = require("dayjs");
// プラグインの追加
dayjs.extend(require("dayjs/plugin/customParseFormat"));
// フォーマット
const YYYYMMDD = "YYYYMMDD";
const YYYYMMDD_HHmmss = "YYYYMMDD HHmmss";
const YYYYMMDD_HHmmss_SSS = "YYYYMMDD HHmmss.SSS";
エラー判定処理
Day.jsの癖として、日付処理ができない場合は「Invalid Date」という文字列を返します(細かいことはわかりませんが。)。それを利用したエラー判定を行います。これは下で示していく自作APIが処理エラー時にnullを返したいために作られました。
function isValidDate(day) {
if (typeof day === "string") {
return day === "Invalid Date" ? null : day;
}
return day.isValid() ? day : null;
}
年齢計算
diff()のポイントは、基準日に対し過去が正の値・未来が負の値となることです。つまり基準日.diff(過去日) > 0 で、基準日.diff(未来日) < 0 です。
/**
* 年齢計算
* @param {string} baseDate 年齢計算の基準日 YYYYMMDD
* @param {string} birthday 生年月日 YYYYMMDD
* @returns 満年齢 or null(計算不可).誕生日に年をとる.
*/
exports.calcAge = (baseDate, birthday) => {
let base = dayjs(baseDate, YYYYMMDD, true);
let birth = dayjs(birthday, YYYYMMDD, true);
// 日付をパースできない.
if (!isValidDate(base) || !isValidDate(birth)) {
return null;
}
let ibase = Number( base.format(YYYYMMDD) );
let ibirth = Number( birth.format(YYYYMMDD) );
return Math.floor( (ibase - ibirth)/10000 );
};
日付計算(年)
日付計算において、年・月・日の加減算はadd()の引数に"year"、"month"、"day"を指定することで計算を行う。
/**
* 日付計算(年)
* @param {string} baseDate 基準日 YYYYMMDD
* @param {number} year 加減算する年
* @returns {string|null} 加減算後の日付 YYYYMMDD
*/
exports.addYears = (baseDate, year) => {
return isValidDate(
dayjs(baseDate, YYYYMMDD, true).add(year, "year").format(YYYYMMDD)
);
};
日付計算(月)
/**
* 日付計算(月)
* @param {string} baseDate 基準日 YYYYMMDD
* @param {number} month 加減算する月
* @returns {string|null} 加減算後の日付 YYYYMMDD
*/
exports.addMonths = (baseDate, month) => {
return isValidDate(
dayjs(baseDate, YYYYMMDD, true).add(month, "month").format(YYYYMMDD)
);
};
日付計算(日)
/**
* 日付計算(日)
* @param {string} baseDate 基準日 YYYYMMDD
* @param {number} day 加減算する日
* @returns {string|null} 加減算後の日付 YYYYMMDD
*/
exports.addDays = (baseDate, day) => {
return isValidDate(
dayjs(baseDate, YYYYMMDD, true).add(day, "day").format(YYYYMMDD)
);
};
日付フォーマッター
/**
* 日付フォーマット
* @param {string} baseDate 日付日時
* @param {string} format フォーマット. フォーマット形式はDay.js参照.
* @returns {string|null} フォーマット後日付
*/
exports.format = (baseDate, format) => {
return isValidDate(dayjs(baseDate).format(format));
};
月末算出
ライブラリが優秀なので、うるう年も対応しています。
/**
* 月末の日付を返す.
* @param {string} baseDate 日付 YYYYMMDD or YYYYMM
* @returns {string|null} 月末日付 YYYYMMDD
*/
exports.endOfMonth = (baseDate) => {
return isValidDate(
dayjs(baseDate, [YYYYMMDD, "YYYYMM"], true).endOf("month").format(YYYYMMDD)
);
};
日付比較
isBefore()は基準日と比較して比較対象日付が未来ならばtrue、過去ならばfalseとなります。つまり、基準日.isBefore(過去日 "day") はtrue、基準日.isBefore(未来日, "day")はfalseです。
/**
* 日付比較
* @param {string} baseDate 基準日 YYYYMMDD
* @param {string} compDate 対象日 YYYYMMDD
* @returns {number|null} 比較結果. 基準日 < 対象日 は -1, 基準日 = 対象日 は 0, 基準日 > 対象日 は 1
*/
exports.compare = (baseDate, compDate) => {
const base = dayjs(baseDate, YYYYMMDD, true);
const comp = dayjs(compDate, YYYYMMDD, true);
if (!isValidDate(base) || !isValidDate(comp)) {
return null;
}
if (base.isSame(comp, "days")) {
return 0;
}
return base.isBefore(comp, "days") ? -1 : 1;
};
日付差分日数
やっていることは年齢計算と同じで、年を計算するか日数を計算するかの違いです。
/**
* 差分日数
* @param {string} fromDate 基準日 YYYYMMDD
* @param {string} toDate 対象日 YYYYMMDD
* @returns {number|null} 計算結果. 基準日 < 対象日は 正の値、基準日 > 対象日は 負の値.
*/
exports.diffDays = (fromDate, toDate) => {
let from = dayjs(fromDate, YYYYMMDD, true);
let to = dayjs(toDate, YYYYMMDD, true);
if (!isValidDate(from) || !isValidDate(to)) {
return null;
}
return to.diff(from, "day");
};
エポック <-> UTC時間変換
UTC時間を使う場合、プラグインを追加します。またエポック時間には秒とミリ秒で使い方が違うので注意します。
エポック秒 to UTC時間
/**
* エポック(秒) to UTC変換
* @param {number} seconds Unixエポック
* @returns {string|null} UTC時間 YYYYMMDD hhmmss
*/
exports.epocSecToUtc = (seconds) => {
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
return isValidDate(dayjs.unix(seconds).utc().format(YYYYMMDD_HHmmss));
};
エポックミリ秒 to UTC変換
/**
* エポック(ミリ秒) to UTC変換
* @param {number} miliseconds
* @returns {string|null} UTC時間 YYYYMMDD hhmmss.SSS
*/
exports.epocMilliSecToUtc = (miliseconds) => {
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
return isValidDate(dayjs(miliseconds).utc().format(YYYYMMDD_HHmmss_SSS));
};
UTC to エポック秒
/**
* UTC to エポック(秒)
* @param {string} baseDate 日付
* @returns {number|null} エポック(秒)
*/
exports.utcToEpocSec = (baseDate) => {
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
let utc = dayjs.utc(baseDate);
if (!isValidDate(utc)) {
return null;
}
return utc.unix();
};
UTC to エポックミリ秒
/**
* UTC to エポック(ミリ秒)
* @param {string} baseDate YYYYMMDD HHmmss.SSS
* @returns {number|null} エポック(ミリ秒)
*/
exports.utcToEpocMilliSec = (baseDate) => {
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
let utc = dayjs.utc(baseDate);
if (!isValidDate(utc)) {
return null;
}
return utc.valueOf();
};
UTC <-> JST 変換
Day.jsオブジェクトは実行環境のロケールに合わせてしまうので、クラウドのリージョンなどの環境では注意が必要ですが、今回は環境に依存しないように実装しています。
UTC to JST
/**
* UTC to JST変換
* @param {string} baseUtc UTC時間. YYYYMMDD HHmmss
* @returns {string|null} 日本時間. YYYYMMDD HHmmss
*/
exports.utcToJst = (baseUtc) => {
dayjs.extend(require("dayjs/plugin/timezone")); // 本来はファイルの先頭で宣言
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
dayjs.tz.setDefault("Asia/Tokyo");
let utc = dayjs.utc(baseUtc, YYYYMMDD_HHmmss);
if (!isValidDate(utc)) {
return null;
}
return utc.tz().format(YYYYMMDD_HHmmss);
};
JST to UTC
/**
* JST to UTC変換
* @param {string} baseJst YYYYMMDD HHmmss
* @returns {string|null} UTC. YYYYMMDD HHmmss
*/
exports.jstToUtc = (baseJst) => {
dayjs.extend(require("dayjs/plugin/timezone")); // 本来はファイルの先頭で宣言
dayjs.extend(require("dayjs/plugin/utc")); // 本来はファイルの先頭で宣言
dayjs.tz.setDefault("Asia/Tokyo");
let jst = dayjs(baseJst, YYYYMMDD_HHmmss, true);
if (!isValidDate(jst)) {
return null;
}
return jst.utc().format(YYYYMMDD_HHmmss);
};