Что такое Google Apps Script и зачем это нужно?
Google Apps Script (GAS) — это облачная платформа для разработки скриптов на основе JavaScript, позволяющая расширять функциональность приложений Google Workspace (Sheets, Docs, Drive, Calendar, Gmail и др.) и автоматизировать рабочие процессы. Умение работать с датой и временем является фундаментальным навыком в GAS, необходимым для логирования событий, планирования задач, создания отчетов с временными метками, управления данными с привязкой ко времени и многого другого.
Основы работы с объектами Date в JavaScript
Google Apps Script использует стандартный встроенный объект Date из JavaScript для представления даты и времени. Этот объект хранит время как количество миллисекунд, прошедших с начала эпохи Unix (1 января 1970 года UTC). Понимание основ работы с Date (создание экземпляра, получение компонентов даты/времени) является отправной точкой для работы с временными данными в GAS.
Импорт библиотеки моментов
Хотя встроенный объект Date и Utilities.formatDate покрывают большинство стандартных задач, для более сложных манипуляций с датами (сложение/вычитание интервалов, относительное время, парсинг сложных форматов) часто используется библиотека Moment.js. Ее необходимо добавить в проект как внешнюю библиотеку через идентификатор скрипта. Примечание: Moment.js находится в режиме поддержки; для новых проектов рассмотрите нативные методы или альтернативы вроде Day.js, если требуется.
Получение текущей даты и времени в Google Apps Script
Использование объекта `Date` для получения текущей даты и времени
Самый простой способ получить текущую дату и время — создать новый экземпляр объекта Date без аргументов. Он будет инициализирован текущим моментом времени согласно системным настройкам сервера, на котором выполняется скрипт (обычно UTC, но может зависеть от среды исполнения).
/**
* Получает текущую дату и время сервера.
* @returns {Date} Объект Date, представляющий текущий момент.
*/
function getCurrentDateTime(): Date {
const now: Date = new Date();
Logger.log(now); // Выведет дату и время в лог
return now;
}Получение текущей даты и времени в определенной временной зоне
Часто требуется получить дату и время не по UTC или времени сервера, а в конкретной временной зоне, например, временной зоне пользователя или временной зоне, указанной в настройках скрипта. Для этого используются методы сервиса Session.
Session.getScriptTimeZone(): Возвращает строковый идентификатор временной зоны, установленной в настройках проекта скрипта (Файл -> Настройки проекта).
Session.getActiveUser().getTimeZone(): Возвращает строковый идентификатор временной зоны пользователя, запустившего скрипт (требует соответствующих разрешений).
Эти идентификаторы используются в дальнейшем при форматировании даты.
Примеры кода для получения текущей даты и времени
/**
* Демонстрирует получение идентификаторов временных зон.
*/
function logTimeZones(): void {
const scriptTimeZone: string = Session.getScriptTimeZone();
Logger.log(`Временная зона скрипта: ${scriptTimeZone}`);
try {
// Требует разрешения, может не работать в некоторых контекстах (например, из пользовательской функции Sheets без явного вызова)
const userTimeZone: string = Session.getActiveUser().getTimeZone();
Logger.log(`Временная зона пользователя: ${userTimeZone}`);
} catch (e) {
Logger.log(`Не удалось получить временную зону пользователя: ${e}`);
}
}
/**
* Получает текущую дату и время (объект Date).
* @returns {Date} Текущая дата и время.
*/
function getNow(): Date {
return new Date();
}Форматирование даты и времени в Google Apps Script
Использование `Utilities.formatDate()` для форматирования даты и времени
Для преобразования объекта Date в удобочитаемую строку используется метод Utilities.formatDate(). Он является ключевым инструментом для представления даты и времени в нужном формате.
Метод принимает три аргумента:
date: Объект Date, который нужно отформатировать.
timeZone: Строка, представляющая временную зону (например, 'Europe/Moscow', 'UTC', или полученная через Session.getScriptTimeZone()).
format: Строка шаблона, определяющая формат вывода (например, 'yyyy-MM-dd HH:mm:ss').
Настройка формата даты и времени (шаблоны)
Шаблоны форматирования основаны на спецификации Java SimpleDateFormat. Некоторые распространенные символы:
y: Год (yyyy для полного года)
M: Месяц в году (MM для двух цифр, MMM для сокращенного названия, MMMM для полного)
d: День месяца (dd для двух цифр)
E: День недели (EEE для сокращенного названия, EEEE для полного)
H: Час в сутках (0-23) (HH для двух цифр)
m: Минута в часе (mm для двух цифр)
s: Секунда в минуте (ss для двух цифр)
z: Временная зона
Примеры форматирования даты и времени для разных локалей
Локаль влияет на названия месяцев и дней недели. GAS обычно использует локаль по умолчанию, но для явного указания локали (например, при генерации отчетов для международной аудитории) можно использовать Utilities.formatString с форматированием даты, хотя Utilities.formatDate сам по себе не имеет параметра локали. Форматирование названий месяцев/дней зависит от настроек среды исполнения и временной зоны.
/**
* Форматирует текущую дату и время для разных сценариев.
*/
function formatCurrentDateTime(): void {
const now: Date = new Date();
const scriptTimeZone: string = Session.getScriptTimeZone(); // Например, 'America/New_York'
const moscowTimeZone: string = 'Europe/Moscow';
// Формат ISO 8601 в временной зоне скрипта
const formattedDefault: string = Utilities.formatDate(now, scriptTimeZone, 'yyyy-MM-dd HH:mm:ss');
Logger.log(`Формат по умолчанию (${scriptTimeZone}): ${formattedDefault}`);
// Формат для России (Москва)
const formattedMoscow: string = Utilities.formatDate(now, moscowTimeZone, 'dd.MM.yyyy HH:mm:ss');
Logger.log(`Формат для Москвы (${moscowTimeZone}): ${formattedMoscow}`);
// Только дата
const formattedDateOnly: string = Utilities.formatDate(now, scriptTimeZone, 'yyyy-MM-dd');
Logger.log(`Только дата (${scriptTimeZone}): ${formattedDateOnly}`);
// Дата с полным названием дня недели и месяца (локализация зависит от среды)
const formattedFull: string = Utilities.formatDate(now, scriptTimeZone, 'EEEE, d MMMM yyyy HH:mm');
Logger.log(`Полный формат (${scriptTimeZone}): ${formattedFull}`);
}Практические примеры использования текущей даты и времени
Запись текущей даты и времени в Google Sheets
Часто используется для логирования выполнения скриптов, отметки времени обновления данных или создания записей с временной меткой.
/**
* Записывает текущую временную метку и сообщение в активный лист Google Sheets.
* @param {string} message Сообщение для записи.
* @param {string} timeZone Целевая временная зона.
*/
function logToSheet(message: string, timeZone: string = Session.getScriptTimeZone()): void {
const sheet: GoogleAppsScript.Spreadsheet.Sheet = SpreadsheetApp.getActiveSheet();
const now: Date = new Date();
const timestamp: string = Utilities.formatDate(now, timeZone, 'yyyy-MM-dd HH:mm:ss');
// Добавляет новую строку с временной меткой и сообщением
sheet.appendRow([timestamp, message]);
}
// Пример вызова: logToSheet('Запуск процесса обработки данных');Создание событий в Google Calendar с использованием текущей даты и времени
Можно создавать события, начинающиеся немедленно или через определенный интервал от текущего момента.
/**
* Создает событие в Google Calendar, начинающееся через час от текущего момента.
* @param {string} title Название события.
* @param {string} calendarId ID календаря (или 'primary' для основного).
*/
function scheduleEventFromNow(title: string, calendarId: string = 'primary'): void {
const calendar: GoogleAppsScript.Calendar.Calendar = CalendarApp.getCalendarById(calendarId);
const now: Date = new Date();
// Время начала: сейчас + 1 час (3600 секунд * 1000 миллисекунд)
const startTime: Date = new Date(now.getTime() + 60 * 60 * 1000);
// Время окончания: начало + 1 час
const endTime: Date = new Date(startTime.getTime() + 60 * 60 * 1000);
try {
const event: GoogleAppsScript.Calendar.CalendarEvent = calendar.createEvent(title, startTime, endTime);
Logger.log(`Событие создано: ${event.getTitle()} (ID: ${event.getId()})`);
} catch (e) {
Logger.log(`Ошибка создания события: ${e}`);
}
}
// Пример вызова: scheduleEventFromNow('Срочное совещание по PPC-кампании');Добавление временной метки к имени файла в Google Drive
Полезно при создании резервных копий или генерации отчетов, чтобы имена файлов были уникальными и отражали время создания.
/**
* Создает копию файла в Google Drive с добавлением временной метки к имени.
* @param {string} fileId ID исходного файла.
* @param {string} targetFolderId ID папки для сохранения копии.
*/
function backupFileWithTimestamp(fileId: string, targetFolderId: string): void {
try {
const file: GoogleAppsScript.Drive.File = DriveApp.getFileById(fileId);
const folder: GoogleAppsScript.Drive.Folder = DriveApp.getFolderById(targetFolderId);
const now: Date = new Date();
const timeZone: string = Session.getScriptTimeZone();
const timestamp: string = Utilities.formatDate(now, timeZone, 'yyyyMMdd_HHmmss');
const newName: string = `${file.getName()}_backup_${timestamp}`;
const copiedFile: GoogleAppsScript.Drive.File = file.makeCopy(newName, folder);
Logger.log(`Создана копия файла: ${copiedFile.getName()} (ID: ${copiedFile.getId()}) в папке ${folder.getName()}`);
} catch (e) {
Logger.log(`Ошибка копирования файла: ${e}`);
}
}
// Пример вызова: backupFileWithTimestamp('ID_ВАШЕГО_ФАЙЛА', 'ID_ПАПКИ_НАЗНАЧЕНИЯ');Расширенные возможности и альтернативные подходы
Использование библиотеки Moment.js для работы с датой и временем (более продвинутые операции)
Moment.js (требует добавления в проект) предоставляет богатый API для манипуляций с датами: добавление/вычитание времени (add, subtract), получение относительного времени (fromNow), проверка валидности, работа с длительностями. Это может упростить код для сложных сценариев, но увеличивает зависимость проекта.
// Предварительно нужно добавить библиотеку Moment.js в проект
// Идентификатор скрипта: 15I5UtU-rcMgcomponenta_EuqFEG2zYm339e8U-B0KeU4eiFAWQxh-e-klt3_
/**
* Демонстрация использования Moment.js (требуется подключенная библиотека).
*/
function demoMomentLib(): void {
if (typeof Moment === 'undefined') {
Logger.log('Библиотека Moment.js не подключена.');
return;
}
const now = Moment(); // Текущий момент
const scriptTimeZone = Session.getScriptTimeZone();
// Форматирование с использованием Moment.js (в зоне скрипта)
Logger.log(`Moment Формат: ${now.tz(scriptTimeZone).format('YYYY-MM-DD HH:mm:ss Z')}`);
// Добавление 7 дней
const nextWeek = Moment().add(7, 'days');
Logger.log(`Через неделю: ${nextWeek.format('DD.MM.YYYY')}`);
// Относительное время
const pastDate = Moment('2023-01-01');
Logger.log(`Дата ${pastDate.format('YYYY-MM-DD')} была ${pastDate.fromNow()}`);
}Обработка ошибок и учет часовых поясов
Всегда учитывайте возможные ошибки, особенно при парсинге дат из внешних источников или при работе с пользовательским вводом. Используйте try...catch блоки. Правильная обработка часовых поясов критична для приложений, работающих с пользователями из разных регионов. Убедитесь, что вы используете правильную временную зону (Session.getScriptTimeZone(), Session.getActiveUser().getTimeZone(), или фиксированную) при форматировании и расчетах.
Оптимизация кода для повышения производительности
Хотя получение new Date() и форматирование через Utilities.formatDate() достаточно быстры, избегайте их многократного вызова внутри циклов, если можно получить или отформатировать дату один раз и переиспользовать результат. Например, при добавлении множества строк в Google Sheets с одной и той же временной меткой, получите и отформатируйте её один раз перед циклом.
/**
* Пример оптимизации: форматирование даты вне цикла.
* @param {string[][]} data Массив данных для записи.
* @param {string} timeZone Целевая временная зона.
*/
function optimizedLogBatchToSheet(data: string[][], timeZone: string = Session.getScriptTimeZone()): void {
const sheet: GoogleAppsScript.Spreadsheet.Sheet = SpreadsheetApp.getActiveSheet();
const now: Date = new Date();
const timestamp: string = Utilities.formatDate(now, timeZone, 'yyyy-MM-dd HH:mm:ss');
const rowsToAdd: string[][] = data.map(row => [timestamp, ...row]);
if (rowsToAdd.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, rowsToAdd.length, rowsToAdd[0].length).setValues(rowsToAdd);
Logger.log(`Добавлено ${rowsToAdd.length} строк с временной меткой ${timestamp}`);
} else {
Logger.log('Нет данных для добавления.');
}
}
// Пример вызова:
// const analyticsData = [['Campaign A', '100', '10'], ['Campaign B', '250', '25']];
// optimizedLogBatchToSheet(analyticsData);Работа с датой и временем в Google Apps Script является неотъемлемой частью разработки эффективных и надежных скриптов для автоматизации задач в Google Workspace.