В API Js-joda отсутствуют специальные типы для
представления понятий «полдень» и «полночь». Эти значения моделируются
через стандартные классы времени: LocalTime,
LocalDateTime, ZonedDateTime и связанные типы.
Несмотря на внешнюю простоту, работа с такими моментами времени содержит
множество нюансов, связанных с переходом суток, часовыми поясами,
сравнением дат и сериализацией.
Полночь соответствует началу суток и представляется временем
00:00.
const { LocalTime } = require('@js-joda/core');
const midnight = LocalTime.MIDNIGHT;
console.log(midnight.toString());
// 00:00
Эквивалентное создание через фабричный метод:
const midnight = LocalTime.of(0, 0);
Также допустим разбор строки:
const midnight = LocalTime.parse('00:00');
Полночь относится уже к новым суткам.
Например:
const { LocalDateTime, LocalDate, LocalTime } = require('@js-joda/core');
const date = LocalDate.of(2025, 5, 10);
const startOfDay = LocalDateTime.of(date, LocalTime.MIDNIGHT);
console.log(startOfDay.toString());
// 2025-05-10T00:00
Здесь 00:00 принадлежит именно 2025-05-10,
а не предыдущему дню.
Полдень соответствует времени 12:00.
const { LocalTime } = require('@js-joda/core');
const noon = LocalTime.NOON;
console.log(noon.toString());
// 12:00
Создание вручную:
const noon = LocalTime.of(12, 0);
Разбор строки:
const noon = LocalTime.parse('12:00');
Класс LocalTime содержит готовые константы:
| Константа | Значение |
|---|---|
LocalTime.MIDNIGHT |
00:00 |
LocalTime.NOON |
12:00 |
Использование констант делает код более читаемым:
const meetingStart = LocalTime.NOON;
const resetTime = LocalTime.MIDNIGHT;
Для получения полуночи конкретной даты используется метод
atStartOfDay().
const { LocalDate } = require('@js-joda/core');
const date = LocalDate.of(2025, 8, 20);
const start = date.atStartOfDay();
console.log(start.toString());
// 2025-08-20T00:00
Метод возвращает объект LocalDateTime.
В Js-joda нет специальной константы «конец суток». Обычно
используется время 23:59:59.999999999.
const { LocalTime } = require('@js-joda/core');
const endOfDay = LocalTime.of(23, 59, 59, 999999999);
console.log(endOfDay.toString());
// 23:59:59.999999999
Важно понимать разницу:
00:00 — начало новых суток23:59:59.999999999 — последний наносекундный момент
текущих сутокconst { LocalTime } = require('@js-joda/core');
const time = LocalTime.parse('00:00');
const isMidnight = time.equals(LocalTime.MIDNIGHT);
console.log(isMidnight);
// true
const { LocalTime } = require('@js-joda/core');
const time = LocalTime.parse('12:00');
const isNoon = time.equals(LocalTime.NOON);
console.log(isNoon);
// true
Полдень часто используется как разделитель первой и второй половины дня.
const { LocalTime } = require('@js-joda/core');
const time = LocalTime.parse('15:30');
console.log(time.isAfter(LocalTime.NOON));
// true
Пример проверки:
if (time.isBefore(LocalTime.NOON)) {
console.log('До полудня');
} else {
console.log('После полудня');
}
Полдень и полночь вызывают наибольшее количество ошибок именно при использовании AM/PM.
| Формат | Значение |
|---|---|
00:00 |
24-часовой |
12:00 AM |
12-часовой |
| Формат | Значение |
|---|---|
12:00 |
24-часовой |
12:00 PM |
12-часовой |
const {
LocalTime,
DateTimeFormatter
} = require('@js-joda/core');
const formatter = DateTimeFormatter.ofPattern('hh:mm a');
console.log(LocalTime.MIDNIGHT.format(formatter));
// 12:00 AM
console.log(LocalTime.NOON.format(formatter));
// 12:00 PM
const {
LocalTime,
DateTimeFormatter
} = require('@js-joda/core');
const formatter = DateTimeFormatter.ofPattern('hh:mm a');
const midnight = LocalTime.parse('12:00 AM', formatter);
const noon = LocalTime.parse('12:00 PM', formatter);
console.log(midnight.toString());
// 00:00
console.log(noon.toString());
// 12:00
const { LocalTime } = require('@js-joda/core');
const midnight = LocalTime.MIDNIGHT;
console.log(midnight.plusHours(5).toString());
// 05:00
const { LocalTime } = require('@js-joda/core');
const noon = LocalTime.NOON;
console.log(noon.plusHours(3).toString());
// 15:00
Одной из ключевых особенностей времени является циклический характер суток.
const { LocalTime } = require('@js-joda/core');
const time = LocalTime.of(23, 30);
const result = time.plusHours(2);
console.log(result.toString());
// 01:30
Дата при этом не изменяется, поскольку LocalTime не
содержит информации о календарном дне.
Если важна дата, необходимо использовать
LocalDateTime.
const { LocalDateTime } = require('@js-joda/core');
const dateTime = LocalDateTime.parse('2025-05-10T23:30');
const result = dateTime.plusHours(2);
console.log(result.toString());
// 2025-05-11T01:30
Здесь уже происходит переход на следующий день.
При работе с часовыми поясами полночь может вести себя неожиданно из-за переходов летнего времени.
const {
ZonedDateTime,
ZoneId
} = require('@js-joda/core');
const zone = ZoneId.of('Europe/Berlin');
const dateTime = ZonedDateTime.parse(
'2025-05-10T00:00+02:00[Europe/Berlin]'
);
console.log(dateTime.toString());
В некоторых часовых поясах переход летнего времени может:
Пример:
const {
LocalDate,
ZoneId
} = require('@js-joda/core');
const zone = ZoneId.of('America/Sao_Paulo');
const date = LocalDate.of(2018, 11, 4);
const start = date.atStartOfDay(zone);
console.log(start.toString());
Во время DST реальное начало суток может быть не
00:00.
Метод учитывает правила временной зоны.
const {
LocalDate,
ZoneId
} = require('@js-joda/core');
const zone = ZoneId.of('Asia/Tokyo');
const result = LocalDate
.of(2025, 1, 1)
.atStartOfDay(zone);
console.log(result.toString());
Возвращается ZonedDateTime.
В LocalTime существует также константа
MIN.
console.log(LocalTime.MIN.toString());
// 00:00
Она эквивалентна полуночи:
console.log(LocalTime.MIN.equals(LocalTime.MIDNIGHT));
// true
Но семантически они отличаются:
| Константа | Смысл |
|---|---|
MIDNIGHT |
Полночь |
MIN |
Минимально возможное время |
Технически это одинаковые значения:
console.log(
LocalTime.NOON.equals(LocalTime.of(12, 0))
);
// true
Однако использование NOON повышает читаемость кода:
const lunchTime = LocalTime.NOON;
Частая ошибка — неправильная проверка ночного интервала.
Неверный вариант:
if (time.isAfter(start) && time.isBefore(end))
Если диапазон проходит через полночь, логика ломается.
const { LocalTime } = require('@js-joda/core');
const start = LocalTime.of(22, 0);
const end = LocalTime.of(6, 0);
const time = LocalTime.of(1, 30);
const isNight =
time.isAfter(start) || time.isBefore(end);
console.log(isNight);
// true
Во многих системах сутки заканчиваются ровно в полночь.
const {
LocalDate,
LocalDateTime,
LocalTime
} = require('@js-joda/core');
const nextDay = LocalDate.of(2025, 6, 1);
const boundary = LocalDateTime.of(
nextDay,
LocalTime.MIDNIGHT
);
console.log(boundary.toString());
// 2025-06-01T00:00
const {
LocalTime,
Duration
} = require('@js-joda/core');
const now = LocalTime.of(20, 15);
const untilMidnight = Duration.between(
now,
LocalTime.MIDNIGHT.plusHours(24)
);
console.log(untilMidnight.toHours());
// 3
const {
LocalTime,
ChronoUnit
} = require('@js-joda/core');
const time = LocalTime.of(8, 45);
const hours = ChronoUnit.HOURS.between(
LocalTime.MIDNIGHT,
time
);
console.log(hours);
// 8
const { LocalTime } = require('@js-joda/core');
const backupTime = LocalTime.MIDNIGHT;
console.log(`Резервное копирование: ${backupTime}`);
const { LocalTime } = require('@js-joda/core');
function isMorning(time) {
return time.isBefore(LocalTime.NOON);
}
console.log(
isMorning(LocalTime.of(9, 0))
);
// true
const { LocalTime } = require('@js-joda/core');
const time = LocalTime.NOON;
const json = JSON.stringify({
time: time.toString()
});
console.log(json);
// {"time":"12:00"}
const parsed = JSON.parse(json);
const restored = LocalTime.parse(parsed.time);
console.log(restored.equals(LocalTime.NOON));
// true
Неверная интерпретация:
| Значение | Реальное время |
|---|---|
12:00 AM |
Полночь |
12:00 PM |
Полдень |
const result = LocalTime.of(23, 0).plusHours(2);
console.log(result.toString());
// 01:00
Дата теряется.
Строка 24:00 не является допустимым временем в
LocalTime.
Неверно:
LocalTime.parse('24:00');
Правильно:
LocalTime.MIDNIGHT
или:
LocalDate
.of(2025, 5, 10)
.plusDays(1)
.atStartOfDay();
const { LocalTime } = require('@js-joda/core');
function isNightShift(time) {
const start = LocalTime.of(22, 0);
const end = LocalTime.of(6, 0);
return time.equals(start)
|| time.isAfter(start)
|| time.isBefore(end);
}
console.log(
isNightShift(LocalTime.of(1, 15))
);
// true
const { LocalTime } = require('@js-joda/core');
function getDayPeriod(time) {
if (time.equals(LocalTime.MIDNIGHT)) {
return 'Полночь';
}
if (time.equals(LocalTime.NOON)) {
return 'Полдень';
}
if (time.isBefore(LocalTime.NOON)) {
return 'Первая половина дня';
}
return 'Вторая половина дня';
}