Google Apps Script: Как преобразовать дату в строку?

Преобразование объектов 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/PM
  • z: Часовой пояс (например, 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.


Добавить комментарий