📚
GAS開発者のための日付操作ガイド - GAS + TypeScriptによる日付操作ユーティリティの実装と応用
1. はじめに
- GAS(Google Apps Script)のプロジェクトにおいて、日付の操作は頻繁に必要となる処理です。
- 本記事では、GASとTypeScriptを使用した日付操作ユーティリティの実装について解説します。
2.日付操作ユーティリティ - DateUtilクラスの実装
/**
* 日付計算のユーティリティクラス
*/
export class DateUtil {
/**
* 基準日から指定日数を加算または減算した日付を取得します
* @param date 基準日
* @param days 加算する日数(負数の場合は減算)
* @param resetTime 時刻をリセットするかどうか(デフォルトはtrue)
* @returns 計算後の日付
*/
public static addDaysToDate(
date: Date,
days: number,
resetTime: boolean = true
): Date {
const resultDate = new Date(date);
resultDate.setDate(resultDate.getDate() + days);
if (resetTime) {
resultDate.setHours(0, 0, 0, 0);
}
return resultDate;
}
/**
* 現在日時から指定日数前の日付を取得します
* @param days 遡る日数
* @returns 指定日数前の日付
*/
public static getDaysAgo(days: number): Date {
return this.addDaysToDate(new Date(), -days);
}
/**
* 来週の月曜日の日付を取得します
* @returns 来週月曜日の日付
*/
public static getNextMonday(): Date {
const today = new Date();
const nextMonday = new Date(today);
nextMonday.setDate(today.getDate() + (8 - today.getDay()));
nextMonday.setHours(0, 0, 0, 0);
return nextMonday;
}
/**
* 来週日曜日の日付を取得します
* @returns 来週日曜日の日付
*/
public static getNextSunday(): Date {
const nextMonday = this.getNextMonday();
const nextSunday = new Date(nextMonday);
nextSunday.setDate(nextMonday.getDate() + 6);
nextSunday.setHours(0, 0, 0, 0);
return nextSunday;
}
/**
* 来週の日付範囲を取得します
* @returns 来週の月曜日と日曜日の日付
*/
public static getNextWeekRange(): { startDate: Date; endDate: Date } {
return {
startDate: this.getNextMonday(),
endDate: this.getNextSunday(),
};
}
/**
* 指定された日付が来週以降の日付かどうかを判定します
* @param date 判定対象の日付
* @returns 来週以降の日付の場合はtrue
*/
public static isDateAfterNextWeek(date: Date): boolean {
const nextMonday = this.getNextMonday();
return date >= nextMonday;
}
/**
* 基準日から指定日数後の日付を文字列形式で取得します
* @param baseDate 基準日
* @param days 進める日数
* @returns yyyy/MM/dd形式の日付文字列
*/
public static addDays(baseDate: Date, days: number): string {
return this.toFormatString(this.addDaysToDate(baseDate, days));
}
/**
* 基準日から指定日数前の日付を文字列形式で取得します
* @param baseDate 基準日
* @param days 遡る日数
* @returns yyyy/MM/dd形式の日付文字列
*/
public static removeDays(baseDate: Date, days: number): string {
return this.toFormatString(this.addDaysToDate(baseDate, -days));
}
/**
* 日付を指定フォーマットの文字列に変換します。
* @param date
* @returns yyyy/MM/dd形式の日付文字列
*/
public static toFormatString(
date: Date | GoogleAppsScript.Base.Date
): string {
return Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd');
}
/**
* 2つの日付が同じ日かどうかを判定します
* @param date1 比較する日付1
* @param date2 比較する日付2
* @returns 同じ日の場合はtrue、それ以外はfalse
*/
public static isSameDate(date1: Date, date2: Date): boolean {
return (
date1.getFullYear() === date2.getFullYear() &&
date1.getMonth() === date2.getMonth() &&
date1.getDate() === date2.getDate()
);
}
/**
* 指定された日付が範囲内かどうかを判定します
* @param date 判定する日付
* @param startDate 範囲開始日
* @param endDate 範囲終了日(この日を含む)
* @returns boolean
*/
public static isDateInRange(
date: Date,
startDate: Date,
endDate: Date
): boolean {
const normalizedDate = this.normalizeDate(date);
const normalizedStart = this.normalizeDate(startDate);
const normalizedEnd = this.normalizeDate(endDate);
return normalizedDate >= normalizedStart && normalizedDate <= normalizedEnd;
}
/**
* 日付の時刻部分を0時0分0秒に正規化します
*/
private static normalizeDate(date: Date): Date {
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
}
/**
* 日付を「MM/DD (曜日)」形式でフォーマットします
* @param date フォーマットする日付
* @returns MM/DD (曜日) 形式の文字列
*/
public static formatDateWithDayOfWeek(date: Date): string {
const dayOfWeek = ['日', '月', '火', '水', '木', '金', '土'][date.getDay()];
return `${date.getMonth() + 1}/${date.getDate()} (${dayOfWeek})`;
}
/**
* 日付範囲を「MM/DD~MM/DD」形式でフォーマットします
* @param startDate 開始日
* @param endDate 終了日
* @returns MM/DD~MM/DD 形式の文字列
*/
public static formatDateRange(startDate: Date, endDate: Date): string {
return `${startDate.getMonth() + 1}/${startDate.getDate()}~${
endDate.getMonth() + 1
}/${endDate.getDate()}`;
}
/**
* 先週の月曜日の日付を取得します
* @returns 先週月曜日の日付
*/
public static getLastMonday(): Date {
const today = new Date();
const lastMonday = new Date(today);
lastMonday.setDate(today.getDate() - (today.getDay() + 6));
lastMonday.setHours(0, 0, 0, 0);
return lastMonday;
}
/**
* 先週の日曜日の日付を取得します
* @returns 先週日曜日の日付
*/
public static getLastSunday(): Date {
const lastMonday = this.getLastMonday();
const lastSunday = new Date(lastMonday);
lastSunday.setDate(lastMonday.getDate() + 6);
lastSunday.setHours(0, 0, 0, 0);
return lastSunday;
}
/**
* 先週の日付範囲を取得します
* @returns 先週の月曜日と日曜日の日付
*/
public static getLastWeekRange(): { startDate: Date; endDate: Date } {
return {
startDate: this.getLastMonday(),
endDate: this.getLastSunday(),
};
}
}
3. 主要メソッドの解説
3.1 日付の取得
DateUtilクラスは様々な日付取得メソッドを提供します。
// 7日前の日付を取得
const sevenDaysAgo = DateUtil.getDaysAgo(7);
console.log(sevenDaysAgo); // 例: 2025-01-11 00:00:00
// 来週の月曜日と日曜日を取得
const nextMonday = DateUtil.getNextMonday();
const nextSunday = DateUtil.getNextSunday();
// 来週の日付範囲を一度に取得
const nextWeekRange = DateUtil.getNextWeekRange();
console.log(nextWeekRange);
// 出力例: { startDate: 2025-01-20 00:00:00, endDate: 2025-01-26 00:00:00 }
3.2 日付操作と文字列に変換
日付の加算・減算を行い、文字列に変換するメソッドを提供します。
const baseDate = new Date('2025-01-18');
// 3日後の日付(文字列型)を取得
const afterThreeDays = DateUtil.addDays(baseDate, 3);
console.log(afterThreeDays); // 出力: "2025/01/21"
// 5日前の日付(文字列型)を取得
const beforeFiveDays = DateUtil.removeDays(baseDate, 5);
console.log(beforeFiveDays); // 出力: "2025/01/13"
3.3 日付の比較と検証
日付の比較や範囲チェックを行うメソッドを提供します。
// 日付範囲のチェック
const targetDate = new Date('2025-01-20');
const startDate = new Date('2025-01-18');
const endDate = new Date('2025-01-25');
const isInRange = DateUtil.isDateInRange(targetDate, startDate, endDate);
console.log(isInRange); // 出力: true
// 日付の一致確認
const date1 = new Date('2025-01-18');
const date2 = new Date('2025-01-18');
console.log(DateUtil.isSameDate(date1, date2)); // 出力: true
3.4 日付のフォーマット
日付を様々な形式に変換するメソッドを提供します。
const date = new Date('2025-01-18');
// 曜日付きフォーマット
const formattedDate = DateUtil.formatDateWithDayOfWeek(date);
console.log(formattedDate); // 出力: "1/18 (土)"
// 日付範囲のフォーマット
const start = new Date('2025-01-20');
const end = new Date('2025-01-26');
const range = DateUtil.formatDateRange(start, end);
console.log(range); // 出力: "1/20~1/26"
4. DateUtilクラスの使用例 - 週次売上データの分析
- 本章では、DateUtilクラスを使用したデータ分析の具体的な実装方法について説明します。
- スプレッドシートに記録された売上データを、日付範囲でフィルタリングし、集計する処理を実装例として紹介します。
分析対象データ
分析の対象となるスプレッドシートには、以下のような週次の売上データが記録されているとします。
日付 | 商品名 | 売上金額 | 担当者 |
---|---|---|---|
2025/01/06(月) | 商品A | 1,200 | 山田 |
2025/01/07(火) | 商品B | 2,300 | 鈴木 |
2025/01/08(水) | 商品A | 1,500 | 田中 |
2025/01/13(月) | 商品C | 3,000 | 山田 |
2025/01/14(火) | 商品B | 2,100 | 鈴木 |
2025/01/15(水) | 商品A | 1,800 | 田中 |
データ分析の実装
-
analyzeWeeklySales
- 週次売上データの分析を実行し、集計結果を返却します。
-
filterByDateRange
- 指定された期間内の売上データを抽出します。
-
analyzeSalesByProduct
- 商品別の売上合計を集計します。
-
analyzeSalesByPerson
- 担当者別の売上合計を集計します。
/**
* 週次売上データの分析を実行し、集計結果を返却します。
*
* @returns 以下の3つの分析結果を含むオブジェクト
* - lastWeek: 直近1週間の売上データ
* - salesByProduct: 商品別の売上集計
* - salesByPerson: 担当者別の売上集計
*/
function analyzeWeeklySales() {
const sheet = SpreadsheetApp.getActiveSheet();
const dataRange = sheet.getDataRange();
const values = dataRange.getValues();
// 2025/01/16(木)にGASを実行したとする
const lastWeekRange = DateUtil.getLastWeekRange();
// ヘッダー行を除いたデータ行を取得
const dataRows = values.slice(1);
return {
lastWeek: filterByDateRange(dataRows, lastWeekRange),
salesByProduct: analyzeSalesByProduct(dataRows),
salesByPerson: analyzeSalesByPerson(dataRows)
};
}
/**
* 指定された期間内の売上データを抽出します。
*
* @param dataRows 売上データの2次元配列(日付、商品名、売上金額、担当者)
* @param dateRange 抽出対象期間(開始日と終了日を含むオブジェクト)
* @returns 指定期間内の売上データ
*/
function filterByDateRange(dataRows: any[][], dateRange: { startDate: Date; endDate: Date }) {
return dataRows.filter(row => {
const rowDate = new Date(row[0]);
return DateUtil.isDateInRange(rowDate, dateRange.startDate, dateRange.endDate);
});
}
/**
* 商品別の売上合計を集計します。
*
* @param dataRows 売上データの2次元配列(日付、商品名、売上金額、担当者)
* @returns 商品名をキー、売上合計を値とするオブジェクト
*/
function analyzeSalesByProduct(dataRows: any[][]) {
const salesByProduct = {};
dataRows.forEach(row => {
const product = row[1];
const amount = row[2];
salesByProduct[product] = (salesByProduct[product] || 0) + amount;
});
return salesByProduct;
}
/**
* 担当者別の売上合計を集計します。
*
* @param dataRows 売上データの2次元配列(日付、商品名、売上金額、担当者)
* @returns 担当者名をキー、売上合計を値とするオブジェクト
*/
function analyzeSalesByPerson(dataRows: any[][]) {
const salesByPerson = {};
dataRows.forEach(row => {
const person = row[3];
const amount = row[2];
salesByPerson[person] = (salesByPerson[person] || 0) + amount;
});
return salesByPerson;
}
実行結果 - 2025/01/16(木)に実行した場合
先週のデータ抽出結果:analysis.lastWeek
日付 | 商品名 | 売上金額 | 担当者 |
---|---|---|---|
2025/01/06 | 商品A | 1,200 | 山田 |
2025/01/07 | 商品B | 2,300 | 鈴木 |
2025/01/08 | 商品A | 1,500 | 田中 |
商品別売上集計:analysis.salesByProduct
商品名 | 売上合計 |
---|---|
商品A | 4,500 |
商品B | 4,400 |
商品C | 3,000 |
担当者別売上集計:analysis.salesByPerson
担当者 | 売上合計 |
---|---|
山田 | 4,200 |
鈴木 | 4,400 |
田中 | 3,300 |
以上のようにDateUtilクラスを使用することで、週次のセールスレポートの作成や、商品ごとの販売傾向の把握、担当者のパフォーマンス評価など、様々な分析に活用することができます。
5. まとめ
本記事では、ClaspとTypeScriptを使用したDateUtilクラスの紹介と活用方法について解説しました。主なポイントは以下の通りです。
-
DateUtilクラスの基本機能
- 日付の取得や計算を行う各種メソッド
- TypeScriptによる型安全な実装
- 時刻のリセットと日付比較機能
-
主要メソッド
- getDaysAgo - 指定日数前の日付取得
- getNextMonday/Sunday - 来週の月曜/日曜の取得
- isDateInRange - 日付範囲のチェック機能
- formatDateWithDayOfWeek - 曜日付き日付フォーマット
-
DateUtilクラスの使用例
- スプレッドシートの週次データ分析
- 日付範囲に基づくデータのフィルタリング
- 商品別・担当者別の売上集計
最後までお読みいただき、ありがとうございました。
本記事が皆様のGAS開発のお役に立てば幸いです。
Discussion