d3-time
При визуализации временных рядов, анализе временных закономерностей или работе со временем в целом неравномерность стандартных временных единиц быстро становится очевидной. Например, в григорианском календаре большинство месяцев имеют 31 день, но некоторые имеют 28, 29 или 30 дней; большинство лет имеют 365 дней, но високосные годы имеют 366 дней; а с переходом на летнее время большинство дней имеют 24 часа, но некоторые имеют 23 или 25 часов. Кроме того, правила перехода на летнее время различаются по всему миру.
В результате этих временных особенностей выполнение, казалось бы, тривиальных задач может оказаться сложным. Например, если вы хотите вычислить количество дней, прошедших между двумя датами, вы не можете просто вычесть и разделить на 24 часа (86 400 000 мс):
start = new Date(2015, 02, 01) // 2015-03-01T00:00 end = new Date(2015, 03, 01) // 2015-04-01T00:00 (end - start) / 864e5 // 30.958333333333332, oops! 🤯
Однако вы можете использовать d3.timeDay.count:
d3.timeDay.count(start, end) // 31 😌
Интервал день interval — это один из нескольких, предоставляемых d3-time. Каждый интервал представляет собой стандартную временную единицу — часы, недели, месяцы и т. д. — и имеет методы для расчета граничных дат. Например, d3.timeDay вычисляет полночь (обычно 00:00 по местному времени) соответствующего дня. Помимо округления и подсчета, интервалы также можно использовать для генерации массивов граничных дат. Например, чтобы вычислить каждое воскресенье текущего месяца:
start = d3.timeMonth.floor() // 2015-01-01T00:00 stop = d3.timeMonth.ceil() // 2015-02-01T00:00 d3.timeWeek.range(start, stop) // [2015-01-07T00:00, 2015-01-14T00:00, 2015-01-21T00:00, 2015-01-28T00:00]
Модуль d3-time не реализует собственную систему календаря; он просто реализует удобный API для календарной арифметики поверх ECMAScript Date. Таким образом, он игнорирует високосные секунды и может работать только с местным часовым поясом и координированным универсальным временем (UTC).
Этот модуль используется шкалами времени D3 для генерации разумных делений, форматом времени D3 и также может быть использован напрямую для выполнения задач, таких как макеты календаря.
Установка
Если вы используете npm, npm install d3-time. Вы также можете скачать последнюю версию на GitHub. Для обычного HTML в современных браузерах импортируйте d3-time из Skypack:
<script type="module">
import {timeDay} from "https://cdn.skypack.dev/d3-time@3";
const day = timeDay();
</script> Для устаревших сред вы можете загрузить UMD-пакет d3-time с CDN, основанного на npm, такого как jsDelivr; экспортируется глобальная переменная d3.
<script src="https://cdn.jsdelivr.net/npm/d3-array@3"></script> <script src="https://cdn.jsdelivr.net/npm/d3-time@3"></script> <script> const day = d3.timeDay(); </script>
Попробуйте d3-time в вашем браузере.
Справочник по API
interval([date]) · Исходный код
Эквивалентно interval.floor, за исключением того, что если date не указан, по умолчанию используется текущее время. Например, d3.timeYear(date) и d3.timeYear.floor(date) являются эквивалентными.
monday = d3.timeMonday() // the latest preceeding Monday, local time
interval.floor(date) · Исходный код
Возвращает новую дату, представляющую последнюю граничную дату интервала до или равную date. Например, d3.timeDay.floor(date) обычно возвращает 00:00 по местному времени на заданную дату date.
Этот метод идемпотентный: если указанная date уже приведена к нижней границе текущего интервала, возвращается новая дата с идентичным временем. Кроме того, возвращаемая дата является минимально выразимым значением связанного интервала, так что interval.floor(interval.floor(date) - 1) возвращает дату предыдущей граничной даты интервала.
Обратите внимание, что операторы == и === не сравнивают значения с объектами Date и, следовательно, вы не можете использовать их для определения того, уже ли указанная date приведена к нижней границе. Вместо этого преобразуйте в число и затем сравните:
// Returns true if the specified date is a day boundary.
function isDay(date) {
return +d3.timeDay.floor(date) === +date;
} Это более надежно, чем проверка, является ли время 00:00, поскольку в некоторых часовых поясах полночь может отсутствовать из-за перехода на летнее время.
interval.round(date) · Исходный код
Возвращает новую дату, представляющую ближайшую граничную дату интервала к date. Например, d3.timeDay.round(date) обычно возвращает 00:00 по местному времени на заданную дату date, если она находится до или в полдень, и 00:00 следующего дня, если она после полудня.
Этот метод идемпотентный: если указанная date уже окружена до текущего интервала, возвращается новая дата с идентичным временем.
interval.ceil(date) · Исходный код
Возвращает новую дату, представляющую самую раннюю граничную дату интервала после или равную date. Например, d3.timeDay.ceil(date) обычно возвращает 00:00 по местному времени на дату, следующую за заданной date.
Этот метод идемпотентный: если указанная date уже окружена до текущего интервала, возвращается новая дата с идентичным временем. Кроме того, возвращаемая дата является максимальным выразимым значением связанного интервала, так что interval.ceil(interval.ceil(date) + 1) возвращает дату следующей граничной даты интервала.
interval.offset(date[, step]) · Исходный код
Возвращает новую дату, равную date плюс step интервалов. Если step не указан, он по умолчанию равен 1. Если step отрицательный, то возвращаемая дата будет до указанной date; если step равен нулю, то возвращается копия указанной date; если step не целое число, он округляется вниз. Этот метод не округляет указанную date до интервала. Например, если date — сегодня в 17:34, то d3.timeDay.offset(date, 1) возвращает 17:34 завтра (даже если переход на летнее время изменился!).
interval.range(start, stop[, step]) · Исходный код
Возвращает массив дат, представляющих каждую граничную дату интервала после или равную start (включительно) и до stop (исключительно). Если step указан, то возвращается каждая step-ая граничная дата; например, для интервала d3.timeDay значение step равное 2 вернёт каждую вторую дату. Если step не целое число, он округляется вниз.
Первая дата в возвращаемом массиве — это самая ранняя граница после или равная start; последующие даты смещаются с помощью offset на step интервалов и округляются с помощью floor. Таким образом, два перекрывающихся диапазона могут быть согласованными. Например, этот диапазон содержит нечётные дни:
d3.timeDay.range(new Date(2015, 0, 1), new Date(2015, 0, 7), 2) // [2015-01-01T00:00, 2015-01-03T00:00, 2015-01-05T00:00]
В то время как этот содержит чётные дни:
d3.timeDay.range(new Date(2015, 0, 2), new Date(2015, 0, 8), 2) // [2015-01-02T00:00, 2015-01-04T00:00, 2015-01-06T00:00]
Чтобы сделать диапазоны согласованными, когда указан step, используйте interval.every вместо этого.
interval.filter(test) · Исходный код
Возвращает новый интервал, который является отфильтрованным подмножеством этого интервала, используя указанную функцию test. Функция test получает дату и должна возвращать true только в том случае, если указанная дата должна считаться частью интервала. Например, чтобы создать интервал, который возвращает 1, 11, 21 и 31 (если существует) каждого месяца:
d3.timeDay.filter(d => (d.getDate() - 1) % 10 === 0)
Возвращаемый отфильтрованный интервал не поддерживает interval.count. См. также interval.every.
interval.every(step) · Исходный код
Возвращает отфильтрованный вид этого интервала, представляющий каждую step-ю дату. Значение step зависит от родительского интервала этого интервала, как определено функцией поля. Например, d3.timeMinute.every(15) возвращает интервал, представляющий каждые пятнадцать минут, начиная с часа: :00, :15, :30, :45 и т. д. Обратите внимание, что для некоторых интервалов возвращаемые даты могут не быть равномерно распределены; родительским интервалом d3.timeDay является d3.timeMonth, и поэтому номер интервала сбрасывается в начале каждого месяца. Если step не допустим, возвращает null. Если step равен единице, возвращает этот интервал.
Этот метод может использоваться совместно с interval.range для обеспечения согласованности двух перекрывающихся диапазонов. Например, этот диапазон содержит нечётные дни:
d3.timeDay.every(2).range(new Date(2015, 0, 1), new Date(2015, 0, 7)) // [2015-01-01T00:00, 2015-01-03T00:00, 2015-01-05T00:00]
Как и этот:
d3.timeDay.every(2).range(new Date(2015, 0, 2), new Date(2015, 0, 8)) // [2015-01-03T00:00, 2015-01-05T00:00, 2015-01-07T00:00]
Возвращаемый отфильтрованный интервал не поддерживает interval.count. См. также interval.filter.
interval.count(start, end) · Исходный код
Возвращает количество граничных дат интервала после start (исключительно) и до или равных end (включительно). Обратите внимание, что это поведение немного отличается от interval.range, потому что его цель — вернуть нулевой номер указанной даты end относительно указанной даты start. Например, для вычисления текущего нулевого номера дня года:
d3.timeDay.count(d3.timeYear(now), now) // 177
Аналогично, для вычисления текущего нулевого номера недели года для недель, которые начинаются с воскресенья:
d3.timeSunday.count(d3.timeYear(now), now) // 25
d3.timeInterval(floor, offset[, count[, field]]) · Источник
Создаёт новый пользовательский интервал, заданный указанными функциями floor и offset, а также необязательной функцией count.
Функция floor принимает одну дату в качестве аргумента и округляет её вниз до ближайшей границы интервала.
Функция offset принимает дату и целое число шага в качестве аргументов и перемещает указанную дату на указанное число границ; шаг может быть положительным, отрицательным или нулевым.
Необязательная функция count принимает начальную и конечную даты, уже округленные до текущей границы интервала, и возвращает число границ между начальной (исключающей) и конечной (включающей) датами. Если функция count не указана, возвращаемый интервал не предоставляет методы interval.count или interval.every. Примечание: из-за внутренней оптимизации указанная функция count не должна вызывать interval.count для других временных интервалов.
Необязательная функция field принимает дату, уже округленную до текущей границы интервала, и возвращает значение поля указанной даты, соответствующее числу границ между этой датой (исключающей) и последней предыдущей границей родительского интервала. Например, для интервала d3.timeDay она возвращает количество дней с начала месяца. Если функция field не указана, по умолчанию она считает количество границ интервала с начала эпохи Unix (1 января 1970 года UTC). Функция field определяет поведение метода interval.every.
Интервалы
Предоставлены следующие интервалы:
d3.timeMillisecond · Источник
d3.utcMillisecond
Миллисекунды; наименьший доступный временной интервал.
d3.timeSecond · Источник
d3.utcSecond
Секунды (например, 01:23:45.0000 AM); 1000 миллисекунд.
d3.timeMinute · Источник
d3.utcMinute · Источник
Минуты (например, 01:02:00 AM); 60 секунд. Обратите внимание, что ECMAScript игнорирует високосные секунды.
d3.timeHour · Источник
d3.utcHour · Источник
Часы (например, 01:00 AM); 60 минут. Обратите внимание, что продвижение времени на один час по местному времени может вернуть тот же час или пропустить час из-за перехода на летнее время.
d3.timeDay · Источник
d3.utcDay · Источник
d3.unixDay · Источник
Дни (например, 7 февраля 2012 года в 12:00); обычно 24 часа. Дни по местному времени могут варьироваться от 23 до 25 часов из-за перехода на летнее время. d3.unixDay похож на d3.utcDay, за исключением того, что он считает дни с начала эпохи Unix (1 января 1970 года), так что interval.every возвращает равномерно распределённые даты, а не изменяющиеся в зависимости от числа дня месяца.
d3.timeWeek · Источник
d3.utcWeek · Источник
Псевдоним для d3.timeSunday; 7 дней и обычно 168 часов. Недели по местному времени могут варьироваться от 167 до 169 часов из-за перехода на летнее время.
d3.timeSunday · Источник
d3.utcSunday · Источник
Недели, начинающиеся с воскресенья (например, 5 февраля 2012 года в 12:00 AM).
d3.timeMonday · Источник
d3.utcMonday · Источник
Недели, начинающиеся с понедельника (например, 6 февраля 2012 года в 12:00 AM).
d3.timeTuesday · Источник
d3.utcTuesday · Источник
Недели, начинающиеся со вторника (например, 7 февраля 2012 года в 12:00 AM).
d3.timeWednesday · Источник
d3.utcWednesday · Источник
Недели, основанные на средах (например, 8 февраля 2012 года в 00:00).
d3.timeThursday · Исходный код
d3.utcThursday · Исходный код
Недели, основанные на четвергах (например, 9 февраля 2012 года в 00:00).
d3.timeFriday · Исходный код
d3.utcFriday · Исходный код
Недели, основанные на пятницах (например, 10 февраля 2012 года в 00:00).
d3.timeSaturday · Исходный код
d3.utcSaturday · Исходный код
Недели, основанные на субботах (например, 11 февраля 2012 года в 00:00).
d3.timeMonth · Исходный код
d3.utcMonth · Исходный код
Месяцы (например, 1 февраля 2012 года в 00:00); диапазон от 28 до 31 дня.
d3.timeYear · Исходный код
d3.utcYear · Исходный код
Годы (например, 1 января 2012 года в 00:00); диапазон от 365 до 366 дней.
Диапазоны
Для удобства также предоставляются псевдонимы для interval.range в виде множественного числа соответствующего интервала.
d3.timeMilliseconds(start, stop[, step]) · Исходный код
d3.utcMilliseconds(start, stop[, step])
Псевдонимы для d3.timeMillisecond.range и d3.utcMillisecond.range.
d3.timeSeconds(start, stop[, step]) · Исходный код
d3.utcSeconds(start, stop[, step])
Псевдонимы для d3.timeSecond.range и d3.utcSecond.range.
d3.timeMinutes(start, stop[, step]) · Исходный код
d3.utcMinutes(start, stop[, step]) · Исходный код
Псевдонимы для d3.timeMinute.range и d3.utcMinute.range.
d3.timeHours(start, stop[, step]) · Исходный код
d3.utcHours(start, stop[, step]) · Исходный код
Псевдонимы для d3.timeHour.range и d3.utcHour.range.
d3.timeDays(start, stop[, step]) · Исходный код
d3.utcDays(start, stop[, step]) · Исходный код
d3.unixDays(start, stop[, step]) · Исходный код
Псевдонимы для d3.timeDay.range, d3.utcDay.range и d3.unixDay.range.
d3.timeWeeks(start, stop[, step])
d3.utcWeeks(start, stop[, step])
Псевдонимы для d3.timeWeek.range и d3.utcWeek.range.
d3.timeSundays(start, stop[, step]) · Исходный код
d3.utcSundays(start, stop[, step]) · Исходный код
Псевдонимы для d3.timeSunday.range и d3.utcSunday.range.
d3.timeMondays(start, stop[, step]) · Source
d3.utcMondays(start, stop[, step]) · Source
Псевдонимы для d3.timeMonday.range и d3.utcMonday.range.
d3.timeTuesdays(start, stop[, step]) · Source
d3.utcTuesdays(start, stop[, step]) · Source
Псевдонимы для d3.timeTuesday.range и d3.utcTuesday.range.
d3.timeWednesdays(start, stop[, step]) · Source
d3.utcWednesdays(start, stop[, step]) · Source
Псевдонимы для d3.timeWednesday.range и d3.utcWednesday.range.
d3.timeThursdays(start, stop[, step]) · Source
d3.utcThursdays(start, stop[, step]) · Source
Псевдонимы для d3.timeThursday.range и d3.utcThursday.range.
d3.timeFridays(start, stop[, step]) · Source
d3.utcFridays(start, stop[, step]) · Source
Псевдонимы для d3.timeFriday.range и d3.utcFriday.range.
d3.timeSaturdays(start, stop[, step]) · Source
d3.utcSaturdays(start, stop[, step]) · Source
Псевдонимы для d3.timeSaturday.range и d3.utcSaturday.range.
d3.timeMonths(start, stop[, step]) · Source
d3.utcMonths(start, stop[, step]) · Source
Псевдонимы для d3.timeMonth.range и d3.utcMonth.range.
d3.timeYears(start, stop[, step]) · Source
d3.utcYears(start, stop[, step]) · Source
Псевдонимы для d3.timeYear.range и d3.utcYear.range.
Штрихи
d3.timeTicks(start, stop, count) · Source
Эквивалентно d3.utcTicks, но в локальном времени.
d3.timeTickInterval(start, stop, count) · Source
Возвращает временной интервал, который будет использоваться d3.timeTicks с теми же аргументами.
d3.utcTicks(start, stop, count) · Source
Возвращает массив примерно count дат через равные интервалы между start и stop (включительно). Если stop предшествует start, даты возвращаются в обратном хронологическом порядке; в противном случае даты возвращаются в хронологическом порядке. Рассматриваются следующие интервалы времени UTC:
- 1 секунда
- 5 секунд
- 15 секунд
- 30 секунд
- 1 минута
- 5 минут
- 15 минут
- 30 минут
- 1 час
- 3 часа
- 6 часов
- 12 часов
- 1 день
- 2 дня
- 1 неделя
- 1 месяц
- 3 месяца
- 1 год
Также рассматриваются кратные миллисекундам (для небольших диапазонов) и годам (для больших диапазонов), следуя правилам d3.ticks. Используется интервал, дающий количество дат, наиболее близкое к count. Например:
start = new Date(Date.UTC(1970, 2, 1)) stop = new Date(Date.UTC(1996, 2, 19)) count = 4 d3.utcTicks(start, stop, count) // [1975-01-01, 1980-01-01, 1985-01-01, 1990-01-01, 1995-01-01]
Если count является временным интервалом, эта функция ведет себя аналогично interval.range, за исключением того, что и start, и stop включительно, и она может вернуть даты в обратном хронологическом порядке, если stop предшествует start.
d3.utcTickInterval(start, stop, count) · Source
Возвращает временной интервал, который будет использоваться функцией d3.utcTicks с теми же аргументами. Если нет соответствующего интервала, например, когда start или stop неверны, возвращает null.
© 2010–2023 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-time