Преобразование объектов Date в строковые представления является фундаментальной операцией при работе с данными в Google Apps Script. Эта необходимость возникает во множестве сценариев, от логирования и отображения информации пользователю до интеграции с внешними системами и API.
Зачем преобразовывать дату в строку?
- Представление данных: Отображение дат в читаемом формате в интерфейсах пользователя, отчетах Google Sheets, документах или электронных письмах.
- Сериализация: Передача данных о дате и времени в форматах, понятных другим системам (например, JSON или XML для API).
- Хранение и логирование: Запись дат в текстовые логи или ячейки таблиц в стандартизированном виде.
- Формирование ключей и идентификаторов: Использование строковых представлений дат для создания уникальных идентификаторов или ключей сортировки.
Обзор основных методов работы с датами в Apps Script
Google Apps Script предоставляет встроенный JavaScript объект Date для работы с датами и временем. Однако для гибкого форматирования и преобразования в строки ключевую роль играет сервис Utilities, в частности его метод formatDate().
Метод Utilities.formatDate(): Основной инструмент форматирования
Метод Utilities.formatDate(date, timeZone, format) является наиболее мощным и рекомендуемым способом преобразования объекта Date в строку с заданным форматом и часовым поясом.
Синтаксис и параметры Utilities.formatDate()
/**
* Преобразует объект Date в строку.
*
* @param {Date} date Объект Date для форматирования.
* @param {string} timeZone Часовой пояс в формате TZ Database (например, 'America/New_York', 'Europe/Moscow'). Можно использовать Session.getScriptTimeZone() для получения часового пояса скрипта.
* @param {string} format Строка формата, определяющая выходное представление даты и времени (см. справочник форматов).
* @return {string} Отформатированная строка даты и времени.
*/
function convertDateToString(date: Date, timeZone: string, format: string): string {
return Utilities.formatDate(date, timeZone, format);
}
Примеры использования с различными форматами даты и времени
Рассмотрим несколько примеров:
// Получаем текущую дату и время
const now: Date = new Date();
// Часовой пояс скрипта
const scriptTimeZone: string = Session.getScriptTimeZone();
// Формат YYYY-MM-DD
const formattedDate1: string = Utilities.formatDate(now, scriptTimeZone, 'yyyy-MM-dd');
Logger.log(formattedDate1); // Пример вывода: 2023-10-27
// Формат DD/MM/YYYY HH:mm:ss
const formattedDate2: string = Utilities.formatDate(now, scriptTimeZone, 'dd/MM/yyyy HH:mm:ss');
Logger.log(formattedDate2); // Пример вывода: 27/10/2023 15:30:00
// Формат с названием месяца и днем недели
const formattedDate3: string = Utilities.formatDate(now, 'Europe/Paris', 'EEEE, d MMMM yyyy');
Logger.log(formattedDate3); // Пример вывода: пятница, 27 октября 2023
Указание часового пояса (timezone)
Корректное указание часового пояса (timeZone) критически важно. Ошибки в часовом поясе приводят к неверному отображению времени. Используйте Session.getScriptTimeZone() для таймзоны скрипта или укажите конкретную таймзону из TZ Database (например, ‘Asia/Yekaterinburg’, ‘UTC’).
/**
* Получает текущее время в Москве.
*
* @return {string} Время в формате HH:mm:ss.
*/
function getMoscowTime(): string {
const now: Date = new Date();
const moscowTimeZone: string = 'Europe/Moscow';
const format: string = 'HH:mm:ss';
return Utilities.formatDate(now, moscowTimeZone, format);
}
Logger.log(getMoscowTime());
Форматы даты и времени: Подробный справочник
Метод Utilities.formatDate() использует спецификаторы формата, основанные на Java SimpleDateFormat. Понимание этих спецификаторов позволяет гибко настраивать вывод.
Стандартные спецификаторы формата (год, месяц, день, час, минута, секунда)
y: Год (например,yy->23,yyyy->2023)M: Месяц в году (например,M->9,MM->09,MMM->сен,MMMM->сентября)d: День месяца (например,d->5,dd->05)E: День недели (например,E->Вт,EEEE->вторник)H: Час дня (0-23) (например,H->9,HH->09)h: Час в am/pm (1-12) (например,h->3,hh->03)m: Минута в часе (например,m->5,mm->05)s: Секунда в минуте (например,s->8,ss->08)S: Миллисекундаa: Маркер AM/PMz: Часовой пояс (например,GMT+03:00)Z: Смещение часового пояса (например,+0300)
Настройка формата: создание собственных шаблонов
Комбинируя спецификаторы и литералы (текст, не являющийся спецификатором, заключается в одинарные кавычки), можно создавать любые шаблоны.
const now: Date = new Date();
const scriptTimeZone: string = Session.getScriptTimeZone();
// Пример сложного формата
const customFormat: string = "'Отчет от' dd MMMM yyyy 'г.' HH:mm '('zzz')'";
const formattedString: string = Utilities.formatDate(now, scriptTimeZone, customFormat);
Logger.log(formattedString); // Пример: Отчет от 27 октября 2023 г. 15:30 (GMT+03:00)
Примеры наиболее часто используемых форматов (ISO 8601, RFC 2822 и т.д.)
- ISO 8601 (Date):
yyyy-MM-dd(например,2023-10-27) - ISO 8601 (DateTime):
yyyy-MM-dd'T'HH:mm:ss'Z'(для UTC) илиyyyy-MM-dd'T'HH:mm:ssXXX(с указанием смещения, например2023-10-27T15:30:00+03:00) - RFC 2822:
EEE, dd MMM yyyy HH:mm:ss Z(например,Fri, 27 Oct 2023 15:30:00 +0300) - Локализованный формат (Россия):
dd.MM.yyyy HH:mm(например,27.10.2023 15:30)
Практические примеры преобразования даты в строку
Преобразование даты для записи в Google Sheets
При записи дат в Google Sheets важно учитывать, что Таблицы могут автоматически интерпретировать строки как даты. Однако для явного контроля формата лучше записывать дату как строку.
/**
* Записывает текущую дату и время в ячейку A1 в формате ГГГГ-ММ-ДД ЧЧ:ММ.
*/
function logDateTimeToSheet(): void {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const now: Date = new Date();
const scriptTimeZone: string = Session.getScriptTimeZone();
const format: string = 'yyyy-MM-dd HH:mm';
const formattedDate: string = Utilities.formatDate(now, scriptTimeZone, format);
// Записываем как строку
sheet.getRange('A1').setValue(formattedDate);
}
Форматирование даты для отправки в электронном письме
В теле письма дата должна быть представлена в понятном для получателя виде.
/**
* Отправляет email с отформатированной датой события.
*
* @param {string} recipientEmail Email получателя.
* @param {Date} eventDate Дата события.
*/
function sendEventNotification(recipientEmail: string, eventDate: Date): void {
const timeZone: string = 'Europe/Moscow'; // Или другая релевантная зона
const format: string = "dd MMMM yyyy 'в' HH:mm z";
const formattedEventDate: string = Utilities.formatDate(eventDate, timeZone, format);
const subject: string = 'Напоминание о событии';
const body: string = `Уважаемый пользователь,\n\nНапоминаем вам о событии, которое состоится ${formattedEventDate}.\n\nС уважением,\nВаша Система Уведомлений`;
MailApp.sendEmail(recipientEmail, subject, body);
}
Преобразование даты для использования в API
Многие API требуют даты в строгом формате, чаще всего ISO 8601.
/**
* Формирует URL для API с датой в формате ISO 8601.
*
* @param {Date} reportDate Дата для отчета.
* @return {string} URL для запроса к API.
*/
function buildApiUrlWithDate(reportDate: Date): string {
const timeZone: string = 'UTC'; // API часто требуют UTC
const format: string = "yyyy-MM-dd'T'HH:mm:ss'Z'"; // ISO 8601 UTC
const formattedDate: string = Utilities.formatDate(reportDate, timeZone, format);
const baseUrl: string = 'https://api.example.com/data';
const apiUrl: string = `${baseUrl}?report_date=${encodeURIComponent(formattedDate)}`;
Logger.log(`Generated API URL: ${apiUrl}`);
return apiUrl;
}
Распространенные ошибки и способы их устранения
Неправильный часовой пояс: Как избежать ошибок
Всегда явно указывайте часовой пояс (timeZone). Не полагайтесь на настройки по умолчанию, так как они могут отличаться в разных окружениях (скрипт, пользователь, таблица). Используйте Session.getScriptTimeZone() для консистентности в рамках выполнения скрипта или конкретные TZ Database имена для работы с определенными регионами.
Некорректный формат: Решение проблем с отображением даты
- Проверяйте спецификаторы: Убедитесь, что используете правильные символы и их количество (например,
MMдля двузначного месяца,Mдля одно/двузначного). - Экранируйте литералы: Текст, который не является спецификатором формата, заключайте в одинарные кавычки (
'текст'). - Тестируйте: Используйте
Logger.log()для проверки результата форматирования перед использованием строки.
Обработка null и пустых значений дат
Перед вызовом Utilities.formatDate() всегда проверяйте, что объект Date не является null или невалидным. Попытка форматировать null приведет к ошибке.
/**
* Безопасно форматирует дату, возвращая пустую строку для null/невалидных дат.
*
* @param {Date | null | any} date Дата для форматирования.
* @param {string} timeZone Часовой пояс.
* @param {string} format Формат.
* @return {string} Отформатированная дата или пустая строка.
*/
function safeFormatDate(date: Date | null | any, timeZone: string, format: string): string {
if (date instanceof Date && !isNaN(date.getTime())) {
try {
return Utilities.formatDate(date, timeZone, format);
} catch (e) {
Logger.log(`Error formatting date: ${e}`);
return ''; // Или другое значение по умолчанию
}
} else {
// Logger.log('Input date is null or invalid.');
return ''; // Возвращаем пустую строку для null или невалидных дат
}
}
// Пример использования
const validDate: Date = new Date();
const invalidDate: any = null;
const sheetValueDate: any = SpreadsheetApp.getActiveSpreadsheet().getRange('B1').getValue(); // Может быть не датой
const tz: string = Session.getScriptTimeZone();
const fmt: string = 'yyyy-MM-dd';
Logger.log(safeFormatDate(validDate, tz, fmt));
Logger.log(safeFormatDate(invalidDate, tz, fmt));
Logger.log(safeFormatDate(sheetValueDate, tz, fmt));
Освоив Utilities.formatDate() и принципы работы с форматами и часовыми поясами, вы сможете эффективно преобразовывать даты в строки для любых задач в Google Apps Script.