Для протокола: заголовок я позаимствовал у Цицерона, в Oratio in Catilinam Prima in Senatu Habita.
В реальной жизни мы часто имеем дело с временны?ми интервалами. Свиданки с зубным врачом, бронирование гостиничных номеров, даже ежедневный обеденный перерыв: планирование всего этого — задача подгонки временно?го интервала в ряд других временны?х интервалов.
Допустим, нам пора навестить стоматолога. Я знаю, что мне нужен 1 час для ежегодной плановой проверки. Я могу посетить врача во время обеда или после работы. У доктора есть и другие пациенты. На диаграмме ниже мои рабочие часы показаны фиолетовым цветом, докторские — красным, нерабочие — серым, а счастливо найденный слот, когда мы оба свободны, — зеленым.
Беглого взгляда на эту диаграмму достаточно, чтобы определить время назначенной встречи. Завтра, в обеденное время. Легко, да?
К сожалению, ни один из известных мне языков программирования не предоставляет возможности определить это программно. Последние несколько лет я состою в тесных отношениях с эликсиром, поэтому пришлось написать библиотеку, решающую именно эту проблему.
Итак, встречайте Tempus
!
Детали реализации
Сущность, вокруг которой построена вся библиотека — Slot
. Он представляет временной интервал самым естественным и простым способом: это структура, с полями from
и to
, оба типа DateTime
. Набор слотов хранится в структуре Slots
, под капотом реализованной как AVLTree
. Этот выбор был сделан для того, чтобы сохранить базовый список слотов согласованным (упорядоченным и не перекрывающимся) с наименьшими затратами при оптимизации доступа по чтению и записи. Обычно список слотов заполняется при инициализации и потом используется для проверки, поиска свободных интервалов, и тому подобного.
Функция Slots.add/2
добавит в список слотов — новый, объединяя слоты по мере необходимости. Это позволяет просто вставлять новые слоты в конструкцию, не беспокоясь о порядке и перекрытии. Также предусмотрена вспомогательная функция Slots.merge/2
для объединения двух наборов слотов. Последнее особенно удобно, когда нужно, например, найти пустой слот в обеих сериях, как в примере с выбором времени посещения дантиста выше.
Можно также проверить любое время на предмет занятости при помощи функций их модуля Slot
: покрывает ли слот заданное время (или другой слот), являются ли слоты непересекающимися, или нет и т. д.
Модуль Tempus
Основной модуль экспортирует функции для работы со слотами, как с прерывистой временной шкалой. Можно добавить любой произвольный интервал времени к началу координат, принимая во внимание слоты; проверить, свободен ли этот интервал, или уже занят слотами, получить следующий свободный или следующий занятый слот, инвертировать временную шкалу, и многое другое.
Вот незамысловатый пример из тестов:
slots =
[
Tempus.Slot.wrap(~D|2020-08-07|), # whole day
%Tempus.Slot{
from: ~U|2020-08-08 01:01:00Z|, # one minute
to: ~U|2020-08-08 01:02:00Z|
},
%Tempus.Slot{
from: ~U|2020-08-08 01:03:00Z|, # one minute
to: ~U|2020-08-08 01:04:00Z|
}
]
|> Enum.into(%Tempus.Slots{})
Если добавить 0
секунд ко времени, уже занятому слотом, вернется первое доступное время после занятого промежутка.
Tempus.add(slots, ~U|2020-08-08 01:01:30Z|, 0, :second)
#? ~U[2020-08-08 01:02:00Z]
Добавив 70 секунд ко времени, на пять секунд предшествующему первому занятому слоту — ~U[2020-08-08 01:00:55Z]
— вернется экземпляр DateTime
через пять секунд после второго занятого слота (5sec + занято + 60sec + занято + 5sec
):
Tempus.add(slots, ~U|2020-08-08 01:00:55Z|, 70, :second)
#? ~U[2020-08-08 01:04:05Z]
И так далее. Разумеется, можно добавлять и отрицательные значения.
Слияние наборов слотов
Slots.merge/2
понимает Stream
в качестве второго аргумента. На данный момент библиотека не поддерживает слияние и использование двух потоков слотов, но вливание потока в существующие временные интервалы возможно. Это может быть полезно, когда у нас есть короткий список, скажем, праздников, и мы хотим объединить его с повторяющимися слотами, например с выходными.
Все функции, возвращающие Slots
и / или Slot
— гарантированно отдают допустимые объекты (нормализованные, упорядоченные и объединенные по мере необходимости).
Что еще?
Текущая реализация покрывает только наши внутренние потребности, поэтому я был бы рад услышать о том, чего не хватает этой библиотеке и что следует в нее добавить.
Удачных временных интервалов!
sshikov
А что, TZ у вас одна на все события, во всех последовательностях?
И еще — зачастую события и интервалы бывают повторяющимися, правда, я не вижу особо, что это может поменять, потому что описанные задачи обычно решаются на ограниченном интервале, от силы год, и можно повторения за год раскрыть в отдельные события/интервалы.
Ну и еще у того, что вы называете слотами, бывают свойства — произвольные. Если описать это в ваших же терминах, то у доктора могут быть не просто пациенты, а известное число пациентов, поэтому свойство интервала у доктора — это именно число. И если оно скажем 2 и менее — вас примут, а если 3 — то нет. В вашем варианте занятость доктора — это просто наличие слота на временной шкале.
Совершенно не факт, что все это стоит добавлять, но посмотреть можно на любую библиотеку с поддержкой формата iCal например, и прикинуть, что они умеют. Да и импорт-экспорт iCal наверное не помешает.
chapuza Автор
TZ это атрибут инстанса
DateTime
, очевидно. Вот сниппет из продакшн-кода, отвечающий за стрим слотов, когда fx-markets закрыты, с корректной обработкой DST, между прочим:Вот выше пример, там повторяющиеся события.
Stream
же.Да, это, кажется, очень разумное рац. предложение, внедрю, когда выдастся свободное время, спасибо!
Я решал практическую задачу, а не писал сферическую библиотеку в вакууме. Но, да, посмотрю, спасибо за наводку.
Наверное, да, посмотрю тоже, спасибо.
sshikov
Сферическую это не про iCal — просто это же в принципе обычный типовой календарь, а их часто рисуют где-то в аутлуке. Ну и и экспорт самый удобный в iCal, поэтому его поддержка это просто тупо удобно. Хотя сам формат — на мой взгляд типично дурацкий.
Ну и на библиотеки я и имел в виду посмотреть — но не обязательно реализовывать все то, что они умеют.
>Вот выше пример, там повторяющиеся события. Stream же.
Понял. Просто без знания синтаксиса это было не очевидно.
Что до TZ — то тут скорее вопрос в том, где вы берете их описание (и как обновляется их база). А уж если даты в прошлом (особенно далеко в прошлом) — то и подавно не очевидно, где брать описание зон.
Вообще, решить для произвольной даты, America/New_York и -5 — это одно и тоже, или же нет, не всегда тривиально. А уж если интервал захватывает какой-то переход на летнее время — то и подавно (потому что на концах интервала время может плавать на час туда-сюда, и по-идее, похожий на вид интервал в разных зонах может оказаться разной длины).
AxeFizik
sshikov
Если бы я мог не работать… :) к сожалению, у нас в некоторых базах бывают даже даты 1 января 0 года (до нашей эры к счастью не встречались). И проблем с ними, прямо скажем, дофига — потому что когда в процессе завязаны скажем БД Оракл (разных версий), MS SQL (тоже разные), Oracle Golden Gate (или OGG BDA). Java, Spark, Hive, Impala, и т.п., и добиться чтобы все это работало согласованно, да еще и с единой базой зон — это практически недостижимо.
chapuza Автор
В Unicode Consortium’s Common Locale Data Repository, а где еще? Обновляется каждый день.
Это на себя берет
DateTime
из поставки эликсира с правильным календарем (Cldr
). Туда можно хоть еврейский календарь засунуть, и все будет работать.Внутри я добавляю микросекунды, так что тут все чисто.
sshikov
>Внутри я добавляю микросекунды, так что тут все чисто.
Я про другое — интервал в одной зоне может в другой просто не существовать, потому что перевод на летнее/зимнее время иногда выглядит так: у нас было 0 часов вчера, а потом сразу бац — и час ночи сегодня. Все что между нулем и часом — в этой зоне не существует. При этом, насколько я понимаю, тут могут вылезать разные странные случаи при любой обработке такого кейса.
>Это на себя берет DateTime из поставки эликсира с правильным календарем (Cldr).
Тут не очень понятно, что значит «правильный», если в разных календарях 00:05 либо является валидным временем, а в другом календаре это же время не существует? Оба календаря по своему правильные — но друг с другом они конфликтуют.
Не факт что это существенно для любой системы, но у нас вот вылезает время от времени. Скорее всего, если вы планируете визит к стоматологу, вы на такое никогда не наступите. Но если стоматолог в другой зоне свой календарь ведет — то могут быть разные странности.
chapuza Автор
Я не понимаю, где тут возможна проблема. Добавить слот с таким временем не позволит
Slots.add/2
.Slot.valid?/1
вернетfalse
, потому что время не валидно.Tempus.add/4
, как я показал выше, отработает корректно. Никаких конфликтов календарей нет, они диффеоморфны. Функция преобразования одного в другой — задана реализацией календаря.Я выше же опубликовал пример вот ровно для этого случая. Fx-рынки открываются в понедельник в 9:00 в Сиднее и закрываются в 22:00 в пятницу в Нью-Йорке. По местному времени, да. DST в этих городах вообще не согласовано никак.
И мой код прекрасно с этим справляется; это была почти ключевая задача этой библиотеки (помимо просто планирования переговорок): стрим добавляет по 86400 секунд к понедельнику, 8 утра по Сиднею и пятнице, 10 вечера, по Нью-Йорку. А потом переводит получившиеся значения в UTC для дальнейших операций. Разница между
from
иto
плавает в пределах двух часов, в зависимости от времени года.Надо будет этот момент поподробнее разжевать в документации, а то мои коллеги тоже не поверили, что все так радужно :)
sshikov
>Я не понимаю, где тут возможна проблема.
>Добавить слот с таким временем не позволит Slots.add/2. Slot.valid?/1 вернет false, потому что время не валидно.
Что значит не валидно, когда оно валидно (в другом календаре)? Ну смотрите, это по Москве, какого-то марта непонятного года, когда был переход на летнее время не было интервала времени с 0 до часу ночи. Но в другом календаре это время вполне валидно. Ну или в наших терминах, как у меня в проекте — Оракл DB считает, что эти вот 05 минут первого вполне правильное время (потому что у него оно например в UTC), а Java на нашей стороне — уже нет (потому что мы пытаемся преобразовать его в MSK, например), и корректирует его на 01:00.
Я не говорю что с этим ничего сделать нельзя, просто поведение в таком случае вполне может быть неожиданным с точки зрения юзера где-то в UI. Я даже не исключаю, что к вашей библиотеке это вообще отношения не имеет, но проблема такая есть, и вполне реальная.
chapuza Автор
Календарь — атрибут инстанса
DateTime
. Время без календаря называетсяNaiveDateTime
и в принципе не имеет смысла в расчетах с вовлечением разных временны?х зон.Это шутка? Совершенно очевидно, что любое время в UTC можно конвертировать в любую другую таймзону, включая MSK. Это напрямую следует из непрерывности временной координаты пространства-времени. То, что ваш код не справляется с тем, чтобы сделать это правильно — не вина времени, Оракла, или Java.
Не может. Пользователю нужно все показывать в какой-то одной таймзоне. Обычно это либо его локальное время, либо локальное время сервера, либо UTC. Вытащите хоть стопятьсот времен из разных источников (обязательное условие: они должны все идти в комплекте с таймзоной, иначе да, проблемы), сконвертируйте во время пользователя, и обпоказывайтесь. Никаких сюрпризов там быть не может.
sshikov
>Это шутка? Совершенно очевидно, что любое время в UTC можно конвертировать в любую другую таймзону, включая MSK. Это напрямую следует из непрерывности временной координаты пространства-времени.
Нет, это совершенно не шутка. Нет никакой непрерывности. Переход на летнее время осуществляется как я написал ранее — после 0 часов следует сразу 1 час ночи. Скажем так — в некоторых системах это так работает. Если вы такого не видели — не значит что так не бывает.
chapuza Автор
Я на DST собаку съел, и видел буквально всё. Я знаю, как осуществляется переход на летнее время. Повторяю еще раз: время непрерывно (это физический факт, его нелепо оспаривать). То, что какие-то соглашения между какими-то людьми изменили систему координат и способ записи — на само время не влияет ровным счетом никак.
0:30 MSK в базе оказаться не может, если код писал не криворукий дебил. Время в UTC (и любой другой зоне), переведенное в MSK, внезапно оказаться 0:30 MSK не может. Такому времени неоткуда взяться.
Если кто-то хранит время без зоны, а потом цепляет к нему MSK и удивляется — этого человека имеет смысл уволить вчерашним днем.
Как я показал в примере выше, мой код с входными данными
23:30 MSK + minutes(31)
в этот конкретный день — вернет1:01 MSK
. Если вы продолжаете считать, что там есть какие-то сложности — я предлагаю еще раз подумать, найти все места, где время хранится без таймзон, и переписать все правильно.Еще раз, для закрепления:
sshikov
>0:30 MSK в базе оказаться не может, если код писал не криворукий дебил. Время в UTC (и любой другой зоне), переведенное в MSK, внезапно оказаться 0:30 MSK не может. Такому времени неоткуда взяться.
Вы не поняли. Оно не оказывается 0:30. Оно преобразуется в ближайшее валидное. Именно это и является для пользователей неприятным сюрпризом.
chapuza Автор
Если честно, я и правда уже мало, что понимаю.
Для пользователя оказывается сюрпризом, что ему показывают правильное время вместо несуществующего?
sshikov
> Условно 20:59 utc это 23:59 msk, 21:00 utc это 0:00 msk, а 21:01 utc это 01:01 msk.
Ну вот смотрите. alexzeed ниже привел пример, как это должно выглядеть с его точки зрения. Я согласен, что это выглядит логично. Но проблема в том, что в реальности это бывает не 01:01, а ближайшее валидное время, то есть скажем 01:00. И минуты при этом пропадают. И обратно в UTC это уже не сконвертировать без потерь.
Он все-таки видимо не совсем так делает, хотя близко к этому. Но главное эффект такой как я выше описал. А уволить при этом придется слишком многих, потому что у нас например, эта проблема всплывает во взаимодействии Oracle DB, Oracle Golden Gate, Java, Hive.
chapuza Автор
Да вы издеваетесь, что ли?
Куда пропадают минуты? С какого, простите, хрена, они куда-то пропадают?
Я не имел дел с ораклом и джавой уже почти 20 лет, но и тогда, 20 лет назад, ни один их этих монстров не стал бы отсекать минуты во времени без прямого на то указания.
Ваша проблема связана с некомпетентностью разработчиков, работающих с временами в вашей этой связке. В мире, где люди умеют обращаться с таймзонами, а не просто пишут код на авось, такой проблемы не существует.
Ее нет, так же, как нет проблемы деления на ноль. На ноль не делят, а если делят, то получают фигню — и обвинять в этом ноль — по меньшей мере странно. И alexzeed все изложил предельно корректно и верно.
sshikov
>Куда пропадают минуты? С какого, простите, хрена, они куда-то пропадают?
Объясняю на пальцах — если Java парсеру из строк в даты подсунуть вот такую невалидную дату (т.е. 00:05, с таймзоной, само собой) — то она преобразуется в ближайшую валидную. Всех деталей я уже не помню, но в целом поведение было именно такое. И я вас уверяю, оно документированное — т.е. это такая фича. Почему так? ХЗ, я могу только предположить. Ведь java дата — это по сути просто число миллисекунд от начала времен, и с переходом на летнее время в таком представлении всегда проблемы будут, потому что берете вы число миллисекунд в 00:00, прибавляете скажем 30 секунд — и получить вы должны не 00:30, а час ночи.
Ну, с большой вероятностью это разработчики Golden Gate — потому что а) невалидная дата в виде строки приходит именно от них б) у них были и другие баги с временными зонами. И я бы охотно последовал вашему совету их уволить — но увы, ни одной вменяемой альтернативы OGG в природе не существует, поэтому с их багами приходится мириться.
chapuza Автор
Я человек неленивый. Стандартный парсер в более-менее нормальном языке программирования таким детским недугом страдать не может. Он и не страдает, что характерно.
https://repl.it/repls/IntelligentSpottedDowngrade
Ввод:
Вывод:
sshikov
А что, 8 марта 2020 в этой зоне переход на летнее время?
То что вы показываете — не единственный «стандартный» парсер, потому что у нас Java 8, и там есть и другие. И не единственный возможный режим парсинга. Ну и главное — у вас время на выходе уменьшается, т.е. из 02:30 получается 01:30, а это не наш случай. У нас переход в обратную сторону, когда 00:00 становится 01:00.
>Я не имел дел с ораклом и джавой уже почти 20 лет
А я с ними каждый день имею дело. И у меня примерно 100 или чуть больше разных ораклов, и штук 20 MS SQL. Я вполне понимаю ваше возмущение на тему «ну не может же там быть такой фигни», но уж поверьте — может. Вот прямо так сразу все детали не вспомню, но если любопытно — завтра постараюсь найти.
chapuza Автор
Я опроверг ложный тезис о том, что время округляется. Вы бы хоть немного за ходом дискуссии послеживали, а?
Между двумя и тремя часами ночи в этот день в этой таймзоне происходит перевод стрелок вперед. Времени
2:30
, таким образом, не существует. И никто никуда никого не округляет, но корректно переводит в зимнее время, потому что3:00
еще не наступило. Когда наступит, перевод осуществится в летнее время. Корректно. Без округлений и смс.Проще этого парсера нет, и быть не может, но давайте, озвучьте, каким пользуетесь вы — и я в том же репле покажу, что с джавой все в порядке. Даже с шестой.
alexzeed не понимаю, что вас удивляет в вашем же примере и зачем вы обзываете авторов джавы. Время никуда не округляется, время корректируется, причем корректируется правильно. Там нет никакого UB, представьте себе рулетку с выкушенным куском 10см-20см. Если вы станете отмерять 15см — увидите 25см, и это правильно. Разумно, и ожидаемо.
Вы запросили
03:30 EET
, вам вернули04:30 EEST
. На зону обратите внимание тоже.sshikov
>Я опроверг ложный тезис
Какой еще тезис? Посмотрите ответ alexzeed ниже. Более того, о том, что оно округляется — это только вы и говорите, поэтому непонятно, чего тут нужно было опровергать?
Я такое слово «округляется» не употреблял, alexzeed тоже. Я говорил, что оно становится ближайшим валидным — то есть в моем случае часом. Приведенная ниже цитата из документации это полностью подтверждает.
Разница между вашим примером и нашим реальным видимо может состоять в том, что в реальном таймзона задана через setTimeZone у SimpleDateFormat, либо по-умолчанию (что в общем почти одно и тоже). Хотя как мы видим ниже, в таком варианте оно тоже проявляется.
И еще ваш пример отличается тем, что у вас две разные зоны для зимнего и летнего времени, EST и EDT. У нас же зона ровно одна, московская. Это как минимум другой случай.
chapuza Автор
Вообще никак не подтверждает. Мне надоело, если честно, с вами спорить, потому что вы либо вообще не понимаете, о чем говорите, либо готовы на любую казуистику, лишь бы замять глупость, которую высказали ранее.
«Становится ближайшим валидным» и «округляет» — это одно и то же, вообще-то. Минуты, разумеется, никуда не пропадают. А приведенная цитата говорит о том, что время правильно сдвигается в правильную сторону.
sshikov
Знаете, почему у вас карма -14, при том что вы достаточно умный? Потому что вы самоуверены до безобразия. Я не собирался вам ничего доказывать. Вы не работали ни с ораклом ни с Java 20 лет — но все еще уверены, что все о них знаете. Вы написали 1 тест — и решили, что все доказали. Ступайте мимо.
chapuza Автор
Конечно. Потому что я не стесняюсь указывать людям недостаточно умным на то, что они недостаточно умные. Я ценю отрицательную карму на этом ресурсе, она мне льстит.
Так-то это вы приперлись в комментарии к моему тексту с неверными замечаниями, так что ступайте-ка сами.
khajiit
Ad hominem.
sshikov
Вовсе нет. Во-первых, я предпочитаю вариант «Разве нас может интересовать мнение человека лысого и вот с таким носом». А во-вторых, это просто мнение об авторе, без попытки что-либо доказать. Без хамства, причем. Он считает меня недостаточно умным, а я его. Ну и норм.
khajiit
Это тоже аргумент к человеку.
Вам довольно долго объясняли с иллюстрациями, чем представление отличается от сущности, вы даже в какой-то момент изобразили понимание. Но потом пошли на очередной круг.
chapuza Автор
Ловко вы прям на лету переобуваетесь. Ну ничего, на хабре это любят. И ад хоминем любят, если он против кого надо ад хоминем.
alexzeed
А мне тоже непонятна проблема с 0:30. Условно 20:59 utc это 23:59 msk, 21:00 utc это 0:00 msk, а 21:01 utc это 01:01 msk. И все. Не может быть 0:30 msk в этот день, неоткуда ему взяться, если кто-то при парсинге 0:30 мск вместо эксепшена превращает его молча в 01:00, то он нехороший редиска, но время тут ни причем.
sshikov
Я вас уверяю, этот нехороший человек — это кто-то из авторов java рантайма. То есть, такое происходит, если вы парсите дату в нормальном формате, с зоной, совершенно стандартным механизмом. Конкретных деталей не приведу — во-первых, это было года полтора назад, а во-вторых, я тот тест не писал, а только читал. Но если интересно, могу в понедельник поискать, без гарантии успеха.
alexzeed
Приношу свои извинения, был самоуверен. Мнение, что авторы джава рантайма нехорошие редиски, не изменю :) И не только из-за этого момента с некорректным временем. Мой опыт разработки на джаве лет 7, но именно с парсингом локального времени не сталкивался. Да, оказывается при парсинге времени, которое попадает в дырку перехода на летнее прибавляется 1 час:
дает"Sun Mar 29 04:30:00 EEST 2020"
. Для SimpleDateFormat в доке не нашел, а для ZonedDateTime этот ноговыстрел действительно задокументирован (класс ZonedDateTime: For Gaps, the general strategy is that if the local date-time falls in the middle of a Gap, then the resulting zoned date-time will have a local date-time shifted forwards by the length of the Gap, resulting in a date-time in the later offset, typically «summer» time). Остаюсь при мнении что тут должен эксепшен выскочить вместо хитрых коррекций.Вообще, мне это напрминает обработку ситуаций Undefined Behavior в С++. Типа, «такого не должно быть, поэтому делаем что хотим».
Ну и такая штука не должна возникать при работе с базой. Она должна возникать на уровне ввода пользовательских данных, или с UI, или допустим из какого-то CSV файла, в общем — снаружи системы. А внутри все времена должны представляться в каком-то непрерывном формате, тогда таких приколов не будет.
sshikov
>Приношу свои извинения, был самоуверен.
Да ладно, мы вполне культурно пообщались, без негатива. Тем более всем интересно, и пример вы в конечном счете самостоятельно раскопали. Вы с chapuza явно оба неленивые, любите докопаться до истины :)
Я ведь в общем и не спорил, что такое поведение — оно не совсем явное, и было бы неплохо либо выкинуть исключение, либо что-то еще сделать, чтобы было понятно, что такое вот произошло. Но факт что оно вполне описано, и тут уж не особо пожалуешься.
Самое смешное, что мы докопались до поддержки оракла, но они тогда ответили что-то совсем невменяемое, типа поменяйте локальную таймзону на UTC, или что-то в этом духе.
>Ну и такая штука не должна возникать при работе с базой.
Ну как-бы на стыке OGG и Hive — это примерно и есть снаружи. И на csv воспроизводилось. То есть, вы в csv кладете такую вот дату, говорите Hive, что этот файл есть таблица вот такой структуры — и опа, в таблице уже часы поменялись.
Опять же, не должна — это в идеальном мире :) В нашем реальном оракл позволяет хранить в базе невалидные даты. То есть польностью невалидные, отрицательные компоненты, а также 61 минуту, 25 часов и пр. И хуже всего, что некоторые разработчики, как у нас выражаются, «с фантазией», этим вот всем пользуются. Хорошо что редко :)
sshikov
>разумное рац. предложение, внедрю, когда выдастся свободное время, спасибо!
Ну да, этож позволяет отмечать интервал не бинарным свойством свободен/занят, а скажем «я тут буду читать книжку, но в принципе для встреч свободен».
PavloT
А чем это отличается от диаграмм Ганта?
sshikov
Э, всем? Это вообще не они. Тут речь про шкалы времени, и отрезки на них, графа тут может и не быть, и задачи решаются другие — приведенная задача со стоматологом это типовой пример планирования митинга — есть шкалы свободного и занятого времени участников, включая комнату для переговоров. И надо их всех совместить, чтобы все участники могли, и комната была свободна.
crustal
Может я что-то не понимаю, можете попробовать изучить SQL, — вроде как это стандартная задача из не очень сложных. К примеру, у вас таблица начал и окончаний интервалов занятости лиц и параметром задано значение длительности встречи. Вам надо выбрать все окончания занятости лица 1 (врача), для которых,
— его самое близкое сверху начало занятости будет отстоять вверх на величину большую длительности встречи;
— самое близкое сверху к нему начало интервала занятости лица 2 (вы) будет также отстоять вверх на величину большую длительности встречи и посередине не будет окончания занятости лица 2.
chapuza Автор
Спасибо, откажусь. Я его еще не настолько забыл, чтобы изучать заново.
К примеру, у меня вообще нет базы данных.
Не только. Например, мне нужно добавить
5 ?? 31_557_600
секунд к сегодняшней дате, игнорируя специально заданные «праздники» и все выходные (в моем решении задается стримом). И получить точное значениеDateTime
, с учетом таймзоны в Сиднее, Австралия.Или мне нужно объединить занятые слоты дантиста с государственными праздниками Каталонии.
Или мне нужно выбрать первый после первого января 2037 года слот продолжительностью в один час, в который свободны все вот эти 10 человек, комната, канал связи, и который пересекается с рабочим временем в таймзоне
America/New_York
.crustal
Наверное таки есть у вас база данных, хоть и самопальная. Данные ведь как-то храните и каким-то образом же обрабатываете.
?No passaran, camarada! Российский Крым приветствует свободную реcпублику Каталония! Возвращаясь к SQL, вы всерьез полагаете (dangling participle), что упомянутые вами нюансы запросов недоступны для SQL. Поправьте меня, если я не прав, но я привык думать, что любой SQL-related джун вам с легкостью отчебучит и не такое.
chapuza Автор
Нет, не храню. Это микросервис, который отвечает по API на запросы. Весь in-memory.
adeshere
Подскажите, пожалуйста, почему у меня может не работать ссылка:
Комп обычный, другие сайты работают… В каких настройках мне надо порыться?
Я лет 25 назад сделал свою библиотеку для работы с календарными интервалами для научных расчетов (она до сих пор используется). Но — на фортране. Одно время было желание как-то превратить этот проект в Open Source, но недостаток мозгов и отсутствие вменяемого английского не позволили сделать даже первый шаг в эту сторону :-((( А сейчас уже и смысла нет, очевидно.
Но посмотреть функционал Вашей библиотеки хочется. Хотя бы для того, чтобы добавить в свой пакет что-то полезное.
chapuza Автор
Не могу даже предположить. Мне неизвестны случаи блокировок именно этих доменов.
Документация: https://hexdocs.pm/tempus
Исходный код: https://github.com/am-kantox/tempus
Bedal
извиняюсь, что просмотрел по диагонали, но учтена возможность смены времени зимнее/летнее внутри интервала?