Datumsberechnung mit DateTime

Ich berechne auf meinem Mac (macOs 11.2.3) und XOJO Version 2020 Release 2.1 das Datum für meinen Kalender.
Der Palmsonntag ist dieses Jahr der 28.03.2020 - eine Woche, also 7 Tage vor Ostern. Ostern ist dieses Jahr am 04.04…

const TagInSekunden as integer = 86400

var OsterSonntag as new DateTime(2021,04,04)

var TmpDatum     as DateTime

var PalmSonntag  as DateTime = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7)

Listbox1.AddRow("Ostersonntag",OsterSonntag.SQLDate)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 7 Tage)",PalmSonntag.SQLDate)

PalmSonntag = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*6)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 6 Tage)",PalmSonntag.SQLDate)

Das Ergebnis:

Das müßte doch jetzt ein Fehler im DateTime-Objekt sein, oder?

Auch wenn deine Formeln soweit ok aussehen: Du rechnest mit Rundungswerten, wenn du auf Secondsfrom1970 gehst. Ist schließlich ein Double, kein Integer. Da mag es dann, insbesondere, da Ostersonntag zur Uhrzeit 00:00 definiert ist, zu Abweichungen kommen.

Mit
Var PalmSonntag As DateTime = OsterSonntag - New DateInterval(0, 0, 7)
(bzw. (0,0,6) für deine zweite Zeile Palmsonntag) landest du auf den korrekten Tagen.

Oh, danke. Ich habe mir DateInterval noch nie angesehen. Ich hatte nicht beachtet, daß die Sekunden Double-Werte sind.
Ich schaue mal wie ich das in meiner Berechnung der Feiertage einsetze.

Ich habe es mal kurz getestet. Es funktioniert gut.

const TagInSekunden as integer = 86400

var OsterSonntag as new DateTime(2021,04,04)

var TmpDatum     as DateTime

var PalmSonntag  as DateTime = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7)

Listbox1.AddRow("Ostersonntag",OsterSonntag.SQLDate)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 7 Tage)",PalmSonntag.SQLDate)

PalmSonntag = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*6)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 6 Tage)",PalmSonntag.SQLDate)

var MyInterval as new DateInterval(0,0,-7)

PalmSonntag = OsterSonntag + MyInterval

Listbox1.AddRow("Palmsonntag (DateInterval 0,0,-7)",PalmSonntag.SQLDate)

Das Ergebnis:

1 Like

Ein beliebter Fehlschluß, Ulrich.

Double kann einen wesentlich größeren Ganzzahlenbereich exact darstellen als Int32 - deswegen wurde es gern anstelle von Int32 benutzt um overflow errors zu vermeiden.

Int64 allerdings kann einen größeren Ganzzahlenbereich exakt darstellen als Double.

Maximaler Integerwert der exakt dargestellt werden kann:

32 bit 64 bit
Integer 2,147,483,647 9,223,372,036,854,775,807
Double 9,007,199,254,740,992 9,007,199,254,740,992
unsigned Integer 4,294,967,295 18,446,744,073,709,551,615

Und die TotalSecondsSeit1970 von 1,617,447,600.0 passen problemlos und exakt in ein Double.

Das Problem scheint die Subtraktion Double - Integer zu sein, denn wenn du im original die 7 zu 7.0 umänderst erhälst du das korekte Ergebnis:

var PalmSonntag  as DateTime = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7.0)
1 Like

Bei mir funktioniert es leider nicht. Ich habe es ausprobiert:

const TagInSekunden as double = 86400.0

var OsterSonntag as new DateTime(2021,04,04)

var TmpDatum     as DateTime

var PalmSonntag  as DateTime = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7.0)

Listbox1.AddRow("Ostersonntag",OsterSonntag.SQLDate)

Listbox1.AddRow("Palmsonntag (Ostersonntag - TagInSekunden*7.0)",PalmSonntag.SQLDate)

var MyInterval as new DateInterval(0,0,-7)

PalmSonntag = OsterSonntag + MyInterval

Listbox1.AddRow("Palmsonntag (DateInterval 0,0,-7)",PalmSonntag.SQLDate)

Das Ergebnis:

That’s not your original code but contains more changes. The code I used is from your original one, and all I changed was 7 to 7.0:

Const TagInSekunden As Integer = 86400

Var OsterSonntag As New DateTime(2021,04,04)

Var TmpDatum     As DateTime

Var PalmSonntag  As DateTime = New DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7.0)

Listbox1.AddRow("Ostersonntag",OsterSonntag.SQLDate)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 7 Tage)",PalmSonntag.SQLDate)

PalmSonntag = New DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*6)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 6 Tage)",PalmSonntag.SQLDate)

DateTime

Ich habe den Quellcode wieder zum Ausgangsbeispiel zurückgesetzt. Ich bekomme bei der Multiplikation mit “7.0” leider das falsche Ergebnis. Den Grund für das andere Ergebnis bei mir kann ich nicht erkennen.

const TagInSekunden as integer = 86400

var OsterSonntag as new DateTime(2021,04,04)

var TmpDatum     as DateTime

var PalmSonntag  as DateTime = new DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*7.0)

Listbox1.AddRow("Ostersonntag",OsterSonntag.SQLDate)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 7 Tage)",PalmSonntag.SQLDate)

PalmSonntag = New DateTime(OsterSonntag.SecondsFrom1970 - TagInSekunden*6)

Listbox1.AddRow("Palmsonntag (Ostersonntag - 6 Tage)",PalmSonntag.SQLDate)

Dann weiß ich wo es falsch läuft (und es ist nicht Double).

Welches Datum SecondsFrom1970 ist hängt davon ab wo auf der Welt man ist - und ich bin in Neuseeland. Also Locale beachten.

Ansonsten MacOS X 10.14.6, Xojo 2020 R2.1

1 Like

Aus der Dokumentation:

DateTime.SecondsFrom1970

The number of seconds since the first 1 January 1970, 00:00 GMT

SecondsFrom1970 ist also nicht Locale-fest sondern Greenwich Mean Time (aka Britische Zeit), und da dies eine Stunde vor der Deutschen Zeit ist landet man im falschen Tag. Versuch mal:

Var d1 As New DateTime(2021, 4, 4, TimeZone.Current)

Die TimeZone.Current bewirkt im Testbeispiel keine Änderung. Ich habe da jetzt die Varianten mit dem Constructor ausprobiert

Mit DateInterval komme ich auf jeden Fall zum richtigen Ergebnis.

Daher lasse ich es bei der Lösung mit DateInterval.

Vielen Dank an Ulrich und Markus!!

Ist auch die korrekte Lösung (von der ich dich nicht abhalten wollte) … :wink:

Dauerhaft oder nur vorübergehend?

Leider semi-dauerhaft (familienbedingt - meine Schwiegereltern hier werden älter, und meine Frau wollte nach 14 Jahren auch gerne mal wieder zurück in ihre Heimat - läuft aber nicht so wie sie es sich vorgestellt hat). Für einen Urlaub kann ich Neuseeland empfehlen, ansonsten nicht: Einkommen 70-80% von Deutschland, alles 50-100% teurer (es bräuchte hier wirklich einen Lidl oder Aldi), weit geringere Auswahl (vieles gibt es hier gar nicht), alles ist verdreht (Weihnachten ohne Lebkuchen im Hochsommer), und wie sehr einem die Jahreszeiten abgehen (wir sind in Auckland was heißt permanent grün und schwül) merkt man erst im zweiten Jahr.

Als Wissenschaftler ist es hier Friedhof - ganz miserabel finanziert, die Ressourcen sind einfach nicht da um wirklich was zu bewegen (es ist mehr “laßt uns auch einen Zehen ins Wasser stecken”), und da alle drei großen Branchen (Tourismus, Landwirtschaft, Erziehung) massiv von Covid betroffen sind (keine Touristen, keine Erntehelfer, keine ausländischen - vor allem Chinesische - Studenten die viel Geld bringen, zB hat Auckland University alleine 30 Millionen an Einnahmen verloren, Auckland City 1 Milliarde) kommt der dicke Hammer hier erst noch …

Nimm dazu ein gigantisches Drogenproblem (Crystal Meth das hier “P” genannt wird) und dadurch eine extrem hohe Beschaffungskriminalität (vor allem Einbrüche), starke Rassenprobleme mit Rassismus von Rechts UND von Links, gigantischer Wohnungsmangel und Wohnnot (wir saßen 20 Monate bei den Schwiegereltern im feuchten Keller bevor wir was fanden das dennoch weit über Budget war - die durchschnittlichen Hauspreise steigen jedes Jahr um etwa 20%), und daß du das permanente Gefühl hast am Arsch der Welt zu sein und komplett abgeschnitten bist (nicht mal schnell rüber nach Frankreich oder Italien oder ins sehr empfohlene Tschechien) und Schwierigkeiten mit dem Kontakthalten hast (weil wenn du wach bist schläft der Rest der Welt und umgekehrt) und ich würde jederzeit sofort nach Europa zurück.

1 Like

Oha.

Hab ich übrigens 2000 bereits vorausgesagt, sowohl die Drogenproblematik als auch das zunehmende Rassenproblem (ich war von 1999 bis 2004 schon hier). Neuseeland hat den gigantischen Fehler gemacht Rasse zu betonen, sprich zB Maori bevorzugt zu behandeln, statt zu sagen “wir kümmern uns um die Armen” (und wenn das 90% Maori sind hätte kein Schwein was dagegen gesagt).

Aber so haben Maori teilweise (die sauteure) Krankenversorgung umsonst, können Medizin studieren wenn sie 1/8 Maori sind (auch ohne den NC zu packen), etc etc - egal ob sie reich oder arm sind … was natürlich einen Keil zwischen die Rassen getrieben hat statt sie zusammenzubringen. Entsprechend haben die Maori dann ihre eigene Party gegründet (und Labour hat seine Maori-Wähler verloren) und es gab im letzten Wahlkampf Plakate mit Checkmark für “Maori” - soll man jemanden wirklich wegen seiner Rasse wählen? Ist nicht gerade DAS Rassismus?

Ein preisgekrönter Assay über ein Pilotprojekt einer Schule für Maori hat darüber geschwärmt wieviel besser die Maori-Kinder abschneiden wenn sie in ihrem eigenen Kulturkreis unterrichtet werden … und propagiert daß mehr Schulen für Maori gebaut werden! Apartheid? Wirklich? Kein Wort darüber daß das Pilotprojekt im Gegensatz zu den chronisch unterfinanzierten und überbelegten Schulen ausgezeichnet finanziert war, ausgewählte Elite-Lehrer hatte, und engagierte Eltern die sich spezifisch dafür bewerben mußten … weil DAS hat ja mit dem Lernerfolg nichts zu tun … :man_facepalming:

Ich schüttel hier praktisch jeden Tag den Kopf über was anderes in Neuseeland …

Nicht daß in Deutschland alles gut wär, aber Deutschland jammert auf einem SEHR hohen Niveau …

2 Likes