Eingabe: Anzahl der Sekunden seit dem 1. Januar des Jahres 0001
Ausgabe: Anzahl der vollen Jahre in diesem Zeitraum
Ich habe einen Algorithmus entwickelt, den ich nicht für die optimale Lösung halte. Ich denke, es sollte eine Lösung geben, die keine Schleife beinhaltet. Siehe Codeblock 1 für den Algorithmus, der A) die Anzahl der Tage bestimmt und B) iterativ 366 oder 365 abhängig von Schaltjahren von der Tagesgesamtmenge subtrahiert, während die Jahresgesamtmenge inkrementiert wird
Es ist nicht so einfach wie Dividing DayCount von 365.2425 und das Abschneiden, weil wir einen Fehlerpunkt am 1. Januar, 0002 (31536000 Sekunden / (365.2425 * 24 * 60 * 60)) = 0.99934 getroffen haben.
Irgendeine Idee über eine Methode ohne Schleifen, um Jahre aus einer Anzahl von Sekunden seit dem 1. Januar 0001 00:00 Uhr zu extrahieren?
Ich muss das herausfinden, weil ich ein Datum brauche, das in ein langes eingebettet ist (welches Sekunden speichert), so dass ich Jahre bis zu 12 Millionen mit einer Genauigkeit von einer Sekunde verfolgen kann.
Codeblock 1 - Ineffizienter Algorithmus, um Jahre von Sekunden (einschließlich Schaltjahren) zu erhalten
%Vor%Bearbeiten: Meine Lösung bestand darin, die Speicherersparnis zu umgehen, indem Sie ein Datum innerhalb von 8 Bit einbetten und jeden Wert (Sekunden bis Jahre) in separaten Ganzzahlen speichern. Dies verursacht sofortige Abrufvorgänge auf Kosten des Speichers.
Edit2: Tippfehler beim ersten Editieren (8Bits)
Wenn Sie Genauigkeit für die Sekunde benötigen, benötigen Sie wahrscheinlich ein kommerzielles Datetime-Paket. es ist einfach zu komplex, um es mit einem einfachen Algorithmus genau zu machen. Zum Beispiel:
Aufgrund dieser und weiterer Komplikationen ist es besser, wenn Sie den Code nicht selbst schreiben, es sei denn, Sie können die Einschränkung, dass Sie Genauigkeit in der Sekunde über 12 Millionen Jahre benötigen, lockern.
>"4. Oktober 1582 - Die hl. Teresa von Ávila stirbt. Sie ist am 15. Oktober begraben."
Wikipeda hat einen Artikel über Julian Date mit einem Algorithmus, den Sie an Ihre Bedürfnisse anpassen können.
>Sie brauchen keine Schleife, berechnen Sie die Sekunden vom 1. Januar 0001 bis zum Beginn der Unix-Epoche (1. Jan. 1970 00:00:00) und speichern Sie sie irgendwo. Dann subtrahiere es von deiner Eingabe und benutze dann ein beliebiges Werkzeug, um den Unix-Zeitstempel (Sekunden vom 1. Januar 1970) in Jahre zu konvertieren und dann 1970 hinzuzufügen. Ich kenne nicht viel VB-Programmierung, um eine detaillierte Anleitung zu veröffentlichen.
Im Folgenden wird vorausgesetzt, dass der Gregorianische Kalender für die kommenden fünfhundertvierundachtzig Milliarden Jahre in Kraft bleibt. Bereite dich auf Enttäuschungen vor. Der Kalender wird möglicherweise verschrottet, wenn unsere Sonne sich zu erweitern beginnt, wodurch sich die Umlaufbahn der Erde und die Dauer des Jahres verändern. Es ist sehr wahrscheinlich, dass noch etwas anderes angenommen wird, wenn die Erde siebeneinhalb Milliarden Jahre in die Sonne fällt von jetzt an.
Nebenbei möchte ich noch nicht einmal versuchen, Daten vor der Verabschiedung des Gregorianischen Kalenders zu behandeln. Ich gebe einfach die Anzahl der Tage zurück, an denen das Datum vor dem 15. Oktober 1582 aufgetreten ist, und die Notwendigkeit, diese Art von Rückgabewert auszudrücken, ist der einzige Grund, warum die GetDateFromSerial
-Funktion einen asString
-Parameter hat.
Ich weiß, dass diese Frage jetzt alt ist, aber ich sehe solche oft und es gab keine einfachen Antworten hier drin.
Meine Lösung verwendet einen alten Trick, zwei Daten so zu schreiben, als ob sie Zahlen wären (z. B. "12. Dezember 2013" wie 20131212) und dann eins voneinander zu subtrahieren und die letzten vier Ziffern zu verwerfen. Ich habe meine Implementierung in F # ausgegraben, Sie können sie in LinqPad einfügen, um die Antworten zu überprüfen. Berücksichtigt Schaltjahre usw. auch:
%Vor%Bitte beachten Sie, dass dies ziemlich naiv ist: Es werden keine Zeitzonen oder historische Zeitzonenänderungen berücksichtigt, die über diejenigen hinausgehen, die bereits von der DateTime-Klasse von .NET behandelt werden. Die eigentliche Grunt-Arbeit wird von der DateTime.AddSeconds-Methode erledigt. Hoffe, das hilft.