Moment: Kontrolle über das Exklusivitäts-/Exklusivitätsverhalten von isBetween

Erstellt am 16. Jan. 2015  ·  28Kommentare  ·  Quelle: moment/moment

Die Methode isBetween überprüft, ob ein Moment zwischen zwei anderen liegt, aber nicht, ob er gleich einer der Vergleichszeiten ist. Ich denke, wir brauchen ein inklusives Argument, obwohl es am besten ist, eine separate isBetweenInclusive-Methode zu erstellen, da das dritte Argument derzeit die Einheiten sind.

Danke

Enhancement Up-For-Grabs

Hilfreichster Kommentar

Das war ein tolles Feature und absolut notwendig!!!!

Alle 28 Kommentare

Das hätte ich auch gerne.

Ich stimme zu, dies wäre eine unglaublich nützliche Funktion. Es wäre fantastisch, zwischen inklusive und exklusivem isBetween wählen zu können oder Inklusion als boolesches Argument zu übergeben.

Es gibt tatsächlich etwas mehr Gedanken, die in diese Funktion einfließen müssen, als das, was derzeit angeboten oder vorgeschlagen wird.

In realen Szenarien ist der Startwert immer inklusive, aber der Endwert ist entweder inklusive oder exklusiv _je nach Granularität_. Insbesondere wenn der Wert eine Zeitkomponente enthält, sollte der Endwert exklusiv sein. Wenn es keine Zeitkomponente enthält, sollte es _inklusive_ sein.

Denken Sie so darüber nach. Wenn ich Sie frage, wie viele Tage es zwischen dem 1. Januar und dem 3. Januar gibt, lautet die Antwort drei Tage . Aber wenn ich Sie frage, wie viele Stunden es zwischen 1:00 und 3:00 Uhr gibt, lautet die Antwort zwei Stunden . Der Mensch tut dies von Natur aus. Es hat einen Einfluss darauf, wie wir die Dauer zwischen Intervallen messen (z. B. mit moment#diff ) und wie wir einen Wert testen, um festzustellen, ob er im Bereich liegt (z. B. mit moment#inBetween ).

Das aktuelle Verhalten von moment#isBetween ist unabhängig von der Granularität vollständig exklusiv. Dies ist nicht sehr nützlich.

Das aktuelle Verhalten von moment#diff ist am Anfang inklusive und am Ende wieder exklusiv, unabhängig von der Granularität. Dies gilt für die Zeit, der Fehler für Tage. Tatsächlich ist das Beispiel in den Dokumenten:

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

In Wirklichkeit würden die meisten Leute erwarten, dass das Ergebnis 2 Tage beträgt.

Das ultimative Problem ist, dass ein moment Objekt eine diskrete Zeiteinheit ist, aber in so vielen Fällen versuchen wir, es wie ein Datum in einem Kalender zu behandeln, und hier beginnen die Nebenwirkungen sichtbar zu werden.

Denken Sie so darüber nach. Wenn ich Sie frage, wie viele Tage es zwischen dem 1. Januar und dem 3. Januar gibt, lautet die Antwort drei Tage. Aber wenn ich Sie frage, wie viele Stunden es zwischen 1:00 und 3:00 Uhr gibt, lautet die Antwort zwei Stunden.

Ich denke, die logische (und für mich erwartete) Antwort ist "2", wenn Sie eine Datumsbibliothek nach der Anzahl der Tage zwischen "1. Januar" und "3. Januar" fragen. Der Grund dafür ist, dass ich ohne eine Zeitangabe erwarten würde, dass es zwischen "01. Januar 00:00" und "3. Januar um 00:00 Uhr" funktioniert. Wie Menschen den Unterschied in der realen Welt ausmachen, hängt wirklich vom Kontext ab, aber ich glaube nicht, dass das etwas damit zu tun hat, wie die Dinge in der Programmierwelt funktionieren.

So wird es für PHPs Carbon gemacht und ich habe nie festgestellt, dass dies ein Problem ist: https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Carbon.php#L1070 -1092

Die zweite, die wir zusammengeführt haben, ist Zwischen Ich wusste, dass einige Leute ein anderes Verhalten für Intervalle spezifizieren wollen, aber ich habe noch keinen guten Vorschlag gesehen. Letztendlich wären beide Enden separat konfigurierbar (ob sie inklusiv/exklusiv sind).

Es sollte auch abwärtskompatibel mit der aktuellen Version sein.

// proposal 1
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "[)"); // start included, end excluded

// proposal 2
m.isBetween(a, b, "+"); // both included
m.isBetween(a, b, "+-"); // start included, end excluded

Ich kann mir kein reales Szenario vorstellen, um den Start auszuschließen, daher könnte es nur ein boolesches Flag dafür sein, ob das Ende ausgeschlossen werden soll oder nicht.

Allerdings - ich mag Vorschlag 1 irgendwie, da er nahe an der richtigen ISO 31-11- Intervallnotation ist. . Ich würde beide Optionen auf beiden Seiten unterstützen wollen, wenn wir so weitermachen.

// these are essential
m.isBetween(a, b, "[]"); // both included
m.isBetween(a, b, "[)"); // start included, end excluded

// these would be rarely used, but complete the syntax
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "(]"); // start excluded, end included

Vorschlag 2 gefällt mir nicht so gut (nichts für ungut)

:+1: für Vorschlag eins.

Ich kann ehrlich gesagt keine Szenarien sehen, in denen Sie explizit eines der Enden ausschließen möchten, aber nicht beide. Selbst wenn Sie versuchen, "bis heute" anzuzeigen, können Sie moment( date ).endOf( "day" ) als Enddatum verwenden, was 23:59.59 Uhr ergibt.

Ich denke, es sollte nur ein boolesches Flag geben, um es inklusiv/exklusiv zu machen, genau wie ein "normaler" Bereich in den meisten Programmiersprachen. Halten Sie es einfach, um Verwirrung zu vermeiden - wenn Sie eine Zeit _kurz vor_ einer Endzeit wünschen, gibt es andere Möglichkeiten, sie zu erhalten.

@mckinnsb - Dieser Ansatz wird normalerweise aus zwei Gründen vermieden:

  1. Die Präzision wird wichtig. In JavaScript wäre die letztmögliche Uhrzeit eines Standardtages 23:59:59.999 , in anderen Sprachen könnte es jedoch 23:59:59 oder 23:59:59.9999999 . Wir interagieren mit Werten aus anderen Quellen über String-Parsing und -Formatierung, daher ist dies wichtig.
  2. Wenn Sie einen Bereich von 00:00:00.000 bis 23:59:59.999 , können Sie die Dauer des Bereichs nicht einfach bestimmen. Anstatt nur duration = end - start , müssen Sie jetzt etwas wie duration = end - start + epsilon tun, wobei Epsilon die minimale Genauigkeit ist, wie oben beschrieben.

Ich weise auch Ihre Aussage zurück, dass es in den meisten Programmiersprachen einen "normalen" Bereich gibt. In Wirklichkeit haben viele Programmierbereiche keine integrierten Bereichstypen. Wenn sie dies tun, ist ihr Verhalten sprachspezifisch. Es gibt kein "normal".

Siehe auch diesen Quora-Beitrag über die range Funktion in Python.

+1 für Vorschlag 1 macht die Dinge flexibel.
Meine erste Erwartung war die gleiche, dass die oberen und unteren Grenzen enthalten sein würden, genau wie ich es in SQL tun würde, X Between A AND B,
Derzeit wird daran gearbeitet x.isBetween(a, b) || x.isSame(a) || x.isSame(b)

+1

+1

+1 Vorschlag 1

+1

+1

+1

@mj1856 Ist das Standardverhalten nicht '()' ?

Is Between 2.9.0+
"Check if a moment is between two other moments, optionally looking at unit scale (minutes, hours, days, etc). **The match is exclusive.**"

isBetween bereits einen dritten optionalen Parameter. Derzeit ist die Methode als function isBetween (from, to, units) wobei units optional ist. Dieser Vorschlag führt zu einem vierten optionalen Parameter, sodass eine Implementierung zwei mögliche dritte Optionen (exklusiv/inklusive vs. Einheiten) oder alle vier verarbeiten muss.

Einige Problemumgehungen (nicht getestet):

() = x.isBetween(start, end) //vollständig exklusiv - die Standardimplementierung zu diesem Zeitpunkt
(] = x.isAfter(start) && x.isSameOrBefore(end) //links exklusiv, rechts inklusive
[) = x.isSameOrAfter(start) && x.isBefore(end) //links inklusive, rechts exklusiv
[] = !(x.isBefore(a) || x.isAfter(b)) //vollständig inklusiv

Vielleicht einfacher zu lesende Problemumgehungen gehen wie folgt:

() = x.isBetween(a,b)
(] = x.isBetween(a,b) || x.isSame(b)
[) = x.isSame(a) || x.isBetween(a,b)
[] = x.isBetween(a, b) || x.isSame(a) || x.isSame(b) // wie !(x.isBefore(a) || x.isAfter(b))

Da der 3. und 4. Parameter beide optional sind, kann es sinnvoll sein, ein Objekt zu übergeben

var options = {
   units: 'milliseconds', // 'year', 'month', etc.
   inclusive: '{)' // '{}', '()', '(}', '{)'
}
m.isBetween(start, end, options)

Wobei die Standardeinheiten Millisekunden sind und die Standardeinheit () .

Mist... ihr habt recht. Verzeihung. Umformulierung...

Markieren Sie dies zum Greifen nah. Die erwartete Verwendung wäre wie in Vorschlag 1 oben, was einen _vierten_ optionalen Parameter zulassen sollte, der an isBetween , der einen von '[]' , '[)' , '()' , '(]' . Es sollte Tests für alle vier enthalten. Der Standardwert, wenn er nicht übergeben wird, sollte der gleiche wie '()' , was auch das aktuelle Verhalten ist.

WRT die Optionen - ich habe wirklich keine Präferenz. Man könnte genauso gut null im dritten Parameter übergeben, um zum vierten zu gelangen, oder zulassen, dass eines der Elemente als dritter oder vierter Parameter übergeben wird, da wir auf bekannte Werte beschränkt sind. Das Optionsobjekt ist auch in Ordnung. Was auch immer der Implementierer für am einfachsten hält – oder zum Teufel, Sie können alle oben genannten Schritte ausführen.

Es sei denn natürlich, jemand anderes hat eine starke Meinung dazu. :)

Guter Start in PR #2943. Wir werden dies in dieser PR verfolgen. Danke!

+1

Ich hätte die Funktionalität in @darrenjennings Commit heute

Redest du davon, das in v2.13 verfügbar gemacht wurde? @rbreier
https://momentjs.com/docs/#/query/is -between/

Genau das habe ich gesucht. Ich danke dir sehr. Ich habe aktualisiert und das funktioniert perfekt für mich.

Das war ein tolles Feature und absolut notwendig!!!!

Die zweite, die wir zusammengeführt haben, ist Zwischen Ich wusste, dass einige Leute ein anderes Verhalten für Intervalle spezifizieren wollen, aber ich habe noch keinen guten Vorschlag gesehen. Letztendlich wären beide Enden separat konfigurierbar (ob sie inklusiv/exklusiv sind).

Es sollte auch abwärtskompatibel mit der aktuellen Version sein.

// proposal 1
m.isBetween(a, b, "()"); // both excluded
m.isBetween(a, b, "[)"); // start included, end excluded

// proposal 2
m.isBetween(a, b, "+"); // both included
m.isBetween(a, b, "+-"); // start included, end excluded

console.log('isBetweenFlag', moment('2010-10-19').isBetween('2010-10-19', '2010-10-25',"+"));

Wenn ich die obige Bedingung verwende, bekomme ich zuerst einen Fehler und dann wird die Bedingung fehlgeschlagen. Ich verwende eckige 6

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen