Gibt es einen Standard für inklusive/exklusive Enden von Zeitintervallen?

Lesezeit: 16 Minuten

Ich frage mich, ob es eine gibt Standard oder “normale” Mittel zum Interpretieren von Endpunkten von Zeitintervalldaten in Bezug auf die Einschließlichkeit/Ausschließlichkeit des Werts, der den Endpunkt definiert. Beachten Sie jedoch, dass ich frage, was der Standard (oder am häufigsten) Konvention ist (falls vorhanden), nicht für eine Dissertation über Ihre persönliche Präferenz. Wenn Sie wirklich eine Dissertation erstellen möchten, fügen Sie ihr bitte einen Verweis auf eine veröffentlichte Norm oder einen Standardtext zu diesem Thema bei. Offene Standards (die ich nicht bezahlen muss, um sie zu lesen) werden stark bevorzugt, es sei denn, sie sind grundlegend fehlerhaft :).

Natürlich gibt es 4 Möglichkeiten für ein Zeitintervall von A nach B:

  1. (A, B) – Beide Enden sind exklusiv.
  2. [A, B] – Beide Enden sind inklusive.
  3. [A, B) – Start is inclusive and end is exclusive
  4. (A, B] – Start ist exklusiv und Ende ist inklusive

Jedes davon hat unterschiedliche Eigenschaften (wie ich es sehe, fühlen Sie sich frei, mehr darauf hinzuweisen)

Das [A, B] Konvention hätte die scheinbar unbequeme Eigenschaft, dass B innerhalb des Intervalls enthalten ist [A, B] und auch [B, C]. Dies ist besonders unpraktisch, wenn B die Mitternachtsgrenze darstellen soll und Sie beispielsweise versuchen, zu bestimmen, auf welchen Tag sie fällt. Auch das bedeutet, dass die Dauer des Intervalls etwas irritierend zu berechnen ist, da [A, B] wobei A = B eine Länge von 1 haben soll und somit die Dauer von [A, B] ist (B – A) + 1

In ähnlicher Weise hätte die (A, B)-Konvention die Schwierigkeit, dass B weder in (A, B) noch (B, C) fällt … Um die Analogie mit Tagesgrenzen fortzusetzen, wäre Mitternacht Teil von keinem Tag. Das ist auch logisch unbequem, weil [A, B] wobei A = B ein Nicht-Sinn-Intervall mit einer Dauer kleiner als null ist, aber das Umkehren von A und B macht es nicht zu einem gültigen Intervall.

Also ich glaube, ich will beides [A, B), or (A, B] und ich kann nicht herausfinden, wie ich mich zwischen ihnen entscheiden soll.

Wenn also jemand einen Link zu einem Standarddokument hat, einen Verweis auf einen Standardtext oder ähnliches, der die Konvention verdeutlicht, wäre das großartig. Wenn Sie alternativ eine Vielzahl von Standarddokumenten und / oder Referenzen verlinken können, die mehr oder weniger vollständig nicht übereinstimmen, kann ich einfach eines auswählen, das ausreichend Autorität für CMA zu haben scheint, und damit fertig sein :).

Schließlich werde ich in Java arbeiten, daher bin ich besonders anfällig für Antworten, die in Java gut funktionieren.

  • Was meinst du mit “inklusive”? Die Zeit ist kontinuierlich, wir diskretisieren sie nur für Berechnungszwecke. Wenn wir in Stunden arbeiten, läuft heute von 00 bis 23 (einschließlich). Aber das ist falsch, sobald wir die Auflösung erhöhen; heute ist von 00:00 bis 23:59 (einschließlich) und so weiter…

    – Oliver Charlesworth

    20. März 2012 um 21:43 Uhr

  • Jedes Projekt, an dem ich jemals gearbeitet habe, wurde von den Geschäftskonventionen der Anwendungsdomäne bestimmt, nicht von abstrakten Konventionen der Programmierung.

    – Affe

    20. März 2012 um 21:44 Uhr

  • @Oli Genau der Punkt. Offensichtlich muss ich eine diskrete Darstellung verwenden, und das ist unnatürlich. Die Frage dreht sich um den besten Weg, um mit der Diskrepanz umzugehen.

    – Guss

    20. März 2012 um 21:44 Uhr


  • @Gus: Dann ist dies nicht zeitspezifisch. Dies ist das gleiche Problem für jede Menge, die wir diskretisieren müssen.

    – Oliver Charlesworth

    20. März 2012 um 21:46 Uhr

  • @Affe Ich bin zufällig in einer Situation, in der ich gebeten werde, etwas vorzuschlagen, und ich habe keinen guten Grund zu der Annahme, dass es eine gut etablierte Geschäftskonvention gibt. Wenn ich falsch liege, ändere ich mich natürlich.

    – Guss

    20. März 2012 um 21:47 Uhr

Voos Benutzeravatar
Voo

Im allgemeinen Fall [A, B) (inclusive start, exclusive end) has a lot going for it and I don’t see any reason why the same wouldn’t be true for time intervals.

Djikstra wrote a nice article about it Why numbering should start at zero which – despite the name – deals mostly with exactly this.

Short summary of the advantages:

  • end - start equals the number of items in the list
  • upper bound of preceding interval is the lower bound of the next
  • allows to index an interval starting from 0 with unsigned numbers [1]

Persönlich ist der zweite Punkt äußerst nützlich für viele Probleme; Betrachten Sie eine ziemlich standardmäßige rekursive Funktion (in Pseudo-Python):

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

Dasselbe mit inklusiver Obergrenze zu schreiben, führt zu vielen Fehlern, die durch einen Fehler anfällig sind.

[1] Das ist der Vorteil gegenüber (A, B] – Ein Intervall, das bei 0 beginnt, ist VIEL häufiger als ein Intervall, das mit endet MAX_VAL. Beachten Sie, dass sich dies auch auf ein zusätzliches Problem bezieht: Die Verwendung von zwei inklusiven Grenzen bedeutet, dass wir eine Sequenz bezeichnen können, deren Länge nicht mit derselben Größe ausgedrückt werden kann.

  • Ich stimme vollkommen zu [A,B) being the best, especially with regard to the midnight problem. 2014-01-01 00:00:002014-01-02 00:00:00, when interpreted using [A,B), includes the entirety of January 1st. This properly excludes 2014-01-02 00:00:00, which falls on January 2nd.

    – Dan Bechard

    Apr 22, 2014 at 21:01

Basil Bourque's user avatar
Basil Bourque

java.time & Half-Open

The java.time classes that supplant the troublesome legacy date-time classes as well as the Joda-Time project define a span-of-time using the Half-Open approach [) where the beginning is inclusive while the ending is exclusive.

For date-time with a fractional second this eliminates the problem of trying to capture last moment. The infinitely-divisible last second must be resolved, but various systems use various granularities such as milliseconds, microseconds, nanoseconds, or something else. With Half-Open, a day, for example, starts at the first moment of the day and runs up to, but does not include, the first moment of the following day. Problem solved, no need to wrestle with last moment of the day and its fractional second.

I have come to see the benefits of using this approach consistently throughout all my date-time handling code. A week for example starting on a Monday runs up to, but does not include, the following Monday. A month starts on the 1st and runs up to, but does not include, the first of the following month thereby ignoring the challenge of determining the number of the last day of the month including Feb 28/29 Leap Year.

Another benefit of consistent use of Half-Open [) is the easing the cognitive load every time I have to detect and decipher and verify a piece of code’s span-of-time approach. In my own programming, I simply glance for a mention of Half-Open in a comment at top and I instantly know how to read that code.

A result of consistent use of Half-Open is reducing the chance of bugs in my code as my thinking and writing style are uniform with no chance of getting confused over inclusive-exclusive.

By the way, note that Half-Open [) means avoiding the SQL BETWEEN conjunction as that is always fully-closed [].

Was das Geschäftsdenken der Kunden betrifft, die ich betreue, versuche ich sie gegebenenfalls davon zu überzeugen, Half-Open ebenfalls ständig zu verwenden. Ich habe viele Situationen erlebt, in denen verschiedene Geschäftsleute falsche Annahmen über die in Berichten abgedeckten Zeiträume getroffen haben. Die konsequente Verwendung von Half-Open vermeidet diese unglücklichen Mehrdeutigkeiten. Aber wenn der Kunde darauf besteht, vermerke ich das in meinem Code und passe Ein-/Ausgänge an, um Half-Open in meiner eigenen Logik zu verwenden. Zum Beispiel verwendet meine Logik eine Woche von Montag bis Montag, aber in einem Bericht subtrahieren Sie einen Tag, um Sonntag anzuzeigen.

Für noch mehr Klassen, die Zeitspannen mit dem halboffenen Ansatz darstellen [), see the ThreeTen-Extras project for its Interval class (a pair of Instant objects) and the LocalDateRange class (a pair of LocalDate objects).

Tip: When printing/displaying reports for business, include a footer that describes the query logic including the detail of the beginning/ending be inclusive/exclusive. I have seen way too much confusion on this in the workplace, with readers making incorrect assumptions about the date ranges (and other criteria).


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

  • Excellent discussion and update WRT newer libraries 🙂

    – Gus

    Aug 5, 2017 at 12:51

  • Representing time as half-open feels like the simplest way to to reason about time. I’m finding it hard to find any source documentation, but what does ISO 8601 say about interval boundaries? Does it specify that they are right-open?

    – mkobit

    Apr 3, 2019 at 15:07

  • @mkobit I have not read the ISO 8601 standard, as it is copyrighted, rather expensive, and not easily obtained. If you look at the Time Intervals portion of the Wikipedia page, its shows multiple examples that seem to be in Half-Open semantics. I suspect that is not explicitly stating Half-Open though — it is simply natural to say that a half-hour meeting at 3 PM ends at 15:30 rather than 15.29.999999999.

    – Basil Bourque

    May 21, 2021 at 5:24

  • Thanks @BasilBourque – when I was trying to look into this a bit more, I too ran into the troubles in looking at ISO8601 you described. I decided to move forward with half-open with right-openness, and it made the system we built simple to reason about!

    – mkobit

    May 21, 2021 at 18:54

I’ll provide what I wrote for our team as an answer using Voo’s link until such time as Voo adds an answer, then I’ll give him credit instead. Here’s what I decided for our case:

Time intervals in our applications will be represented as a pair of
instantaneous times with the convention that the start time is
inclusive and the end time is exclusive. This convention is
mathematically convenient in that the difference of the bounds is
equal to the length of the interval, and is also numerically
consistent with the way arrays and lists are subscripted in java
programs (see http://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF). The
practical upshot of this is that interval 2012-03-17T00:00:00.000Z –
2012-03-18T00:00:00.000Z denotes the entirety of St. Patrick’s Day,
and every date beginning with 2012-03-17 will be identified as
included in St Patrick’s Day, but 2012-03-18T00:00:00.000Z will not be
included, and St Patrick’s Day will include exactly 24*60*60*1000
milliseconds.

Despite this thread focusing more on Java, I thought it’d be quite interesting to see other adopted conventions, especially given that the pandas Python library is ubiquitous for data analysis these days, and the fact that this StackOverflow page is one of the top search results when looking for conventions on the inclusivity/exclusivity of time ranges.

Quoting this page:

The start and end dates are strictly inclusive. So it will not generate any dates outside of those dates if specified.

Also, it’s not only generating date ranges. The convention is also adopted when trying to index into time-series data. Here’s a simple test on data frames with 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 01.07.2017 002.07.2017 1 03.07.2017 2 04.07.2017 3 05.07.2017 4

Ich kann es nicht mit Sicherheit sagen, aber ich bezweifle, dass es einen Standard oder eine Konvention gibt. Ob Sie den Start- oder Endzeitpunkt einbeziehen oder nicht, hängt von Ihrem Anwendungsfall ab, also überlegen Sie, ob sie für Sie wichtig sind. Wenn die Entscheidung willkürlich ist, wählen Sie eine aus, beachten Sie, dass die Wahl willkürlich ist, und fahren Sie fort.

Was in Java unterstützt wird, implementiert die Joda Time-Bibliothek Intervals, die die Startzeit, aber nicht die Endzeit enthalten

  • +1: Verwenden Sie einfach Joda Time :). Kann auch hilfreich sein, um zu sehen, was eine Digitaluhr tut: Zeiten werden gemäß (und einschließlich) dem Beginn des Intervalls gekennzeichnet.

    – Andreas Aylett

    20. März 2012 um 21:49 Uhr

  • Obwohl ich möglicherweise die Konvention von Joda Time akzeptieren könnte, wenn es keine anderen besseren Antworten gibt, möchte ich dem Projekt keine Bibliotheken hinzufügen, es sei denn, ich muss es tatsächlich … 🙂

    – Guss

    20. März 2012 um 21:57 Uhr

  • Wenn dies die erste Bibliothek ist, die Ihr Projekt benötigt, kann das Hinzufügen mühsam sein (abhängig von Ihren Entwicklungs- und Bereitstellungseinstellungen), sodass ich Ihr Zögern verstehen kann. Wenn Sie bereits Bibliotheken haben, lohnt es sich, Joda Time zu verwenden. Die API für den Umgang mit Daten ist weitaus besser als die java.util Paket. Mit Bibliotheken können Sie sich auf Ihre Anwendung konzentrieren, indem Sie die üblichen oder schwierigen Dinge für Sie implementieren.

    – sgmorrison

    20. März 2012 um 22:05 Uhr

  • Ich verstehe nicht, warum Zeitintervalle anders gehandhabt werden sollten als andere Intervalle. Im allgemeinen Fall [A, B) has a LOT going for it – djikstra wrote a nice paper summarizing the different approaches and why inclusive, exclusive is the best. Also his penmanship is really excellent

    – Voo

    Mar 20, 2012 at 22:14


  • @Voo Nice, this link is precisely the sort of thing I was looking for. A clear exposition on a fundamental basis by a person or group of known expertise. Clarifies my thinking, and covers my butt :), care to turn it into an answer so I can give you credit?

    – Gus

    Mar 21, 2012 at 14:28

I have just been through this exact same thought process and i think it is very important that this is standardised in some way, or at least clarified by means of these types of Q&A posts!

In our case the date ranges in question are used as inputs and outputs to / from a microservice; one that, in the short-term at least, will be called by an existing monolithic application (it’s a monolith decomposition project). Therefore, i think that the comment above relating to the decision being driven by business requirements is, in our case, less relevant (because the direct “users” of the software we’re building are really technical people). If we were handling the input from a date picker that might be a different story!

My recommendation was that all start dates are inclusive and all end dates are exclusive – so [A,B) in your notation. This was for the following reasons:

  1. We had previously agreed that any incoming dates containing time parts would be rejected (even if the JSON value was “2018-01-01T00:00:00”) and that we’d output all dates without times. Therefore, if the end date is exclusive, as soon as the string is deserialized into the .NET DateTime object, it would be a day out.

  2. I like the idea that date ranges (which in our case should always yield whole days) can can always be calculated by simply doing dateRange = (endDateExcl – startDateIncl).TotalDays. No need to add 1 everywhere!

  3. Much of the business validation performed by the service is checking that multiple data ranges are flush against each other without gaps. This is easy to eye check when using [A,B) because each B should match the preceding A. If we go with [A,B] dann würden wir (Entwickler, Tester, Support-Ingenieure) uns oft fragen: “Wie viele Tage hat der März nochmal?” (z.B [2018-03-01,2018-03-30],[2018-04-01,2018-04-30]) oder “Hat 2016 einen Schalttag?” (z.B [2016-02-01,2016-02-28],[2016-03-01,2016-03-30]).

Nur um hinzuzufügen, ich empfehle jedem dringend, unabhängig von seiner Entscheidung, alle Attributnamen, Variablen, Methoden oder anderweitig explizit mit “Incl” oder “Excl” zu versehen, damit es für jeden klar ist, ohne Dokumentation suchen zu müssen!

Wir haben auch empfohlen, dass alle Daten im ISO-Format eingegeben werden sollten und dass alles mit einem „Z“ am Ende ebenfalls abgelehnt werden sollte (weil das Verständnis ist, dass wir in ganzen Tagen arbeiten und kein Datum haben möchten in ein DateTime-Objekt mit einer fehlerhaften Stunde (oder 23!) wegen der Sommerzeit deserialisiert werden).

Fußnote, ich hätte dies wahrscheinlich als Kommentar zu Voos Antwort gepostet, aber ich bin gerade (verspätet!) SO beigetreten und muss mir mein Lob verdienen, bevor ich das tun kann! 😉

Viel Spaß beim Dating x

  • +1: Verwenden Sie einfach Joda Time :). Kann auch hilfreich sein, um zu sehen, was eine Digitaluhr tut: Zeiten werden gemäß (und einschließlich) dem Beginn des Intervalls gekennzeichnet.

    – Andreas Aylett

    20. März 2012 um 21:49 Uhr

  • Obwohl ich möglicherweise die Konvention von Joda Time akzeptieren könnte, wenn es keine anderen besseren Antworten gibt, möchte ich dem Projekt keine Bibliotheken hinzufügen, es sei denn, ich muss es tatsächlich … 🙂

    – Guss

    20. März 2012 um 21:57 Uhr

  • Wenn dies die erste Bibliothek ist, die Ihr Projekt benötigt, kann das Hinzufügen mühsam sein (abhängig von Ihren Entwicklungs- und Bereitstellungseinstellungen), sodass ich Ihr Zögern verstehen kann. Wenn Sie bereits Bibliotheken haben, lohnt es sich, Joda Time zu verwenden. Die API für den Umgang mit Daten ist weitaus besser als die java.util Paket. Mit Bibliotheken können Sie sich auf Ihre Anwendung konzentrieren, indem Sie die üblichen oder schwierigen Dinge für Sie implementieren.

    – sgmorrison

    20. März 2012 um 22:05 Uhr

  • Ich verstehe nicht, warum Zeitintervalle anders gehandhabt werden sollten als andere Intervalle. Im allgemeinen Fall [A, B) has a LOT going for it – djikstra wrote a nice paper summarizing the different approaches and why inclusive, exclusive is the best. Also his penmanship is really excellent

    – Voo

    Mar 20, 2012 at 22:14


  • @Voo Nice, this link is precisely the sort of thing I was looking for. A clear exposition on a fundamental basis by a person or group of known expertise. Clarifies my thinking, and covers my butt :), care to turn it into an answer so I can give you credit?

    – Gus

    Mar 21, 2012 at 14:28

1431000cookie-checkGibt es einen Standard für inklusive/exklusive Enden von Zeitintervallen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy