Подтвердить что ты не робот

Существует ли стандарт для инклюзивных/эксклюзивных концов временных интервалов?

Мне интересно, существует ли стандартное или "нормальное" средство интерпретации конечных точек данных интервала времени в отношении инклюзивности/исключительности значения, определяющего конечную точку. Обратите внимание, что я спрашиваю, что такое стандартное (или наиболее распространенное) соглашение (если оно есть), а не для диссертации по вашим личным предпочтениям. Если вы действительно хотите предоставить диссертацию, приложите ее к ссылке на опубликованный стандарт или стандартный текст по этому вопросу. Открытые стандарты (которые мне не нужно платить за чтение) являются очень предпочтительными, если они не имеют фундаментальных недостатков:).

Конечно, существует 4 возможности для временного интервала от A до B:

  • (A, B). Оба конца являются эксклюзивными.
  • [A, B] - Оба конца включены.
  • [A, B) - запуск включен, а end - эксклюзивным
  • (A, B) - Исходный запуск и завершение включено

Каждый из них имеет разные характеристики (как я вижу, не стесняйтесь указать больше)

В соглашении [A, B] было бы кажущееся неудобным свойство, что B содержится с инволюцией [A, B], а также [B, C]. Это особенно неудобно, если B предназначен для представления границы полуночи, и вы пытаетесь определить, в какой день он, например, попадает. Кроме того, это означает, что продолжительность интервала немного раздражает для вычисления, поскольку [A, B], где A = B должно иметь длину 1 и, следовательно, продолжительность [A, B] равна (B - A) + 1

Аналогично, соглашение (A, B) было бы затруднено тем, что B не входит ни в ни (A, B), ни (B, C)... продолжая аналогию с дневными границами, полночь не будет частью ни дня. Это также логически неудобно, потому что [A, B], где A = B - нечувствительный интервал с длительностью меньше нуля, , но изменение A и B не делает его допустимым интервалом.

Поэтому я думаю, что хочу либо [A, B], либо (A, B], и я не могу понять, как решить между ними.

Итак, если у кого-то есть ссылка на документ стандартов, ссылка на стандартный текст или аналогичный, который разъясняет соглашение, которое было бы здорово. В качестве альтернативы, если вы можете связать различные документы стандартов и/или ссылки, которые более или менее полностью не согласны, тогда я могу просто выбрать тот, который, как представляется, обладает достаточными полномочиями для CMA и будет с ним выполнен:).

Наконец, я буду работать на Java, поэтому я особенно восприимчив к ответам, которые хорошо работают на Java.

4b9b3361

Ответ 1

В общем случае [A, B) имеет много общего для него, и я не вижу причин, почему то же самое было бы неверно для временных интервалов.

Djikstra написал хорошую статью об этом Почему нумерация должна начинаться с нуля, которая, несмотря на название, в основном касается именно этого.

Краткое описание преимуществ:

  • end - start равно количеству элементов в списке
  • верхняя граница предыдущего интервала является нижней границей следующего
  • позволяет индексировать интервал, начинающийся с 0 с неподписанными номерами [1]

Лично второй момент чрезвычайно полезен для множества проблем; рассмотрим довольно стандартную рекурсивную функцию (в псевдопитоне):

def foo(start, end):
    if end - start == 1:
        # base case
    else:
        middle = start + (end - start) / 2
        foo(start, middle)
        foo(middle, end)

Написание же с инклюзивной верхней границей приводит к множеству ошибок, подверженных ошибкам.

[1] Преимущество по сравнению с (A, B] - интервал, начинающийся с 0, больше, чем интервал, заканчивающийся на MAX_VAL. Обратите внимание, что это также относится к одной дополнительной задаче: использование двух инклюзивных границ означает, что мы можем обозначить последовательность, длина которой не может быть выражена с одинаковым размером.

Ответ 2

Я расскажу, что я написал для нашей команды как ответ, используя ссылку Voo, до тех пор, пока Voo не добавит ответа, тогда я дам ему кредит. Вот что я решил для нашего случая:

Временные интервалы в наших приложениях будут представлены в виде пары мгновенное время с условием, что время начала включительно, а время окончания - исключительно. Это соглашение математически удобно в том смысле, что разность границ равный длине интервала, а также численно в соответствии с тем, как массивы и списки индексируются в java программы (см. http://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF). практическим результатом этого является тот интервал 2012-03-17T00: 00: 00.000Z - 2012-03-18T00: 00: 00.000Z обозначает весь день Святого Патрика, и каждая дата, начинающаяся с 2012-03-17, будет определена как включен в день Святого Патрика, но 2012-03-18T00: 00: 00.000Z не будет включен, и День Святого Патрика будет включать ровно 24 * 60 * 60 * 1000 миллисекунды.

Ответ 3

Я не могу сказать наверняка, но я сомневаюсь, что существует стандарт или соглашение. Независимо от того, включите ли вы начало или конец, зависит от вашего варианта использования, поэтому подумайте, важны ли они для вас. Если решение произвольно, выберите один, обратите внимание, что выбор произвольный и двигаться дальше.

Что касается поддержки Java, библиотека времени Joda реализует Interval, которые включают время начала, но не время окончания

Ответ 4

Несмотря на то, что эта тема больше посвящена Java, я подумал, что было бы интересно увидеть другие принятые соглашения, особенно учитывая, что библиотека pandas Python в настоящее время вездесущ для анализа данных и того факта, что эта страница StackOverflow является одним из лучших результатов поиска при поиске соглашений о включении/исключительности временных диапазонов.

Цитата эта страница:

Даты начала и окончания строго включены. Таким образом, он не будет генерировать какие-либо даты за пределами этих дат, если они указаны.

Кроме того, он не только генерирует диапазоны дат. Соглашение также принимается при попытке индексирования в данные временных рядов. Здесь простой тест на кадры данных с DatetimeIndex

>>> import pandas as pd
>>> pd.__version__
'0.20.2'
>>> df = pd.DataFrame(list(range(20)))
>>> df.index = pd.date_range(start="2017-07-01", periods=20)
>>> df["2017-07-01":"2017-07-05"]
            0
2017-07-01  0
2017-07-02  1
2017-07-03  2
2017-07-04  3
2017-07-05  4

Ответ 5

java.time и Half-Open

Классы java.time, которые вытесняют неприятные классы времени и времени, а также проект Joda-Time определяют диапазон -time, используя метод Half-Open [], где начало включено, в то время как окончание является эксклюзивным.

Для даты-времени с дробной секундой это устраняет проблему попыток захвата последнего момента. Бесконечно делимая последняя секунда должна быть разрешена, но различные системы используют различные гранулярности, такие как миллисекунды, микросекунды, наносекунды или что-то еще. Например, с Half-Open, например, день начинается в первый момент дня и заканчивается, но не включает, первый момент следующего дня. Проблема решена, нет необходимости бороться с последним моментом дня и его дробной секундой.

Я пришел к пониманию преимуществ использования этого подхода последовательно на протяжении всего моего кода обработки даты. Например, неделя, начинающаяся в понедельник, заканчивается, но не включает следующий понедельник. Месяц начинается с 1-го и заканчивается, но не включает, первый из следующего месяца, тем самым игнорируя вызов определения номера последнего дня месяца, включая февраль 28/29.

Еще одно преимущество последовательного использования Half-Open [) - это облегчение когнитивной нагрузки каждый раз, когда я должен обнаруживать и расшифровывать и проверять подход кодов по времени. В моем собственном программировании я просто заглядываю за упоминанием Half-Open в комментарии сверху, и я сразу же знаю, как читать этот код.

Результат последовательного использования Half-Open уменьшает вероятность ошибок в моем коде, так как мой стиль мышления и письма одинаковый, и у вас нет шансов запутаться в инклюзивном эксклюзиве.

Кстати, обратите внимание, что Half-Open [) означает избегать соединения SQL BETWEEN, поскольку он всегда полностью закрыт [].

Что касается бизнес-мышления клиентов, которых я обслуживаю, в соответствующих случаях я пытаюсь убедить их постоянно использовать Half-Open. Я видел много ситуаций, когда различные деловые люди делали неправильные предположения о периодах времени, охватываемых отчетами. Последовательное использование Half-Open позволяет избежать этих несчастливых двусмысленностей. Но если клиент настаивает, я отмечаю это в своем коде и настраиваю входы/выходы, чтобы использовать Half-Open в моей собственной логике. Например, моя логика использует неделю с понедельника по понедельник, но в отчете вычесть день, чтобы показать воскресенье.

Для еще большего количества классов, представляющих промежутки времени с помощью метода Half-Open [], см. проект ThreeTen-Extras для класса Interval (пара объектов Instant) и класс LocalDateRange (пара объектов LocalDate).


О java.time

Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь режим обслуживания, советуем перейти к классам java.time.

Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.

Где получить классы java.time?

  • Java SE 8, Java SE 9, а затем
    • Встроенный.
    • Часть стандартного Java API с объединенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональных возможностей java.time обратно переносится на Java 6 и 7 в ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и больше.

Ответ 6

Я только что прошел через этот то же самый процесс мышления, и я думаю, что очень важно, что это стандартизировано каким-то образом или, по крайней мере, разъяснено с помощью этих типов сообщений Q & A!

В нашем случае рассматриваемые диапазоны дат используются как входы и выходы в/из микросервиса; один, который, по крайней мере, в краткосрочной перспективе, будет вызван существующим монолитным приложением (это проект монолитного разложения). Поэтому я считаю, что вышеприведенный комментарий, касающийся решения, обусловленного требованиями бизнеса, в нашем случае менее уместен (поскольку прямые "пользователи" программного обеспечения, которое мы строим, действительно являются техническими людьми). Если бы мы обрабатывали входные данные с помощью выбора даты, это может быть другая история!

Моя рекомендация заключалась в том, что все начальные даты являются инклюзивными, и все конечные даты являются исключительными - так [A, B] в ваших обозначениях. Это произошло по следующим причинам:

  • Ранее мы согласились с тем, что любые входящие даты, содержащие временные части, будут отклонены (даже если значение JSON было "2018-01-01T00: 00: 00" ) и что мы будем выводить все даты без раз. Поэтому, если конечная дата является исключительной, как только строка десериализуется в объект .NET DateTime, это будет выходной.

  • Мне нравится идея, что диапазоны дат (которые в нашем случае всегда должны давать целые дни) всегда можно вычислить, просто делая dateRange = (endDateExcl - startDateIncl).TotalDays. Не нужно добавлять 1 везде!

  • Большая часть проверки бизнеса, выполняемая службой, проверяет, что несколько диапазонов данных сливаются друг с другом без пробелов. Это легко проверить при использовании [A, B], потому что каждый B должен соответствовать предыдущему A. Если мы пойдем с [A, B], то мы (разработчики, тестеры, инженеры поддержки) часто спрашивали себя: "Сколько дней снова в марте?" (например, [2018-03-01,2018-03-30], [2018-04-01,2018-04-30]) или "Есть ли в 2016 году високосный день?" (например, [2016-02-01,2016-02-28], [2016-03-01,2016-03-30]).

Просто добавлю, я настоятельно рекомендую всем, независимо от решения, явно суффикс всех имен атрибутов, переменных, методов или иным образом с помощью "Incl" или "Excl", чтобы всем было ясно, что не нужно искать документацию!

Мы также рекомендовали, чтобы все даты появлялись в формате ISO и что все, что было с "Z" на конце, также должно быть отклонено (поскольку понимание заключается в том, что мы работаем целыми днями, и мы не хотим дату, подлежащую десериализации в объект DateTime с часовым часом (или 23!) из-за летнего времени).

Сноска, я бы, вероятно, разместил это как комментарий к Voo ответу, но я просто (с опозданием!) присоединился к SO, и мне нужно заработать свое удовольствие, прежде чем я смогу это сделать!; -)

Счастливые знакомства x