【GAS、JavaScript】月末や月またぎも考慮した日付の計算をする

1627 語
8 分
【GAS、JavaScript】月末や月またぎも考慮した日付の計算をする

はじまり#

リサちゃん avatar
リサちゃん
月またぎの日付の計算がしたいなあ
135ml avatar
135ml
結構、野放しにしていたこの問題。
リサちゃん avatar
リサちゃん
調べても調べても・・・!
135ml avatar
135ml
じゃあ、跨ぐか

※当ページはアフィリエイト広告を利用しています。

基本的な日付の取得#

まず、 JavaScript では、Dateオブジェクトを使用して日付を扱います。新しい日付を作成するには、以下のようにします。

let today = new Date(); // 今日の日付
let specificDate = new Date(2024, 1, 13); // 2024年1月13日

日本時間を考慮した日付の取得#

そして、タイムゾーンを考慮した日付の取得はこんな感じで可能です。

まあ、下準備はこんなもんでしょうか。

const timezoneDiffOfTokyo = (new Date().getTimezoneOffset() + (540)) * 60 * 1000;
const today = new Date(Date.now() + timezoneDiffOfTokyo);

日付の成分の取得と設定#

日付から年、月、日などを取得または設定するには、getおよびsetメソッドを使用します。

const today = new Date();
let year = today.getFullYear();
let month = today.getMonth(); // 注意: 月は0から始まる
let day = today.getDate();
console.log(today)
console.log(year)
console.log(month)
console.log(day)
today.setFullYear(2025);
today.setMonth(11); // 12月
today.setDate(25);
console.log(today)
console.log(today.getMonth())
console.log(today.getDate())

出力結果はこうなります。月の部分だけ注意が必要です。

Mon Feb 12 2024 20:29:13 GMT-0500 (Eastern Standard Time)
2024
1
12
Thu Dec 25 2025 20:29:13 GMT-0500 (Eastern Standard Time)
11
25

日付の計算#

明日の日付や、 1 週間前といった日付を取得したければこう書けます。

let tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);
let lastWeek = new Date();
lastWeek.setDate(today.getDate() - 7);

しかし、これだけだと、月またぎを考慮した日付計算ができません。

例えば、 2/13 から 1/31 を引くと、-18になってダメダメです。

月またぎで 2 つの日付の差が分かる関数#

そして、本題です。

まずは、コードから見せます。

/**
* @description Get boolean value whether the difference between formerDay and latterDay is over or not.
* @param {Date()} formerDay
* @param {Date()} latterDay
* @param {number} targetDiff
* @return {boolean}
*/
function isDateDiffOver(formerDay, latterDay, targetDiff){
if(Math.abs(latterDay.getMonth() - formerDay.getMonth()) > 2){
console.log(`isDateDiffOver: 555555555555555555555555555555555555555555555555555555555555555555555`);
return true;
}else if(Math.abs(latterDay.getMonth() - formerDay.getMonth()) === 1){
let diffDates = latterDay.getDate() - formerDay.getDate();
formerDay.setDate(0); // Get end of month
diffDates += formerDay.getDate();
console.log(diffDates);
console.log(`isDateDiffOver: 666666666666666666666666666666666666666666666666666666666666666666666`);
if(diffDates <= targetDiff){
return true;
}
}else{
if(latterDay.getDate() - formerDay.getDate() <= targetDiff){
console.log(`isDateDiffOver: 77777777777777777777777777777777777777777777777777777777777777777777777`);
return true;
}
}
return false;
}

この関数は、formerDay(前者の日付)とlatterDay(後者の日付)の差が、targetDiffの数値を超えているかどうかを取得できるものです。

文章で書くとややこしいので、図付きで説明します。

考え方としては、最終的には緑色の範囲と青色の範囲が欲しいので、下記の流れになります。

  1. latterDay(後者の日付)と、formerDay(前者の日付)に 2 ヶ月以上の差があれば、trueになります。
  2. diffDatesを宣言するときは、latterDay(後者の日付)からformerDay(前者の日付)を引きます。
  3. そして、formerDay → End of Monthの部分の範囲が取れていないので、formerDay.setDate(0)をします。
  4. formerDay.setDate(0)をすると、前者の月の末日が取得できます。
  5. そして、formerDay.getDate()を足すと、緑色の範囲と青色の範囲が取得できたことになります。
  6. 緑色の範囲と青色の範囲にtargetDiffより大きい差があれば、trueになります。
  7. 緑色の範囲と青色の範囲がtargetDiffより小さかったら、falseになります。(指定した差の中に収まっている。)

やっぱりタイムスタンプが最強なのかもしれない#

とまあ、年月日のパラメータを使ってこねていきますが・・・

この考え方で計算すると、じゃあ 12 月と 1 月の場合はどうするの? とか、formerDaylatterDayより新しい日付だったらどうするの? とか、何だか色々と面倒くさいことが残ってしまいます。

そこで、日付同士を計算する時は、「UNIXタイムスタンプ」を使うのが最善策なのかもしれません。 (JavaScript のDate型でググっても、あんまり UNIX タイムスタンプで計算する方法がヒットしませんよね・・・)

UNIX タイムスタンプとは、巷で有名なわわわさんから引用すると・・・

時間の表現方法だよ。「1970年1月1日午前0時0分0秒(UTC)」からの経過秒数で表現するよ。 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

だそうです。

まあ、時刻を表す絶対的な指標ということですかね。

それでは、 UNIX タイムスタンプを活用した関数です。これが本命。

/**
* @description Get boolean value whether the difference between formerDay and latterDay is over or not.
* @param {Date()} formerDay
* @param {Date()} latterDay
* @param {number} targetDiff
* @return {boolean}
* @example
* formerDay = 2022/01/23; latterDay = 2022/01/24; targetDiff = 1; return false;
* formerDay = 2022/01/23; latterDay = 2022/01/24; targetDiff = 0; return true;
*/
function isDateDiffOver(formerDay, latterDay, targetDiff){
let timestamp1 = Math.floor(formerDay.getTime() / 1000);
let timestamp2 = Math.floor(latterDay.getTime() / 1000);
const margin = 10 * 1000;
console.log(formerDay)
console.log(latterDay)
console.log(targetDiff)
console.log(`isDateDiffOver: 11111111111111111111111111111111111111111111111111111111111111111`);
console.log(timestamp2 - timestamp1)
console.log(60 * 60 * 24 * (targetDiff + 1) - 1)
if(Math.abs(timestamp2 - timestamp1) >= 60 * 60 * 24 * targetDiff - margin){
console.log(`isDateDiffOver: 44444444444444444444444444444444444444444444444444444444444444444`);
return true;
}
console.log(`isDateDiffOver: 999999999999999999999999999999999999999999999999999999999999999999999`);
return false;
}

UNIX タイムスタンプは、日付ではなく整数型の値なので、比較をするのが物凄く楽です。もう、こんなにコードが短くなってしまいました。

UNIX タイムスタンプはミリ秒単位で記録されるものなので、秒間や日にちの比較をする際には 1000 で割ってあげると良いでしょう。

これで、じゃあ 12 月と 1 月の場合はどうするの?とかの問題が解消されます。しかし、「formerDaylatterDayより新しい日付だったらどうするの?」とかの問題が残っています。

そこで、もう一つ関数を用意します。

/**
* @description Get boolean value whether latterDay is later than formerDay or not.
* @param {Date()} formerDay
* @param {Date()} latterDay
* @return {boolean}
* @example
* formerDay = 2022/01/25; latterDay = 2022/01/24; return false;
* formerDay = 2022/01/23; latterDay = 2022/01/24; return true;
*/
function isLatterDayLater(formerDay, latterDay){
let timestamp1 = Math.floor(formerDay.getTime() / 1000);
let timestamp2 = Math.floor(latterDay.getTime() / 1000);
if(timestamp2 - timestamp1 > 0){
console.log(`isLatterDayLater: 88888888888888888888888888888888888888888888888888888888888888888888888888`);
return true
}
console.log(`isLatterDayLater: 999999999999999999999999999999999999999999999999999999999999999999999`);
return false;
}

この関数を使うことで、formerDaylatterDayの前後関係を判定することが出来ます。

なので、この節で紹介した、isDateDiffOver()isLatterDayLater()で論理演算すれば日付に関する計算は問題ないのではないでしょうか。(1970 年 1 月 1 日午前 0 時 0 分 0 秒が基準なのをお忘れなく。)

Google Apps Script の関連書籍#

Google Apps Script × ChatGPTのツボとコツがゼッタイにわかる本amzn.to
Amazon.co.jpで購入する
Google Apps Script Webアプリ開発 第4版amzn.to
Amazon.co.jpで購入する
Google Apps Script目的別リファレンス 実践サンプルコード付き 第3版amzn.to
Amazon.co.jpで購入する
Google Apps Script クローリング&スクレイピングのツボとコツがゼッタイにわかる本amzn.to
Amazon.co.jpで購入する

おしまい#

リサちゃん avatar
リサちゃん
よし、日付の差が取れたぞ
135ml avatar
135ml
日付の操作って、本当に面倒くさいよな

以上になります!

記事を共有

この記事が役に立ったなら、ぜひ他の人と共有してください!

【GAS、JavaScript】月末や月またぎも考慮した日付の計算をする
https://endorphinbath.com/posts/gas-date-diff-over-the-month/
著者
kinkinbeer135ml
公開日
2024-02-13
ライセンス
CC BY-NC-SA 4.0
関連記事 スマート
1
【JavaScript】実行中の関数自身の関数名を取得する
Code 実行している関数やメソッド自身の名前を取得する方法を紹介します。この方法は、その関数名を取得する関数を別の関数から呼び出してもらわなければなりません。thisに関数をバインドする必要があるためです。その呼び出し方の種類を掲載しています。
2
【JavaScript】Errorタイプのオブジェクトかどうかを判定する
Code JavaScriptで渡した値がErrorオブジェクトかどうかを判定する関数が見つからなかったので、僕が書いたものを紹介します。
3
【JavaScript】数値を0埋めされた文字列として加工する
Code JavaScriptで、IDなどを採番する時に0埋めした数値が欲しい時があります。その時に利用できるスニペットを紹介します。
4
【GAS】「承認が必要です:このプロジェクトがあなたのデータへのアクセス権限を必要としています。」の表示工程を省くようにするスコープ設定
Code GAS実行時のOAuth承認プロセスを省くために必要なappsscript.jsonのスコープ設定について紹介します。
5
【GAS】スクリプトプロパティがGUIで確認できないのでJSONに入れることにした
Code GASのエディタでスクリプトプロパティを編集出来なくなる事象を回避するために、プロパティの値をJSONで格納するように実装していく記事です。
ランダム記事 ランダム
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次