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

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

Основные понятия

Для работы с датами и временем в скриптах Google Рекламы используется встроенный объект JavaScript Date. Этот объект 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, 2025 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 time zone offsets.
const date1 = new Date('February 17, 2025 13:00:00 -0500');
const date2 = new Date('February 17, 2025 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, 2025 13:00:00 -0500');

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

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

// 2025-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, 2025 13:00:00 -0500');

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

По умолчанию используется часовой пояс America/Los_Angeles (тихоокеанское время) независимо от часового пояса, связанного с аккаунтом Google Рекламы. Если вы хотите представить объект даты в виде строки, используя собственный формат и часовой пояс для ведения журнала или других целей, всегда используйте Utilities.formatDate(date, timeZone, format).

Часовой пояс по умолчанию при создании объекта даты

Если при создании объекта даты используется строка, в которой не указано смещение часового пояса, то часовым поясом считается America/Los_Angeles (тихоокеанское время) независимо от часового пояса, связанного с аккаунтом Google Рекламы. Пример:

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

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

При создании объекта даты с помощью строки всегда указывайте смещение часового пояса, чтобы объект даты представлял нужный вам момент времени.

Часовой пояс по умолчанию в методах объекта даты

В объектах даты JavaScript есть несколько методов, которые предполагают часовой пояс по умолчанию, например:

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

Это также относится к эквивалентам этих методов в set___() (например, setMonth()) и getTimezoneOffset().

В скриптах Google Рекламы по умолчанию используется тихоокеанское время (America/Los_Angeles) независимо от часового пояса, заданного в аккаунте Google Рекламы. Поэтому, если ваш аккаунт Google Рекламы не находится в этом часовом поясе, вам обычно следует избегать использования этих методов.

Чтобы получить год, месяц, дату, день, часы или минуты для объекта даты в часовом поясе вашего аккаунта, используйте Utilities.formatDate(date, timeZone, format) с форматом, указывающим нужную часть даты или времени, и AdsApp.currentAccount().getTimeZone(), чтобы получить часовой пояс вашего аккаунта.

Создание объекта даты из форматированной строки даты

Вы можете создать объект даты, передав форматированную строку в конструктор. Рассмотрим пример.

const date = new Date('February 17, 2025 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 года по всемирному координированному времени. Вы можете выполнять математические операции с этим значением, а затем применять новое значение к объекту даты с помощью 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 (например, 2025-06-30 – это 30 июня 2025 г.).

Аналогично, метод 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, 2025 13:00:00 -0500 (Eastern Time)
const now = new Date();
spreadsheet.getRange('A1').setValue(now);

Значение в ячейке A1 будет следующим: 17-Feb-25 10:00:00.

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

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

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