Czy istnieje standard dla inclusive / exclusive końców przedziałów czasowych?

Zastanawiam się, czy istnieje standardowy lub "normalny" sposób interpretacji punktów końcowych przedziału czasu w odniesieniu do inkluzywności / wyłączności wartości definiującej punkt końcowy. Zauważ jednak, że pytam, jaki standard (lub najczęściej) zjazd jest (jeśli jest), a nie na rozprawę o osobistych preferencjach. Jeśli naprawdę chcesz dostarczyć pracę doktorską, dołącz ją do odniesienia do czyjegoś opublikowanego Standardu lub standardu tekst w tej sprawie. Otwarte standardy (których nie muszę płacić za czytanie) są bardzo preferowane, chyba że są zasadniczo wadliwe :).

Oczywiście istnieją 4 możliwości przedziału czasowego od A do B:

  1. (A, B) - oba końce są wyłączne.
  2. [A, B] - oba końce są łącznie.
  3. [A, B) - początek jest inkluzywny, a koniec Wyłączny
  4. (A, B] - początek jest wyłączny, a koniec jest inkluzywny

Każdy z nich ma inne cechy (jak to widzę, nie krępuj się wskazać więcej)

Konwencja [A, B] miałaby pozornie niewygodną właściwość, że b jest zawarta w intevalu [a, B], a także [B, C]. Jest to szczególnie niewygodne, jeśli B ma reprezentować granicę północy i próbujesz określić, w którym dniu wypada na przykład. Oznacza to również, że czas trwania przedziału jest nieco irritatig do obliczenia od [A, B], gdzie A = B powinien mieć długość 1, a zatem czas trwania [A, B] jest (B-A) + 1

Podobnie konwencja (A, B) miałaby tę trudność,że B nie mieści się w Ani (A,B), ani (B, C)... kontynuując analogię z granicami dnia, północ nie będzie częścią żadnego dnia. Jest to również logicznie niewygodne, ponieważ [A, B] gdzie A = B jest bezsensownym interwałem o czasie trwania mniejszym niż zero, ale odwrócenie A i B nie czyni go prawidłowym interwałem .

Więc myślę, że chcę albo [A, B), albo (A, B] i nie wiem jak decydować między nimi.

Więc jeśli ktoś ma link do dokumentu standardowego, odniesienie do tekstu standardowego lub podobnego, które wyjaśniają konwencję, która byłaby świetna. Alternatywnie, jeśli możesz połączyć różne dokumenty norm i / lub odniesienia, które mniej lub bardziej całkowicie się nie zgadzają, to mogę po prostu wybrać taki, który wydaje się mieć wystarczające uprawnienia do CMA i być z nim zrobione :).

Wreszcie będę pracował w Javie, więc jestem szczególnie podatny na odpowiedzi, które działają dobrze w Javie.

Author: Gus, 2012-03-21

6 answers

W ogólnym przypadku, [A, B) ma wiele do zrobienia i nie widzę powodu, dla którego to samo nie byłoby prawdą dla przedziałów czasowych.

Djikstra napisał o tym fajny artykuł Dlaczego numeracja powinna zaczynać się od zera , który-wbrew nazwie-dotyczy głównie właśnie tego.

Krótkie podsumowanie korzyści:

  • end - start równa się liczbie pozycji na liście
  • górna granica przedziału poprzedzającego jest dolną granicą następnego
  • pozwala na indeks interwał zaczynający się od 0 z liczbami niepodpisanymi[1]

Osobiście drugi punkt jest niezwykle przydatny w wielu problemach; rozważ dość standardową funkcję rekurencyjną (w pseudo Pythonie):

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

Pisanie tego samego z włączoną górną granicą wprowadza wiele błędów podatnych na jeden błąd.

[1] to jest zaleta w porównaniu do (A, B] - interwał zaczynający się od 0 jest znacznie częstszy niż interwał kończący się na MAX_VAL. Zwróć uwagę, że dotyczy to również do jednego dodatkowego problemu: użycie dwóch granic inkluzywnych oznacza, że możemy oznaczać ciąg, którego długości nie można wyrazić za pomocą tej samej wielkości.

 38
Author: Voo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-21 18:15:15

Podam to co napisałem dla naszego zespołu jako odpowiedź używając linku Voo do czasu aż Voo doda odpowiedź, wtedy dam mu kredyt. Oto co postanowiłem dla naszej sprawy:

Przedziały czasowe w naszych aplikacjach będą reprezentowane jako para chwilowe czasy z konwencją, że czas rozpoczęcia jest inclusive i czas zakończenia jest wyłączny. Konwencja ta jest matematycznie wygodne, gdyż różnica granic jest równa długości interwał, a także jest numerycznie zgodny ze sposobem zapisu tablic i list w Javie programy (Zobacz http://www.cs.utexas.edu / ~ EWD / ewd08xx / EWD831. PDF ). The 2012-03-17T00:00:00.000 Z – 2012-03-18T00:00:00.000 Z, i każda data rozpoczynająca się od 2012-03-17 będzie oznaczona jako wliczone w Dzień Świętego Patryka, ale 2012-03-18T00:00:00.000 Z nie będzie wliczony, a Dzień Św. Patryka będzie Dołącz dokładnie 24*60*60*1000 milisekundy.

 4
Author: Gus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-21 14:59:54

Nie mogę powiedzieć na pewno, ale wątpię, że istnieje norma lub konwencja. To, czy włączysz pocztę początkową lub końcową, zależy od Twojego przypadku użycia, więc zastanów się, czy są one dla Ciebie ważne. Jeśli decyzja jest arbitralna, wybierz jedną, zauważ, że wybór jest arbitralny i idź dalej.

Co do tego, co jest obsługiwane w Javie, biblioteka czasu Joda implementuje Intervals, które zawierają czas rozpoczęcia, ale nie czas zakończenia

 2
Author: sgmorrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-20 21:45:34

Pomimo tego, że ten wątek skupia się bardziej na Javie, pomyślałem, że byłoby całkiem interesujące zobaczyć inne przyjęte konwencje, zwłaszcza biorąc pod uwagę, że biblioteka pandas Python jest wszechobecna do analizy danych w dzisiejszych czasach, i fakt, że ta strona StackOverflow jest jednym z najlepszych wyników wyszukiwania, Gdy szukasz konwencji dotyczących inkluzywności/wyłączności zakresów czasu.

Cytowanie tej strony:

Daty rozpoczęcia i zakończenia są ściśle inclusive. Więc nie będzie Generuj dowolne daty poza tymi datami, jeśli są określone.

Nie tylko generuje zakresy dat. Konwencja jest również przyjęta przy próbie indeksowania danych szeregów czasowych. Oto prosty test na ramkach danych z 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
 1
Author: Ivan Gozali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 19:23:46

Java.time & Half-Open

Java.CZAS klasy, które zastępują kłopotliwe starsze klasy date-time, jak również projekt Joda-Time definiują rozpiętość czasu przy użyciu podejścia półotwartego [), gdzie początek jest inclusive, podczas gdy zakończenie jest exclusive.

Dla daty i czasu z ułamkową sekundą eliminuje to problem próby uchwycenia ostatniej chwili. Nieskończenie podzielna ostatnia sekunda musi być rozwiązana, ale różne systemy używaj różnych ziarnistości, takich jak milisekundy, mikrosekundy, nanosekundy lub coś innego. Na przykład w przypadku Half-Open, dzień zaczyna się w pierwszej chwili dnia i trwa do, ale nie zawiera , a nie, pierwszej chwili następnego dnia. Problem rozwiązany, nie trzeba zmagać się z ostatnią chwilą dnia i jego ułamkową sekundą.

Zacząłem dostrzegać korzyści płynące z konsekwentnego stosowania tego podejścia przez cały mój kod do obsługi daty i czasu. Tydzień np. początek w poniedziałek trwa do, ale nie obejmuje, następnego poniedziałku. Miesiąc rozpoczyna się 1. i trwa do, ale nie obejmuje, pierwszego następnego miesiąca, ignorując tym samym wyzwanie określenia liczby ostatniego dnia miesiąca, w tym 28/29 lutego roku przestępnego.

Kolejną zaletą konsekwentnego stosowania półotwartego [) jest złagodzenie obciążenia poznawczego za każdym razem, gdy muszę wykryć, odszyfrować i zweryfikować fragment kodu w czasie. W moim własnym programowaniu wystarczy spojrzeć na wzmiankę o półotwartym w komentarzu na górze i od razu wiem, jak odczytać ten kod.

Rezultatem konsekwentnego używania półotwartego kodu jest zmniejszenie szansy na błędy w moim kodzie, ponieważ mój styl myślenia i pisania jest jednolity, bez szans na zmieszanie się z wyłącznością.

Przy okazji, zauważ, że półotwarte [) oznacza unikanie kombinacji SQL BETWEEN, ponieważ zawsze jest całkowicie zamknięte [].

Co do biznesowego myślenia klientów I serwować, w razie potrzeby staram się ich przekonać do ciągłego używania półotwartych. Widziałem wiele sytuacji, w których różni biznesmeni robili błędne założenia dotyczące okresów czasu objętych raportami. Konsekwentne stosowanie półotwartych unika tych niefortunnych niejasności. Ale jeśli klient nalega, zaznaczam to w moim kodzie i dostosowuję wejścia/wyjścia tak, aby używać półotwartego w mojej własnej logice. Na przykład moja logika używa tygodnia poniedziałek-poniedziałek, ale w raporcie odjąć dzień, aby pokazać Niedziela.

Jeszcze więcej klas reprezentujących czas z podejściem półotwartym [), zobacz projekt ThreeTen-Extras dla jego klasy Interval (para obiektów Instant) i klasy LocalDateRange (para obiektów {4]}).


O Javie.CZAS

Java.Framework time jest wbudowany w Javę 8 i nowszą. Klasy te zastępują kłopotliwe staredziedzictwo klasy date-time, takie jak java.util.Date, Calendar, & SimpleDateFormat.

Projekt Joda-Time , obecnie w trybie konserwacji , radzi migrację do java.CZAS klasy.

Aby dowiedzieć się więcej, Zobacz samouczek Oracle. I wyszukaj przepełnienie stosu dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Skąd pobrać Javę.zajęcia czasowe?

The ThreeTen-Extra projekt rozszerza Javę.czas z dodatkowymi zajęciami. Ten projekt jest poligonem dla potencjalnych przyszłych dodatków do Javy.czas. Możesz znaleźć tutaj kilka przydatnych klas, takich jak Interval, YearWeek, YearQuarter, i więcej .

 1
Author: Basil Bourque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-03 05:41:57

Właśnie przechodziłem przez ten sam proces myślowy i uważam, że bardzo ważne jest, aby został on w jakiś sposób ustandaryzowany, lub przynajmniej wyjaśniony za pomocą tego typu postów z pytaniami i odpowiedziami!

W naszym przypadku zakresy dat są używane jako wejścia i wyjścia do / Z mikroserwisu; taki, który, przynajmniej krótkoterminowo, zostanie wywołany przez istniejącą aplikację monolityczną (jest to projekt rozkładu monolitu). Dlatego uważam, że powyższy komentarz dotyczący podejmowanie decyzji w oparciu o wymagania biznesowe jest w naszym przypadku mniej istotne (ponieważ bezpośredni "użytkownicy" tworzonego przez nas oprogramowania to naprawdę ludzie techniczni). Gdybyśmy zajmowali się wejściami z selektora DAT, to może być inna historia!

Moim zaleceniem było to, że wszystkie daty rozpoczęcia są inclusive i wszystkie daty zakończenia są wyłączne - więc [A, B)w notacji. Było to z następujących powodów:

  1. Wcześniej uzgodniliśmy, że wszelkie nadchodzące daty zawierające części czasu zostaną odrzucone (nawet jeśli wartość JSON to "2018-01-01T00:00:00") i że będziemy wypisywać wszystkie daty bez czasów. Dlatego, jeśli data końcowa jest wyłączna, gdy tylko łańcuch zostanie deserializowany do obiektu. NET DateTime, będzie to dzień.

  2. Podoba mi się pomysł, że zakresy dat (które w naszym przypadku powinny zawsze dawać całe dni) można zawsze obliczyć po prostu wykonując dateRange = (endDateExcl - startDateIncl).TotalDays. Nie trzeba dodawać 1 wszędzie!

  3. Większość walidacji biznesowej wykonywanej przez usługę polega na sprawdzeniu, czy wiele zakresów danych jest równo ze sobą bez luk. Jest to łatwe do sprawdzenia podczas używania [A, B), ponieważ każde B powinno pasować do poprzedniego A. Jeśli pójdziemy z [A, B], to my (programiści, testerzy, inżynierowie wsparcia) często zadawalibyśmy sobie pytanie " ile dni jest w marcu ponownie?"(np. [2018-03-01,2018-03-30],[2018-04-01,2018-04-30]) albo " czy 2016 ma dzień przestępny?"(np. [2016-02-01,2016-02-28],[2016-03-01,2016-03-30]).

Aby dodać, zdecydowanie polecam każdemu, niezależnie od decyzji, aby wyraźnie przyrostek wszystkich nazw atrybutów, zmiennych, metod lub w inny sposób z "Incl" lub "Excl", aby było jasne dla wszystkich bez konieczności poszukiwania dokumentacji!

Zaleciliśmy również, aby wszystkie daty były w formacie ISO i że wszystko, co ma " Z " na końcu, również powinno być odrzucone (ponieważ zrozumienie jest takie, że jesteśmy praca w ciągu całych dni i nie chcemy, aby data została deserializowana do obiektu DateTime z godziną rogue (lub 23!) ze względu na czas letni).

Przypis, pewnie zamieściłbym to jako komentarz do odpowiedzi Voo, ale właśnie (z opóźnieniem!) dołączył więc i muszę zasłużyć na moje uznanie, zanim będę mógł to zrobić! ;-)

Happy dating x

 1
Author: Hashababba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-06 11:39:06