SetUTCHours: примеры (JAVASCRIPT)

Использование setUTCHours для управления временем по UTC в JavaScript
Раздел: Дата и время, UTC методы
setUTCHours(hoursValue: number, minutesValue?: number, secondsValue?: number, msValue?: number): number

Основы метода setUTCHours

Метод setUTCHours() принадлежит объекту Date в JavaScript. Его применяют для установки часов указанной даты по всемирному координированному времени (UTC). Метод изменяет дату объекта и возвращает обновленное количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 UTC.

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

Синтаксис: dateObj.setUTCHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])

  • hoursValue (обязательный): Целое число от 0 до 23, представляющее часы.
  • minutesValue (необязательный): Целое число от 0 до 59, представляющее минуты.
  • secondsValue (необязательный): Целое число от 0 до 59, представляющее секунды.
  • msValue (необязательный): Целое число от 0 до 999, представляющее миллисекунды.

Возвращаемое значение: Количество миллисекунд между новой установленной датой и полуночью 1 января 1970 года по UTC. При этом исходный объект Date мутирует.

Простые примеры использования

Пример 1: Установка только часов

const date = new Date('2023-12-25T00:00:00.000Z');
console.log('Изначально:', date.toISOString());
const result = date.setUTCHours(15);
console.log('Результат (мс):', result);
console.log('Измененная дата:', date.toISOString());
Изначально: 2023-12-25T00:00:00.000Z
Результат (мс): 1703516400000
Измененная дата: 2023-12-25T15:00:00.000Z

Пример 2: Установка часов, минут и секунд

const date = new Date('2023-06-10T12:30:45.000Z');
date.setUTCHours(8, 15, 30);
console.log(date.toISOString());
2023-06-10T08:15:30.000Z

Пример 3: Корректная обработка крайних значений

const date = new Date('2023-01-31T23:59:59.999Z');
// Установка 25 часов (переход на следующий день)
date.setUTCHours(25);
console.log(date.toISOString());
2023-02-01T01:00:00.000Z

Альтернативные методы в JavaScript

setHours(): Аналогичный метод, но работает с локальным временем системы, а не UTC. Используется, когда необходимо учитывать или выводить время для конкретного региона пользователя.

setUTCMinutes(), setUTCSeconds(), setUTCMilliseconds(): Узкоспециализированные методы для установки отдельных компонентов времени в UTC. Предпочтительны, если нужно изменить только минуты или секунды, не затрагивая часы.

Temporal (экспериментальный API): Новый, более удобный и иммутабельный API для работы со временем. Рекомендуется для новых проектов, готовых использовать экспериментальные возможности, так как он устраняет многие недостатки объекта Date.

Частые ошибки и проблемы

1. Путаница между setUTCHours и setHours:

const date = new Date('2023-12-25T00:00:00Z'); // UTC дата
// Допустим, локальный пояс UTC+3
console.log('UTC:', date.toISOString());
date.setHours(15); // Установит 15 часов по МОСКВЕ (UTC+3)
console.log('После setHours:', date.toISOString());
// Восстановим дату
date.setUTCHours(0);
date.setUTCHours(15); // Установит 15 часов строго по UTC
console.log('После setUTCHours:', date.toISOString());
UTC: 2023-12-25T00:00:00.000Z
После setHours: 2023-12-25T12:00:00.000Z
После setUTCHours: 2023-12-25T15:00:00.000Z

2. Неявное изменение других компонентов даты при передаче недопустимых значений:

const date = new Date('2023-01-31T23:30:00.000Z');
// Установка 70 минут корректирует и часы
date.setUTCHours(10, 70);
console.log(date.toISOString());
2023-01-31T11:10:00.000Z // Часы увеличились на 1

3. Игнорирование возвращаемого значения:

Метод возвращает таймстамп, но новички часто забывают, что исходный объект Date также изменяется. Это может привести к неожиданным мутациям в коде.

История изменений

Поведение метода setUTCHours() оставалось стабильным с момента стандартизации в ECMAScript 1 (1997 год). Основные изменения связаны с общей спецификацией объекта Date.

В ECMAScript 2015 (ES6) были уточнены детали обработки нечисловых аргументов (они приводятся к числу) и корректировки значений, выходящих за допустимые диапазоны (что приводит к изменению более старших компонентов даты).

Современные движки JavaScript следуют стандарту ECMAScript 5.1 и выше, где поведение полностью определено. Нет существенных различий в работе метода между последними версиями ECMAScript.

Расширенные примеры применения

Пример 1: Сброс времени на начало дня (00:00:00.000) по UTC

Пример javascript
function startOfUTCDay(date) {
  const newDate = new Date(date); // Создание копии
  newDate.setUTCHours(0, 0, 0, 0);
  return newDate;
}
const now = new Date();
console.log('Исходная:', now.toISOString());
console.log('Начало дня:', startOfUTCDay(now).toISOString());
Исходная: 2023-10-05T14:33:12.456Z
Начало дня: 2023-10-05T00:00:00.000Z

Пример 2: Добавление определенного количества часов к дате

Пример javascript
function addUTCHours(date, hoursToAdd) {
  const newDate = new Date(date);
  const currentHours = newDate.getUTCHours();
  newDate.setUTCHours(currentHours + hoursToAdd);
  return newDate;
}
const initialDate = new Date('2023-07-01T10:00:00.000Z');
console.log('+8 часов:', addUTCHours(initialDate, 8).toISOString());
// Корректно обрабатывает переход через полночь
console.log('+20 часов:', addUTCHours(initialDate, 20).toISOString());
+8 часов: 2023-07-01T18:00:00.000Z
+20 часов: 2023-07-02T06:00:00.000Z

Пример 3: Установка времени для всех дат в массиве

Пример javascript
const dates = [
  new Date('2023-01-01'),
  new Date('2023-02-15'),
  new Date('2023-03-30')
];
// Установка времени 09:30:00 UTC для каждой даты
const standardizedDates = dates.map(date => {
  const d = new Date(date);
  d.setUTCHours(9, 30, 0, 0);
  return d;
});
standardizedDates.forEach(d => console.log(d.toISOString()));
2023-01-01T09:30:00.000Z
2023-02-15T09:30:00.000Z
2023-03-30T09:30:00.000Z

Пример 4: Создание временных меток для графика с интервалом в 3 часа по UTC

Пример javascript
function generateUTCTimeLabels(startDate, periods) {
  const labels = [];
  const current = new Date(startDate);
  current.setUTCHours(0, 0, 0, 0);
  for (let i = 0; i < periods; i++) {
    labels.push(new Date(current).toISOString().substr(11, 5)); // HH:mm
    current.setUTCHours(current.getUTCHours() + 3);
  }
  return labels;
}
console.log(generateUTCTimeLabels(new Date(), 8));
['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00']

Аналоги в других языках программирования

Python (datetime.replace с часовым поясом utc):

from datetime import datetime, timezone
dt = datetime(2023, 12, 25, 0, 0, tzinfo=timezone.utc)
# Создание нового объекта (иммутабельно)
new_dt = dt.replace(hour=15)
print(dt.isoformat())
print(new_dt.isoformat())
2023-12-25T00:00:00+00:00
2023-12-25T15:00:00+00:00

PHP (setTime с DateTimeImmutable):

$date = new DateTimeImmutable('2023-12-25T00:00:00Z');
$newDate = $date->setTime(15, 0, 0); // Устанавливает локальное время
$newDateUTC = $date->setTime(15, 0, 0)->setTimezone(new DateTimeZone('UTC'));
echo $date->format('c'), "\n";
echo $newDateUTC->format('c');
2023-12-25T00:00:00+00:00
2023-12-25T15:00:00+00:00

MySQL (функция DATE_ADD / временные литералы):

-- Установка конкретного времени для timestamp
SELECT TIMESTAMP('2023-12-25 00:00:00') + INTERVAL 15 HOUR AS new_time;
new_time: 2023-12-25 15:00:00

Ключевое отличие JavaScript-метода — мутабельность и работа непосредственно с объектом Date, в то время как во многих других языках операции со временем иммутабельны и требуют явного указания часового пояса.

JS setUTCHours function comments

En
SetUTCHours Sets the hour for a specified date according to universal time