日時の設定

Google 広告 スクリプトでは日時の設定が必要になることがあります。一般的なユースケースとしては、特定の期間のレポートの取得、特定の時間にキャンペーンまたは広告グループを実行するスケジュールの設定、スクリプトが最後に実行された時刻のスプレッドシートへの出力などがあります。このガイドでは、Google 広告スクリプトで日時を扱う際の重要な概念、よくある問題、おすすめのアプローチについて説明します。

基本概念

Google 広告 スクリプトで日時を設定するには、JavaScript の組み込み関数である日付オブジェクトを使用します。JavaScript の日付オブジェクトを使用すると、特定の日時が表示されます。新しく日付オブジェクトを作成するには、次のような複数の方法があります。

// Create a date object for the current date and time.
const now = new Date();

// Create a date object for a past date and time using a formatted string.
const date = new Date('February 17, 2021 13:00:00 -0500');

// Create a copy of an existing date object.
let copy = new Date(date);

AdWords スクリプトを使い始めたばかりのユーザーは、日付オブジェクトでのタイムゾーンの扱いについて混乱する場合がよくあります。日付オブジェクトを、単一のタイムゾーンの時計の時刻と考えるというのは自然な考え方ですが、正しくありません。たとえば、上記のスニペットでは、一部のユーザーは、date が 1 つのタイムゾーン、つまり作成に使用された -5 時間オフセットのタイムゾーンでのみ有効であると勘違いしています。この誤った考え方では、他のタイムゾーンで使用するために date を「変換」する必要があります。

しかし、日付オブジェクトが指しているのは、タイムゾーンとは独立した特定の瞬間であるというのが正しい考え方です。特定の瞬間は、タイムゾーンによって時計に表示される時間が異なりますが、同じ瞬間です。たとえば、次のスニペットについて考えてみましょう。

// Create two date objects with different times and timezone offsets.
const date1 = new Date('February 17, 2021 13:00:00 -0500');
const date2 = new Date('February 17, 2021 10:00:00 -0800');

// getTime() returns the number of milliseconds since the beginning of
// January 1, 1970 UTC.
// True, as the dates represent the same moment in time.
console.log(date1.getTime() == date2.getTime());

// False, as the dates are separate objects, though they happen to
// represent the same moment in time.
console.log(date1 == date2);

日付オブジェクトが示しているのはある特定の瞬間であるため、タイムゾーンごとに「変換」する必要はありません。なお、日付を特定のタイムゾーンの形式に合った文字列に整形することは可能です。

特定の形式とタイムゾーンで日付を文字列としてレンダリングするには、Utilities.formatDate(date, timeZone, format) を使用します。例:

const date = new Date('February 17, 2021 13:00:00 -0500');

// February 17, 2021 13:00:00 -0500
console.log(Utilities.formatDate(date, 'America/New_York', 'MMMM dd, yyyy HH:mm:ss Z'));

// February 17, 2021 10:00:00 -0800
console.log(Utilities.formatDate(date, 'America/Los_Angeles', 'MMMM dd, yyyy HH:mm:ss Z'));

// 2021-02-17T18:00:00.000Z
console.log(Utilities.formatDate(date, 'Etc/GMT', 'yyyy-MM-dd\'T\'HH:mm:ss.SSS\'Z\''));

これらの例では、タイムゾーン ID を使用してタイムゾーンを直接指定しています。スクリプトを実行している Google 広告アカウントに関連付けられているタイムゾーンを取得するには、AdsApp.currentAccount().getTimeZone() を使用します。

主な注意点

日付オブジェクト記録時のデフォルトのタイムゾーン

Logger.log() を使用して日付オブジェクトを直接ロギングすると、デフォルトの形式とタイムゾーンを使用してレンダリングされます。例:

const date = new Date('February 17, 2021 13:00:00 -0500');

// Wed Feb 17 10:00:00 GMT-08:00 2021
console.log(date);

デフォルトのタイムゾーンは、Google 広告 アカウントに関連付けられているタイムゾーンにかかわらず「アメリカ、ロサンゼルス(太平洋標準時)」です。ロギングやその他の目的で、カスタム形式とタイムゾーンを使用して日付オブジェクトを文字列としてレンダリングする場合は、常に Utilities.formatDate(date, timeZone, format) を使用します。

日付オブジェクト作成時のデフォルトのタイムゾーン

タイムゾーン オフセットが指定されていない文字列を使用して日付オブジェクトを作成する場合は、Google 広告アカウントに関連付けられているタイムゾーンに関係なく、タイムゾーンは America/Los_Angeles(太平洋時間)と見なされます。次に例を示します。

// Create a date without specifying the timezone offset.
const date = new Date('February 17, 2021 13:00:00');

// Wed Feb 17 13:00:00 GMT-08:00 2021
console.log(date);

文字列を使用して日付オブジェクトを作成する場合は、日付オブジェクトが本当に必要な時刻を表すように、必ずタイムゾーン オフセットを含めます。

日付オブジェクトのメソッドが使用できるデフォルトのタイムゾーン

JavaScript の日付オブジェクトには、デフォルトのタイムゾーンを前提とするメソッドがいくつかあります。

  • getFullYear()
  • getMonth()
  • getDate()
  • getDay()
  • getHours()
  • getMinutes()

これには、これらのメソッドの set___() 同等のメソッド(setMonth() など)と getTimezoneOffset() も含まれます。

Google 広告スクリプトでは、Google 広告アカウントに関連付けられているタイムゾーンに関係なく、デフォルトのタイムゾーンはアメリカ、ロサンゼルス(太平洋時間)です。そのため、Google 広告アカウントのタイムゾーンがこのタイムゾーンでない限り、通常はこれらの方法を使用しないでください。

アカウントのタイムゾーンにある日付オブジェクトの年、月、日、時、分、秒を取得するには、必要な日付または時刻の部分を指定する形式で Utilities.formatDate(date, timeZone, format) を使用し、AdsApp.currentAccount().getTimeZone() を使用してアカウントのタイムゾーンを取得します。

形式を指定した日付の文字列を使って日付オブジェクトを作成する

日付オブジェクトを作成する際、形式を指定した日付の文字列を日付コンストラクタに含めることができます。たとえば、次のとおりです。

const date = new Date('February 17, 2021 13:00:00 -0500');

コンストラクタが解析できるのは、特定の日付文字列の形式のみです。日付文字列が正しく解析されるように、常に MMMM dd, yyyy HH:mm:ss Z 形式で指定してください。

たとえば、現在のアカウントのタイムゾーンで今日の正午の日付オブジェクトを作成するには、次のようにします。

const now = new Date();
const timeZone = AdsApp.currentAccount().getTimeZone();
const noonString = Utilities.formatDate(now, timeZone, 'MMMM dd, yyyy 12:00:00 Z');
const noon = new Date(noonString);

日付コンストラクタに渡される日付文字列を作成する場合、「z」パターンを使用しないでください。コンストラクタが常に解析できるとは限りません。「Z」パターンのみを使用してください。

日付の計算

特定の日付から何日か前、または何日か後の日付を取得するなど、簡単な日付の計算が必要な場合があります。日付演算を行う場合は、getTime() を使用します。日付オブジェクトで getTime() を呼び出すと、1970 年 1 月 1 日(UTC)からの経過時間(ミリ秒)が返されます。この値に対して計算を行い、setTime() を使用して新しい値を日付オブジェクトに適用するか、新しい日付オブジェクトを作成するときにパラメータとして指定できます。

例:

const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const now = new Date();
const yesterday = new Date(now.getTime() - MILLIS_PER_DAY);

この例では、yesterday は正確に 24 時間前です。

レポート

AdsApp.search() を使用してレポートを取得する場合、GAQL クエリで日付を yyyy-MM-dd の形式で指定する必要があります(たとえば、2021-06-30 は 2021 年 6 月 30 日になります)。

同様に、多くの Google 広告スクリプト オブジェクトで使用できる getStatsFor() メソッドでは、日付を同じ形式で指定する必要があります。Utilities.formatDate(date, timeZone, format) を使用して、日付オブジェクトをこの形式でフォーマットします。

たとえば、1~3 日前のレポートを取得する場合は次のようになります。

const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
const now = new Date();
const from = new Date(now.getTime() - 3 * MILLIS_PER_DAY);
const to = new Date(now.getTime() - 1 * MILLIS_PER_DAY);

const timeZone = AdsApp.currentAccount().getTimeZone();
const results = AdsApp.search(
  'SELECT campaign.name, metrics.clicks' +
  'FROM campaign ' +
  'WHERE segments.date BETWEEN ' +
    Utilities.formatDate(from, timeZone, 'yyyy-MM-dd') + ' AND ' +
    Utilities.formatDate(to, timeZone, 'yyyy-MM-dd'));

スプレッドシート

Google 広告スクリプトでは、日付オブジェクトを含む出力をスプレッドシートに書き込むことがよくあります。日付オブジェクトを渡してスプレッドシートのセルを設定すると、スプレッドシートのタイムゾーンを使用して日付が解釈されます。たとえば、タイムゾーンが太平洋時間に設定されているスプレッドシートがあるとします。

// Suppose today is February 17, 2021 13:00:00 -0500 (Eastern Time)
const now = new Date();
spreadsheet.getRange('A1').setValue(now);

A1 の値は 2021 年 2 月 17 日 10:00:00 になります。

日付オブジェクトがスプレッドシートに正しく書き込まれるようにするには、スプレッドシートのタイムゾーンを、ご自身の Google 広告 アカウントと同じタイムゾーンに設定します。

spreadsheet.setSpreadsheetTimeZone(AdsApp.currentAccount().getTimeZone());

スプレッドシートの時刻を手動で設定することもできます。