日時の設定

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 広告アカウントに関連付けられているタイムゾーンに関係なく、タイムゾーンはアメリカ/ロサンゼルス(太平洋時間)とみなされます。次に例を示します。

// 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 の値は 17-Feb-21 10:00:00 になります。

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

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

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