Existe-t-il une norme pour les intervalles de temps inclusifs/exclusifs?

je me demande s'il existe un standard ou" normal " moyen d'interpréter les points de fin des données d'intervalle de temps en ce qui concerne l'inclusivité/l'exclusivit é de la valeur définissant le point de fin. Notez cependant que je demande ce que la norme (ou le plus commun) convention est (s'il y a un), pas pour une dissertation sur votre préférence personnelle. Si vous voulez vraiment vous fournir une thèse, veuillez le joindre à un référence à une norme publiée ou à un texte standard sur la question. Les standards ouverts (que je n'ai pas à payer pour lire) sont grandement préférés à moins qu'ils ne soient fondamentalement défectueux :).

bien sûr il y a 4 possibilités pour un intervalle de temps de A à B:

  1. (A, B) - les deux extrémités sont exclusives.
  2. [A, B] - les deux extrémités sont inclusives.
  3. [A, B] - le début est inclusif et la fin est exclusive
  4. (A, B] - départ exclusif et fin inclusive

chacun de ceux-ci a des caractéristiques différentes (comme je le vois, n'hésitez pas à préciser plus)

la convention [A, B] aurait la propriété apparemment incommode que B contient avec l'inteval [a, b] et aussi [B, C]. Cela est particulièrement gênant si B est destiné à représenter la limite de minuit et vous essayez de déterminer jour, il tombe par exemple. En outre, cela signifie que la durée de l'intervalle est légèrement irritante à calculer puisque [A, B] où A = B devrait avoir une longueur de 1 et donc la durée de [A, B] est (B - A) + 1

de même, la Convention (A,B) aurait la difficulté que B ne relève ni de (A,B) ni de (B, C)... en continuant l'analogie avec les limites du jour, minuit ne ferait partie d'aucune des deux journées. C'est aussi logiquement gênant parce que [A, B] où A = B est un intervalle de non sens avec une durée inférieure à zéro, mais l'inversion de A et B n'en fait pas un intervalle valide .

donc je pense que je veux soit [a, b), ou (a, B] et je ne peux pas comprendre comment décider entre eux.

donc, si quelqu'un a un lien vers un document de normes, une référence à un texte standard ou similaire qui clarifie la convention qui serait grande. Alternativement, si vous pouvez lier une variété de normes documents et / ou références qui, plus ou moins complètement, ne sont pas d'accord, alors je peux juste en choisir un qui semble avoir suffisamment d'autorité à L'AMC et être fait avec elle :).

Enfin, je vais travailler en Java, donc je suis particulièrement sensible aux réponses qui fonctionnent bien en Java.

34
demandé sur Gus 2012-03-21 01:38:19

6 réponses

dans le cas général, [A, B) a beaucoup de chance et je ne vois pas pourquoi la même chose ne serait pas vraie pour les intervalles de temps.

Djikstra a écrit un bel article à ce sujet pourquoi la numérotation devrait commencer à zéro qui - malgré le nom - traite principalement avec exactement cela.

bref résumé des avantages:

  • end - start est égal au nombre d'articles de la liste
  • limite supérieure de l'intervalle précédent est la limite inférieure de la prochaine
  • permet d'indexer un intervalle à partir de 0 avec des numéros non signés [1]

personnellement le deuxième point est extrêmement utile pour beaucoup de problèmes; considérez une fonction récursive assez standard (en pseudo python):

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

écrit la même chose avec Limite supérieure inclusive introduit lots de commettre des erreurs par l'une des erreurs.

[1] C'est l'avantage par rapport à (A, B] - un intervalle commençant par 0 est beaucoup plus commun qu'un intervalle se terminant par MAX_VAL . Notez que cela concerne également un problème supplémentaire: L'utilisation de deux limites inclusives signifie que nous pouvons dénoter une séquence dont la longueur ne peut pas être exprimée avec la même taille.

38
répondu Voo 2012-03-21 18:15:15

je vais fournir ce que j'ai écrit pour notre équipe comme une réponse en utilisant le lien de Voo jusqu'à ce que Voo ajoute une réponse, puis je vais lui donner le crédit à la place. Voici ce que j'ai décidé pour notre affaire:

intervalles de temps dans nos applications seront représentés comme une paire de instantanée fois avec la convention que l'heure de début est inclusive et l'heure de fin est exclusif. La présente convention est mathématiquement commode en ce que la différence des limites être égale à la longueur de l'intervalle, et est numériquement compatible avec la façon dont les tableaux et les listes sont inscrits en java programmes (voir http://www.cs.utexas.edu / ~EWD / ewd08xx / EWD831.PDF ). Le le résultat pratique de ceci est que l'intervalle 2012-03-17T00: 00:00.000 Z – 2012-03-18T00: 00:00.000 Z indique l'intégralité de la journée de la Saint Patrick, et chaque date commençant par 2012-03-17 sera identifiée comme inclus dans St Patrick's Day, mais 2012-03-18T00: 00:00.000 Z ne sera pas inclus, et le jour de la St Patrick comprendra exactement 24*60*60*1000 milliseconde.

4
répondu Gus 2012-03-21 14:59:54

Je ne peux pas le dire avec certitude, mais je doute qu'il existe une norme ou une convention. Que vous incluiez ou non l'instant de début ou de fin dépend de votre cas d'utilisation, alors considérez s'ils sont importants pour vous. Si la décision est arbitraire, en choisir un, notez que le choix est arbitraire et de progresser.

quant à ce qui est supporté en Java, la bibliothèque Joda Time implémente Interval s qui incluent l'Heure de début mais pas l'Heure de fin

2
répondu sgmorrison 2012-03-20 21:45:34

malgré ce fil se concentrant davantage sur Java, j'ai pensé qu'il serait très intéressant de voir d'autres conventions adoptées, surtout étant donné que le pandas Python bibliothèque est omniprésent pour l'analyse des données ces jours-ci, et le fait que cette page StackOverflow est l'un des meilleurs résultats de recherche quand on cherche des conventions sur l'inclusivité/exclusivité des plages de temps.

citant cette page :

les dates de début et de fin sont strictement inclusives. Il ne générera donc pas de dates en dehors de ces dates si elles sont spécifiées.

aussi, ce n'est pas seulement générer des plages de dates. La convention est également adoptée lorsqu'il s'agit d'indexer des données chronologiques. Voici un test simple sur les bases de données avec 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
répondu Ivan Gozali 2017-08-02 19:23:46

de java.temps & demi-ouvert

Le de java.les classes de temps qui supplantent les classes de date-heure héritées ainsi que le projet Joda-Time définissent une période de temps en utilisant l'approche semi-ouverte [) où le début est inclusive tandis que la fin est exclusive .

pour date-heure avec une fraction de seconde ceci élimine le problème d'essayer de capturer dernier moment. La dernière seconde divisible à l'infini doit être résolue, mais divers systèmes utilisent diverses granularités telles que des millisecondes, des microsecondes, des nanosecondes, ou autre chose. Avec demi-ouvert, un jour, par exemple, commence au premier moment de la journée et court jusqu'à, mais ne pas inclure, le premier moment du jour suivant. Problème résolu, pas besoin de se battre avec le dernier moment de la journée et sa fraction de seconde.

je suis venu voir les avantages d'utiliser cette approche de façon uniforme tout au long de mon code de manipulation de date-heure. Par exemple, une semaine commençant un lundi court jusqu'au lundi suivant, mais ne comprend pas. Un mois commence le 1er et court jusqu'au, mais ne comprend pas, le premier du mois suivant ignorant ainsi le défi de déterminer le nombre du dernier jour du mois incluant les 28/29 fév année bissextile.

un Autre avantage de l'utilisation cohérente de semi-Ouvert [) est l'assouplissement la charge cognitive chaque fois que je dois détecter et déchiffrer et vérifier l'approche temporelle d'un morceau de code. Dans ma propre programmation, je regarde simplement pour une mention de demi-ouvert dans un commentaire en haut et je sais instantanément comment lire ce code.

un résultat de l'utilisation cohérente de Half-Open est de réduire le risque de bogues dans mon code que ma pensée et le style d'écriture sont uniformes avec aucune chance de devenir confus sur inclusive-exclusive.

par le manière, notez que Half-Open [) signifie éviter la conjonction SQL BETWEEN car elle est toujours entièrement fermée [].

en ce qui concerne la façon de penser des clients que je sers, j'essaie de les convaincre, le cas échéant, de toujours utiliser la demi-ouverture. J'ai vu de nombreuses situations où divers gens d'affaires faisaient des suppositions erronées sur les périodes couvertes dans les rapports. Le recours systématique à la méthode semi-ouverte permet d'éviter ces ambiguïtés malheureuses. Mais si le client insiste, je note cela dans mon code et ajuste les entrées/sorties de façon à utiliser la moitié ouverte dans ma propre logique. Par exemple, ma logique utilise une semaine du lundi au lundi, mais sur un rapport soustraire un jour pour montrer le dimanche.

pour encore plus de classes représentant des périodes de temps avec l'approche semi-ouverte [), voir le ThreeTen-Extras projet pour sa classe Interval (une paire d'objets Instant ) et la classe LocalDateRange (une paire d'objets LocalDate ).


à Propos de java.time

Le de java.time framework est construit dans Java 8 et plus tard. Ces classes remplacent les anciennes héritées classes de date-heure telles que java.util.Date , Calendar , & SimpleDateFormat .

The Joda-Time project , maintenant en mode maintenance , conseille la migration vers le java.temps des classes.

pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

où obtenir le java.les classes de temps?

ThreeTen-Extra " le projet étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous trouverez peut-être des cours utiles ici, tels que Interval , YearWeek , YearQuarter , et plus .

1
répondu Basil Bourque 2017-08-03 05:41:57

je viens de passer par ce même processus de réflexion et je pense qu'il est très important que cela soit standardisé d'une manière ou d'une autre, ou du moins clarifié au moyen de ces types de questions et réponses!

dans notre cas, les plages de dates en question sont utilisées comme entrées et sorties d'un microservice; une qui, à court terme au moins, sera appelée par une application monolithique existante (c'est un projet de décomposition monolithique). Donc, je pense que le commentaire ci-dessus concernant la décision étant motivé par les exigences d'affaires est, dans notre cas, moins pertinent (parce que le direct les utilisateurs "du logiciel que nous construisons sont vraiment des personnes techniques). Si on manipulait l'entrée d'un dragueur de dattes ça pourrait être une autre histoire!

ma recommandation était que toutes les dates de début sont inclusives et toutes les dates de fin sont exclusives - donc [A,B] dans votre notation. C'était pour les raisons suivantes:

  1. nous avions convenu au préalable que toute date d'arrivée contenant des parties de temps serait rejetée (même si la valeur JSON était "2018-01-01T00:00:00") et que nous produirions toutes les dates sans heure. Par conséquent, si la date de fin est exclusive, dès que la chaîne est désérialisée dans L'objet.net DateTime, ce sera un jour sans.

  2. j'aime l'idée que les plages de dates (qui dans notre cas devrait toujours donner des jours entiers) peut peut toujours être calculé en faisant simplement dateRange = (endDateExcl - startDateIncl).TotalDays. Pas besoin d'ajouter de 1 partout!

  3. une grande partie de la validation des activités effectuée par le service consiste à vérifier que des plages de données multiples se recoupent sans discontinuité. Ceci est facile à vérifier lors de l'utilisation de [A, B) parce que chaque B devrait correspondre au précédent A. Si nous allons avec [A, B] alors nous (devs, testeurs, ingénieurs de soutien) serait souvent demander nous-mêmes "Combien de jours est en Mars de nouveau?"(e.g. [2018-03-01,2018-03-30],[2018-04-01,2018-04-30]) ou " est-ce que 2016 a une journée bissextile?"(e.g. [2016-02-01,2016-02-28],[2016-03-01,2016-03-30]).

juste pour ajouter, je recommande fortement à quiconque, quelle que soit sa décision, de suffixer explicitement tous les noms d'attribut, variables, méthodes ou autrement avec" Incl "ou" Excl " de sorte qu'il soit clair pour tout le monde sans avoir à chasser la documentation!

nous avons également recommandé que toutes les dates doivent venir dans le format ISO et que tout ce qui a un" Z " à la fin doit également être rejeté (parce qu'il est entendu que nous travaillons en jours entiers et nous ne voulons pas qu'une date soit désérialisée en un objet DateTime avec une heure de rogue (ou 23!) en raison de l'heure d'été).

note de bas de page, j'aurais probablement posté ceci comme commentaire à la réponse de Voo mais j'ai juste (tardivement!) rejoint et ont besoin de gagner ma bravo avant que je puisse le faire! ;- )

Happy rencontres x

1
répondu Hashababba 2017-11-06 11:39:06