Wie berechne ich mit Javascript den Tag des Jahres von 1 bis 366? Beispielsweise:
- Der 3. Januar sollte der 3. Januar sein .
- Der 1. Februar sollte 32 sein .
javascript
Kirk Woll
quelle
quelle
var days = new Date().getFullYear() % 4 == 0 ? 366 : 365;
Antworten:
Folgende OP-Bearbeitung:
Bearbeiten: Der obige Code schlägt fehl, wenn
now
ein Datum zwischen dem 26. März und dem 29. Oktober liegt undnow
die Zeit vor 1 Uhr morgens liegt (z. B. 00:59:59). Dies liegt daran, dass der Code die Sommerzeit nicht berücksichtigt. Sie sollten dies kompensieren :quelle
Math.floor
gab mir durchweg ein Ergebnis von 1 Tag weniger als erwartet nach einem bestimmten Tag im April.Math.ceil
hat wie erwartet funktioniert, aber ich habe gesehen, dass empfohlen wird, dass SieMath.round
anstelle von beiden verwenden.new Date(2014, 0, 1)
, und nichtnew Date(2014, 0, 0)
wie Sie hier haben. Ist das beabsichtigt? Vielleicht ist es das, was dafür verantwortlich ist, dass wir eines Tages frei sind undnew Date(2014, 0, 0)
zurückkehren werden12/31/2013
..setUTCHours
undDate.UTC()
für eine zuverlässigere Lösung.ceil
anstattfloor
, dies gibt Ihnen ein Nummerierungssystem, bei dem der 1. Januar = 1. Wenn Sie den 1. Januar = 0 möchten (wiefloor
es Ihnen geben würde), subtrahieren Sie einfach 1 von Ihrem Endergebnis.var diff = now - start + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
Dies funktioniert bei Änderungen der Sommerzeit in allen Ländern (der oben genannte "Mittag" funktioniert in Australien nicht):
quelle
getDay()
muss in geändert werdengetDate()
. Ersteres gibt den Wochentag zurück (0 = Sonntag..6 = Samstag), nicht den Tag.Ich finde es sehr interessant, dass niemand UTC in Betracht gezogen hat, da es nicht der Sommerzeit unterliegt. Daher schlage ich Folgendes vor:
Sie können es folgendermaßen testen:
Welche Ergebnisse für das Schaltjahr 2016 (überprüft mit http://www.epochconverter.com/days/2016 ):
quelle
function doyToDate(doy, year) { return new Date(year, 0, doy); }
quelle
Glücklicherweise gibt diese Frage nicht an, ob die Nummer des aktuellen Tages erforderlich ist, sodass Platz für diese Antwort bleibt.
Auch einige Antworten (auch auf andere Fragen) hatten Schaltjahrprobleme oder verwendeten das Date-Objekt. Obwohl die javascript
Date object
etwa 285.616 Jahre Abdeckungen (100.000.000 Tage) auf beiden Seiten vom 1. Januar 1970 wurde ich mit allen möglichen unerwarteten Zeitpunkt satt Inkonsistenzen in verschiedenen Browsern (insbesondere die Jahre 0 bis 99). Ich war auch neugierig, wie man es berechnet.So habe ich eine einfache und vor allem schrieb kleinen Algorithmus zur Berechnung der korrekten ( proleptische Gregorian / astronomisches / ISO 8601: 2004 (Abschnitt 4.3.2.1), so Jahr
0
existiert und ein Schaltjahr und Tag des Jahres negative Jahre unterstützt werden ) basierend auf Jahr , Monat und Tag .Beachten Sie, dass in der
AD/BC
Notation das Jahr 0 AD / BC nicht existiert: Stattdessen1 BC
ist das Jahr das Schaltjahr! WENN Sie die BC-Notation berücksichtigen müssen, subtrahieren Sie einfach zuerst ein Jahr vom (ansonsten positiven) Jahreswert !!Ich habe (für Javascript) den Kurzschluss-Bitmasken-Modulo-Schaltjahr-Algorithmus modifiziert und mir eine magische Zahl ausgedacht , um eine bitweise Suche nach Offsets durchzuführen (ohne Jan und Februar, sodass 10 * 3 Bits benötigt werden (30 Bits sind weniger als) 31 Bit, damit wir sicher ein anderes Zeichen in der Bitverschiebung speichern können, anstatt
>>>
)).Beachten Sie, dass weder Monat noch Tag sein dürfen
0
. Das bedeutet , dass , wenn Sie diese Gleichung müssen nur für den aktuellen Tag (Fütterung es mit.getMonth()
) brauchen Sie nur das entfernen--
aus--m
.Beachten Sie, dass dies ein gültiges Datum voraussetzt (obwohl die Fehlerprüfung nur einige Zeichen mehr ist).
Hier ist die Version mit korrekter Bereichsvalidierung.
Wieder eine Zeile, aber ich habe sie zur besseren Lesbarkeit (und folgenden Erläuterungen) in drei Zeilen aufgeteilt.
Die letzte Zeile ist identisch mit der obigen Funktion, jedoch wird der (identische) Schaltjahr-Algorithmus in einen vorherigen Kurzschlussabschnitt (vor der Berechnung der Tageszahl) verschoben, da auch bekannt sein muss, wie viele Tage ein Monat in einem hat gegebenes (Schalt-) Jahr.
Die mittlere Zeile berechnet die korrekte Versatzzahl (für die maximale Anzahl von Tagen) für einen bestimmten Monat in einem bestimmten (Schalt-) Jahr unter Verwendung einer anderen magischen Zahl: Da
31-28=3
und3
nur 2 Bits und dann12*2=24
Bits sind, können wir alle 12 Monate speichern. Da die Addition schneller als die Subtraktion sein kann, addieren wir den Offset (anstatt ihn zu subtrahieren31
). Um einen Schaltjahr-Entscheidungszweig für Februar zu vermeiden, ändern wir diese magische Suchnummer im laufenden Betrieb.Damit bleibt uns die (ziemlich offensichtliche) erste Zeile: Sie überprüft, ob Monat und Datum innerhalb der gültigen Grenzen liegen, und stellt sicher, dass bei einem
false
Bereichsfehler ein Rückgabewert angezeigt wird (beachten Sie, dass diese Funktion auch 0 nicht zurückgeben kann, da 1 Januar 0000 ist noch Tag 1.) und bietet eine einfache Fehlerprüfung :if(r=dayNo(/*y, m, d*/)){}
.Wenn auf diese Weise verwendet werden (wo Monat und Tag können nicht sein
0
), dann kann man ändern ,--m>=0 && m<12
umm>0 && --m<12
(Speicher ein anderes Zeichen).Der Grund , warum ich das Snippet getippt in seiner derzeitigen Form ist , dass für die Monatswerte-0 basiert, man muss nur das Entfernen
--
von--m
.Extra:
Beachten Sie, dass Sie den Algorithmus für diesen Tag pro Monat nicht verwenden, wenn Sie nur den maximalen Tag pro Monat benötigen. In diesem Fall gibt es einen effizienteren Algorithmus (da wir nur leepYear benötigen, wenn der Monat Februar ist). Als Antwort auf diese Frage habe ich Folgendes gepostet: Wie lässt sich die Anzahl der Tage in einem Monat am besten mit Javascript bestimmen? .
quelle
Date.prototype.dayNo = function(){ var y = this.getFullYear(); var m = this.getMonth()+1; var d = this.getDate(); return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d; };
+1
aus ,this.getMonth()+1
wenn Sie entfernen die--
aus--m
. EDIT Also, ich würde (für eine Bibliothek) tun:Date.prototype.dayNo = function(){ var y=this.getFullYear(), m=this.getMonth(); return m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+this.getDate(); };
2^31 - 2016
js in den nächsten Jahren wahrscheinlich etwas veraltet sein wird.:)
Aber bis dahin wird es zumindest vorhersehbare und konsistente Ergebnisse liefern, haha. EDIT , nur aus theoretischen Gründen, mit dem langsameren konventionellen All-Modulo-Algo für Leapyear kann der Bereich auf 2 ^ 53 erweitert werden. Der Monatssuchalgo ist nicht der begrenzende Faktor.Wenn Sie das Rad nicht neu erfinden möchten, können Sie die hervorragende Bibliothek date-fns (node.js) verwenden:
quelle
Nun, wenn ich Sie richtig verstehe, wollen Sie 366 in einem Schaltjahr, sonst 365, oder? Ein Jahr ist ein Schaltjahr, wenn es gleichmäßig durch 4 teilbar ist, aber nicht durch 100, es sei denn, es ist auch durch 400 teilbar:
Nach dem Update bearbeiten:
In diesem Fall glaube ich nicht, dass es eine eingebaute Methode gibt. Sie müssen dies tun:
(Ja, das habe ich tatsächlich gemacht, ohne zu kopieren oder einzufügen. Wenn es einen einfachen Weg gibt, werde ich verrückt sein.)
quelle
:)
Dies ist eine einfache Methode, um den aktuellen Tag im Jahr zu ermitteln, und es sollten problemlos Schaltjahre berücksichtigt werden:
Javascript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0))/1000/60/60/24);
Javascript in Google Apps Script:
Math.round((new Date().setHours(23) - new Date(new Date().getYear(), 0, 1, 0, 0, 0))/1000/60/60/24);
Die Hauptaktion dieses Codes besteht darin, die Anzahl der im aktuellen Jahr verstrichenen Millisekunden zu ermitteln und diese Zahl dann in Tage umzuwandeln. Die Anzahl der im aktuellen Jahr verstrichenen Millisekunden kann ermittelt werden, indem die Anzahl der Millisekunden der ersten Sekunde des ersten Tages des aktuellen Jahres, die mit
new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0)
(Javascript) odernew Date(new Date().getYear(), 0, 1, 0, 0, 0)
(Google Apps Script) ermittelt wurde, von den Millisekunden abgezogen wird der 23. Stunde des aktuellen Tages, die mit gefunden wurdenew Date().setHours(23)
. Mit der Einstellung des aktuellen Datums auf die 23. Stunde soll sichergestellt werden, dass der Tag des Jahres korrekt gerundet wirdMath.round()
.Sobald Sie die Anzahl der Millisekunden des aktuellen Jahres haben, können Sie diese Zeit in Tage umrechnen, indem Sie durch 1000 dividieren, um Millisekunden in Sekunden umzuwandeln, dann durch 60 teilen, um Sekunden in Minuten umzuwandeln, und dann durch 60 teilen, um Minuten in Stunden umzurechnen. und schließlich durch 24 teilen, um Stunden in Tage umzuwandeln.
Hinweis: Dieser Beitrag wurde bearbeitet, um Unterschiede zwischen JavaScript und JavaScript zu berücksichtigen, die in Google Apps Script implementiert sind. Außerdem wurde mehr Kontext für die Antwort hinzugefügt.
quelle
.setHours
Methode für das erste Datumsobjekt verwendet und die Uhrzeit mit dem zweiten Datumsobjekt angegeben habe, wirkt sich eine Änderung von 1 Stunde gegenüber der Sommerzeit nicht auf die Zeiten der in dieser Berechnung verwendeten Datumsobjekte aus.Ich denke, das ist einfacher:
quelle
Diese Methode berücksichtigt Zeitzonenprobleme und Sommerzeit
(nahm von hier )
Siehe auch diese Geige
quelle
Math.round ((neues Datum (). SetHours (23) - neues Datum (neues Datum (). GetFullYear (), 0, 1, 0, 0, 0)) / 1000/86400);
optimiert die Antwort weiter.
Darüber hinaus kann durch Ändern von setHours (23) oder der vorletzten Null später auf einen anderen Wert ein Tag des Jahres in Bezug auf eine andere Zeitzone bereitgestellt werden. Zum Beispiel, um eine in Amerika befindliche Ressource aus Europa abzurufen.
quelle
Das ist meine Lösung
quelle
Ich habe eine lesbare erstellt, die den Trick sehr schnell erledigt und JS-Datumsobjekte mit unterschiedlichen Zeitzonen verarbeitet.
Ich habe einige Testfälle für Zeitzonen, Sommerzeit, Schaltsekunden und Schaltjahre aufgenommen.
PS ECMA-262 ignoriert im Gegensatz zu UTC Schaltsekunden. Wenn Sie dies in eine Sprache konvertieren, die echte UTC verwendet, können Sie einfach 1 hinzufügen
oneDay
.quelle
Ich möchte eine Lösung bereitstellen, die Berechnungen durchführt und die Tage für jeden vorherigen Monat hinzufügt:
Auf diese Weise müssen Sie die Details der Schaltjahre und der Sommerzeit nicht verwalten.
quelle
Eine Alternative mit UTC-Zeitstempeln. Wie andere angemerkt haben, ist der Tag, an dem der 1. Monat angezeigt wird, 1 statt 0. Der Monat beginnt jedoch bei 0.
quelle
Sie können Parameter als Datumsnummer in der
setDate
Funktion übergeben:quelle
Dies kann für diejenigen nützlich sein, die den Tag des Jahres als Zeichenfolge benötigen und über eine jQuery-Benutzeroberfläche verfügen.
Sie können jQuery UI Datepicker verwenden:
Darunter funktioniert es genauso wie bei einigen der bereits erwähnten Antworten (
(date_ms - first_date_of_year_ms) / ms_per_day
):quelle
Für diejenigen unter uns, die eine schnelle alternative Lösung suchen.
Die Größe der Monate des Jahres und die Art und Weise, wie Schaltjahre funktionieren, passen perfekt dazu, unsere Zeit mit der Sonne in Einklang zu halten. Heck, es funktioniert so perfekt, dass wir nur hier und da nur Sekunden einstellen . Unser derzeitiges System der Schaltjahre ist seit dem 24. Februar 1582 in Kraft in Kraft und wird wahrscheinlich auf absehbare Zeit in Kraft bleiben.
Die Sommerzeit kann sich jedoch stark ändern. Es kann sein, dass in 20 Jahren ein Land die Zeit um einen ganzen Tag oder ein anderes Extrem für die Sommerzeit ausgleicht. Ein ganzer DST-Tag wird mit ziemlicher Sicherheit nie stattfinden, aber die DST ist dennoch sehr in der Luft und unentschlossen. Somit ist die obige Lösung nicht nur sehr, sehr schnell, sondern auch zukunftssicher.
Das obige Code-Snippet läuft sehr schnell. Mein Computer kann 65536 Daten in ~ 52 ms in Chrome verarbeiten.
quelle
quelle
Dies ist eine Lösung, die die problematischen Probleme mit Datumsobjekten und Zeitzonen vermeidet. Es ist erforderlich, dass Ihr Eingabedatum das Format "JJJJ-TT-MM" hat. Wenn Sie das Format ändern möchten, ändern Sie die Funktion date_str_to_parts:
quelle
Ich mache mir immer Sorgen, wenn ich Mathematik mit Datumsfunktionen mische (es ist so leicht, ein Schaltjahr und andere Details zu übersehen). Angenommen, Sie haben:
Ich würde vorschlagen, Folgendes zu verwenden: Tage werden gespeichert in
day
:Ich kann keinen Grund erkennen, warum dies nicht gut funktionieren würde (und ich wäre nicht so besorgt über die wenigen Iterationen, da dies nicht so intensiv genutzt wird).
quelle
/ * BENUTZEN SIE DIESES SCRIPT * /
quelle