Seite 5 von 6

Re: Date64 - Unixtime 64bit

Verfasst: 29.07.2017 10:49
von Lord
Nino hat geschrieben:...
Dieser Code stellt Berechnungen mit dem Gregorianischen Kalender an. Derjenige, der dieses Modul in einem Programm verwendet, ist letztlich selbst dafür verantwortlich dass Berechnungen im Zusammenhang seines Programms sinnvoll sind.
...
Das ist sicherlich grundsätzlich richtig.

Code: Alles auswählen

  ; == Windows ==
  ; >> Minimum: 01.01.1601 00:00:00
  ; >> Maximum: 31.12.9999 23:59:59
Dieser Hinweis im Modul kann aber Nutzer in falscher Sicherheit wiegen.
(Ich nutze nur Windows, deshalb führe ich Linux und MacOS hier nicht an.)
Es wäre sicherlich nicht falsch, an dieser Stelle auf die Besonderheiten der
Einführung des Gregorianischen Kalenders hinzuweisen.

Re: Date64 - Unixtime 64bit

Verfasst: 29.07.2017 17:28
von Sicro
Lord hat geschrieben:Darf ich darauf hinweisen, daß

Code: Alles auswählen

Debug DaysInMonth64(1700, 2)
weiterhin für große Teile Deutschlands/Europas/der Welt fehlerhafte Werte liefert?
Ich habe deinen Hinweis nicht vergessen :)

Bis jetzt sehe ich diese Anforderung jedoch für zu speziell an.

sqlite zum Beispiel bietet anscheinend auch keine Möglichkeit an, gebietsspezifische Einstellungen festzulegen:
https://www.sqlite.org/lang_datefunc.html

Die MacOS-API vereinheitlicht es anscheinend ebenfalls:
The Julian to Gregorian Transition
...
Some countries adopted the Gregorian calendar at various later times. Nevertheless, for consistency the change is modeled at the same time regardless of locale.
...
https://developer.apple.com/library/con ... 010240-SW1

Re: Date64 - Unixtime 64bit

Verfasst: 30.07.2017 10:04
von Lord
Nino hat geschrieben:...
Sicher wäre so eine Liste o. Ä. wie du vorschlägst hilfreich, aber viele Benutzer des Moduls brauchen das gar nicht, da für die Zeitberechnungen die sie durchführen immer der Gregorianische Kalender gilt.
...
... und dann immer zu falschen Werten bei der Datumdifferenz oder der Wochentagberechnung führen kann.
Nino hat geschrieben:...
Diejenigen welche die genannten zusätzlichen Informationen benötigen, müssen sich momentan halt selbst darum bemühen und Zeitdifferenzen u. Ä. ggf. entsprechend korrigieren.
Selbst die NASA ist nicht gefeit vor fehlerhaften Annahmen (z.B. Hubble).
Sicro hat geschrieben:...
Bis jetzt sehe ich diese Anforderung jedoch für zu speziell an.
...
Ich halte zumindest einen entsprechenden Hinweis im Quellcode für angebracht.

Re: Date64 - Unixtime 64bit

Verfasst: 30.07.2017 10:32
von Nino
Lord hat geschrieben:
Nino hat geschrieben:...
Sicher wäre so eine Liste o. Ä. wie du vorschlägst hilfreich, aber viele Benutzer des Moduls brauchen das gar nicht, da für die Zeitberechnungen die sie durchführen immer der Gregorianische Kalender gilt.
...
... und dann immer zu falschen Werten bei der Datumdifferenz oder der Wochentagberechnung führen kann.
Genau falsch geschlussfolgert.
Lord hat geschrieben:
Nino hat geschrieben:...
Diejenigen welche die genannten zusätzlichen Informationen benötigen, müssen sich momentan halt selbst darum bemühen und Zeitdifferenzen u. Ä. ggf. entsprechend korrigieren.
Selbst die NASA ist nicht gefeit vor fehlerhaften Annahmen (z.B. Hubble).
Und was willst du damit zum Ausdruck bringen?

Re: Date64 - Unixtime 64bit

Verfasst: 30.07.2017 20:29
von Sicro
Lord hat geschrieben:Ich halte zumindest einen entsprechenden Hinweis im Quellcode für angebracht.
Erledigt.

Die Grenzen der Datumsbereiche habe ich teilweise durch Testläufe in Erfahrung gebracht.
Der Chaos mit der Kalenderreform war mir zu diesem Zeitpunkt nicht ganz bewusst.

Wahrscheinlich werde ich doch eine Korrektur-Funktion für die unterschiedlichen Einführungszeiten des gregorianischen Kalenders einbauen.
Es wäre eine Besonderheit, die viele andere Datum-Bibliotheken nicht vorweisen können.

Aktuell möchte ich aber erst die Basis-Funktionen auf einen stabilen Stand bringen.
Siehe auch: http://www.purebasic.fr/english/viewtop ... 12&t=68837


Ich habe inzwischen bereits eine Korrektur-Funktion geschrieben, die Integration bleibt aber wie gesagt noch aus:

Code: Alles auswählen

IncludeFile "Date64[Win,Lin,Mac].pbi"
UseModule Date64

Enumeration FixTransition_Country
  #FixTransition_Country_Austria
  #FixTransition_Country_Belgium
  #FixTransition_Country_Bulgaria
  #FixTransition_Country_China
  #FixTransition_Country_Czechoslovakia
  #FixTransition_Country_Denmark
  #FixTransition_Country_Egypt
  #FixTransition_Country_Estonia
  #FixTransition_Country_Finland
  #FixTransition_Country_France
  #FixTransition_Country_Germany__Bavaria
  #FixTransition_Country_Germany__Catholic
  #FixTransition_Country_Germany__Protestant
  #FixTransition_Country_Germany__Prussia
  #FixTransition_Country_GreatBritain
  #FixTransition_Country_Greece
  #FixTransition_Country_Hungary
  #FixTransition_Country_Ireland
  #FixTransition_Country_Italy
  #FixTransition_Country_Japan
  #FixTransition_Country_Luxembourg
  #FixTransition_Country_Netherlands
  #FixTransition_Country_Norway
  #FixTransition_Country_Poland
  #FixTransition_Country_Portugal
  #FixTransition_Country_Romania
  #FixTransition_Country_SovietRussia
  #FixTransition_Country_Spain
  #FixTransition_Country_Sweden
  #FixTransition_Country_Switzerland
  #FixTransition_Country_Turkey
  #FixTransition_Country_USA__AlaskaAfterPurchase
  #FixTransition_Country_USA__Eastcoast
  #FixTransition_Country_USA__Mississippi
  #FixTransition_Country_USA__Texas_Florida_California_Nevada_NewMexico
  #FixTransition_Country_USA__Washington_Oregon
  #FixTransition_Country_UserDefined
EndEnumeration

Procedure.q FixTransitionJulianDateToGregorianDate64(Date.q, Country.i, LastDayInJulianCalendar$="", FirstDayInGregorianCalendar$="")
  ;Source of all information: http://www.kalenderlexikon.de/anzeigen.php?Eintrag=Einf%FChrungGregorKal
 
  Protected.i Year, Month, Day, Hour, Minute, Second
  Protected.q Date_LastDayInJulianCalendar, Date_FirstDayInGregorianCalendar
  
  If Country = #FixTransition_Country_UserDefined
    Date_LastDayInJulianCalendar     = ParseDate64("%mm/%dd/%yyyy", LastDayInJulianCalendar$)
    Date_FirstDayInGregorianCalendar = ParseDate64("%mm/%dd/%yyyy", FirstDayInGregorianCalendar$)
    
    If Date > Date_LastDayInJulianCalendar And Date < Date_FirstDayInGregorianCalendar
      ProcedureReturn Date_FirstDayInGregorianCalendar
    EndIf
  EndIf
 
  Year   = Year64(Date)
  Month  = Month64(Date)
  Day    = Day64(Date)
  Hour   = Hour64(Date)
  Minute = Minute64(Date)
  Second = Second64(Date)
 
  Select Country
     
    Case #FixTransition_Country_China
      ;?????????????????????????????????????
     
    Case #FixTransition_Country_USA__AlaskaAfterPurchase
      ;?????????????????????????????????????
     
    Case #FixTransition_Country_Germany__Catholic, #FixTransition_Country_Italy, #FixTransition_Country_Poland,
         #FixTransition_Country_Portugal, #FixTransition_Country_USA__Texas_Florida_California_Nevada_NewMexico,
         #FixTransition_Country_Spain
      If Year = 1582 And Month = 10 And Day > 4 And Day < 15
        Day = 15
      EndIf
     
    Case #FixTransition_Country_France, #FixTransition_Country_USA__Mississippi
      If Year = 1582 And Month = 12 And Day > 9 And Day < 20
        Day = 20
      EndIf
     
    Case #FixTransition_Country_Luxembourg
      If Year = 1582 And Month = 12 And Day > 14 And Day < 25
        Day = 25
      EndIf
     
    Case #FixTransition_Country_Belgium, #FixTransition_Country_Netherlands
      If Year = 1582 And Month = 12 And Day > 21
        Year  = 1583
        Month = 1
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_Germany__Bavaria
      If Year = 1583 And Month = 10 And Day > 5 And Day < 16
        Day = 16
      EndIf
     
    Case #FixTransition_Country_Austria, #FixTransition_Country_Czechoslovakia
      If Year = 1584 And Month = 1 And Day > 6 And Day < 17
        Day = 17
      EndIf
     
    Case #FixTransition_Country_Switzerland
      If Year = 1584 And Month = 1 And Day > 11 And Day < 22
        Day = 22
      EndIf
     
    Case #FixTransition_Country_Hungary
      If Year = 1587 And Month = 10 And Day > 21
        Month = 11
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_Germany__Prussia
      If Year = 1610 And ((Month = 8 And Day > 22) Or (Month = 9 And Day = 1))
        Month = 9
        Day   = 2
      EndIf
     
    Case #FixTransition_Country_Denmark, #FixTransition_Country_Germany__Protestant, #FixTransition_Country_Norway
      If Year = 1700 And Month = 2 And Day > 18
        Month = 3
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_GreatBritain, #FixTransition_Country_Ireland, #FixTransition_Country_USA__Eastcoast,
         #FixTransition_Country_USA__Washington_Oregon
      If Year = 1752 And Month = 9 And Day > 2 And Day < 14
        Day = 14
      EndIf
     
    Case #FixTransition_Country_Finland, #FixTransition_Country_Sweden
      If Year = 1753 And Month = 2 And Day > 17
        Month = 3
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_Japan
      If Year = 1872 And Month = 12 And Day > 19
        Year  = 1873
        Month = 1
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_Bulgaria
      If Year = 1916 And Month = 4 And Day < 14
        Day = 14
      EndIf
     
    Case #FixTransition_Country_Estonia, #FixTransition_Country_SovietRussia
      If Year = 1918 And Month = 2 And Day < 14
        Day = 14
      EndIf
     
    Case #FixTransition_Country_Romania
      If Year = 1919 And Month = 4 And Day < 14
        Day = 14
      EndIf
     
    Case #FixTransition_Country_Greece
      If Year = 1924 And Month = 3 And Day > 9 And Day < 23
        Day = 23
      EndIf
     
    Case #FixTransition_Country_Turkey
      If Year = 1925 And Month = 12 And Day > 18
        Year  = 1926
        Month = 1
        Day   = 1
      EndIf
     
    Case #FixTransition_Country_Egypt
      If Year = 1928 And Month = 9 And Day > 17
        Month = 10
        Day   = 1
      EndIf
      
  EndSelect
 
  ProcedureReturn Date64(Year, Month, Day, Hour, Minute, Second)
EndProcedure

Define.q Date, Date_fixed1, Date_fixed2

Date = Date64(1700, 2, 19)
Debug "DayInMonth: " + DaysInMonth64(Year64(Date), Month64(Date)) ; 28

Date_fixed1 = FixTransitionJulianDateToGregorianDate64(Date, #FixTransition_Country_Denmark)
Debug "DayInMonth: " + DaysInMonth64(Year64(Date_fixed1), Month64(Date_fixed1)) ; 31

Date_fixed2 = FixTransitionJulianDateToGregorianDate64(Date, #FixTransition_Country_UserDefined, "02/18/1700", "03/01/1700")
Debug "DayInMonth: " + DaysInMonth64(Year64(Date_fixed2), Month64(Date_fixed2)) ; 31
Edit: Code erweitert, um benutzerdefinierte Datumsübergänge zu ermöglichen.

Re: Date64 - Unixtime 64bit

Verfasst: 31.07.2017 09:32
von Lord
Sicro hat geschrieben:
Lord hat geschrieben:Ich halte zumindest einen entsprechenden Hinweis im Quellcode für angebracht.
Erledigt.
:allright:
Sicro hat geschrieben:...
Die Grenzen der Datumsbereiche habe ich teilweise durch Testläufe in Erfahrung gebracht.
Der Chaos mit der Kalenderreform war mir zu diesem Zeitpunkt nicht ganz bewusst.
...
Deshalb ja mein Hinweis. :wink:
Sicro hat geschrieben:...
Wahrscheinlich werde ich doch eine Korrektur-Funktion für die unterschiedlichen Einführungszeiten des gregorianischen Kalenders einbauen.
Es wäre eine Besonderheit, die viele andere Datum-Bibliotheken nicht vorweisen können.
...
Das sehe ich auch so. Man muß ja nicht Unterlassungssünden wiederholen.
Sicro hat geschrieben: ...
Ich habe inzwischen bereits eine Korrektur-Funktion geschrieben, die Integration bleibt aber wie gesagt noch aus:
Eine Alternative wäre ein zusätzlicher, optionaler Parameter, mit dem das Umstellungsdatum übergeben werden kann bzw. muß, wenn im betrachteten Zeitraum die Kalenderumstellung erfolgte. So mußt Du nicht für alle Möglichkeiten die Umstellungsdaten herausfinden und als Konstanten definieren.
Meistens ist es dann doch so, daß man ein Umstellungsdatum nicht findet oder berücksichtigt. So kannst Du aber dem Nutzer die Möglichkeit eröffnen, trotzdem das Modul zu nutzen.

Re: Date64 - Unixtime 64bit

Verfasst: 01.08.2017 13:08
von Sicro
Lord hat geschrieben:Eine Alternative wäre ein zusätzlicher, optionaler Parameter, mit dem das Umstellungsdatum übergeben werden kann bzw. muß, wenn im betrachteten Zeitraum die Kalenderumstellung erfolgte. So mußt Du nicht für alle Möglichkeiten die Umstellungsdaten herausfinden und als Konstanten definieren.
Ich habe den obigen Code um diese Funktionalität erweitert. :)

Re: Date64 - Unixtime 64bit

Verfasst: 03.08.2017 08:01
von Lord
Sicro hat geschrieben:...
Ich habe den obigen Code um diese Funktionalität erweitert. :)
:allright:

Re: Date64 - Unixtime 64bit

Verfasst: 16.08.2018 20:27
von Qnode
Hey,

hatte auch gerade das 2038er-Problem und bin dann glücklicherweise auf diesen Thread und das Code-Archiv bei Sicro gestoßen. Ein Glück dass es Euch gibt!

Gehört so ein Code nicht eigentlich auf Dauer in den Kernel von Purebasic?

Ich meine, ungültige Datumsangaben ab 2038? Wirkt zwar noch lange hin, aber nicht, wenn man Datumsangaben für die Zukunft machen muss. Ich verarbeite in einer Struktur ein Datum, dass das Ende der Gültigkeit des Datensatzes angibt (hier: Eine finanzielle, wiederkehrende Finanzbuchung, also z.B. sowas wie ein Kredit). Da ist 2038 manchmal schon ganz Nahe (bspw. bei einer Hausfinanzierung).

Oder kann man Date64 (noch) nicht zum Standard-Date machen, solange auch noch 32bit unterstützt wird?

Re: Date64 - Unixtime 64bit

Verfasst: 16.08.2018 21:09
von mk-soft
Da gibt es einige Includes...

https://www.purebasic.fr/english/viewto ... 12&t=56031
https://www.purebasic.fr/english/viewto ... 12&t=68824

Aber ich Denke das bald PB intern auf time64 umgestellt wird. Ist nur eine frage wann die Standard Libraries für alle OS time64 unterstützen.