Работа с датами и временем

Скриптам 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);

Пользователей новых сценариев часто сбивает с толку то, как объекты даты обрабатывают часовые пояса. Естественный, но неправильный способ представления объекта даты — это время на часах в одном часовом поясе . Например, в приведенном выше фрагменте некоторые пользователи ошибочно предполагают, что date действительна только в одном часовом поясе, а именно в часовом поясе со смещением -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\''));

В этих примерах часовой пояс указан напрямую с помощью идентификатора часового пояса . Чтобы получить часовой пояс, связанный с аккаунтом 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».

Математика даты

Некоторым сценариям необходимо выполнять простые математические операции с датами, например находить дату за X дней до или после заданной даты. При выполнении математических вычислений с датами используйте getTime() . Вызов getTime() для объекта даты возвращает количество миллисекунд с начала 1 января 1970 года по всемирному координированному времени (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 (например, 30 июня 2021-06-30 будет 30 июня 2021 г.).

Аналогично, метод getStatsFor() доступный во многих объектах скриптов Google Рекламы, требует указания дат в одном и том же формате. Используйте Utilities.formatDate(date, timeZone, format) для форматирования объекта даты в этом формате.

Например, чтобы получить отчет за период от одного до трех дней назад:

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 февраля 21 10:00:00.

Чтобы объекты даты записывались в электронную таблицу так, как вы ожидаете, установите часовой пояс таблицы в соответствии с часовым поясом вашего аккаунта Google Реклама:

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

Вы также можете установить время для электронной таблицы вручную .