datum nach sekunden vor dem 1.1.1970 (ab den 1.1.1600)
Verfasst: 18.11.2006 22:56
vor kurzem gab es hier im forum mal zwei anfragen bezüglich umrechnung eines datum vor dem 1.1.1970 in sekunden. dazu hab ich mir ein paar gedanken gemacht und zwei proceduren geschrieben, die ein datum ausgehend vom 1.1.1600 in sekunden und wieder zurück rechnen können. das jahr 1600 hab ich deswegen gewählt, weil unser heutiger kalender erst am 15.10.1582 eingeführt wurde ich dieses datum ein bisschen "krumm" fand.
entweder ist in meinen routinen ein fehler oder der fehler liegt bei PB. als variable für die sekunden verwende ich quad und bei werte grösser 2^47 gibt es programmaufhänger. ist jetzt nicht ganz so schlimm, weil mit 2^47 sekunden kommt man schon etwas weiter als 4 millionen jahre
. deswegen hab ich auch nicht weiter nach dem problem gesucht. aber wenn jemand den fehler findet, wäre ich für eine info dankbar.
die beiden proceduren mit ein paar beispielen:
entweder ist in meinen routinen ein fehler oder der fehler liegt bei PB. als variable für die sekunden verwende ich quad und bei werte grösser 2^47 gibt es programmaufhänger. ist jetzt nicht ganz so schlimm, weil mit 2^47 sekunden kommt man schon etwas weiter als 4 millionen jahre

die beiden proceduren mit ein paar beispielen:
Code: Alles auswählen
OpenConsole()
;
; Die date-Structure muss nicht unbedingt definiert werde, nur wenn man diese auch
; verwenden möchte.
Structure date
Jahr.l
Monat.l
Tag.l
Stunde.l
Minute.l
Sekunde.l
WTag.l
EndStructure
; #################################################################################
; DateToSek wandelt ein Datum in Sekunden seit dem 1.1.1600 0 Uhr um.
; Wenn das Datum mittels eines Pointers auf die Structure date übergeben wird,
; werden Date$ und Form$ ignoriert.
; Wird das Datum per Date$ übergeben, muss in Form$ die reihen der Daten übergeben werden.
; Z.B.: Date$="18.08.1968 um 12 Uhr 25" : Form$="%TT%MM%JJ%SS%MI"
; Angegeben werden kann:
; %JJ -> Jahr
; %MM -> den Monat
; %TT -> den Tag
; %SS -> die Stunden
; %MI -> Minuten
; %SE -> Sekunden
; Werden Stunden, Minuten und Sekunden nicht angegeben, werden sie auf 0 gesetzt.
;
Procedure.q DateToSek(Date$,Form$,*Date=0)
If *Date
Jahr=PeekL(*Date)
Monat=PeekL(*Date+4)
Tag=PeekL(*Date+8)
Stunde=PeekL(*Date+12)
Minute=PeekL(*Date+16)
Sekunde=PeekL(*Date+20)
Else
Stunde=0
Minute=0
Sekunde=0
*Str.Character=@Date$
Sp=0
p=-2
Repeat
p=FindString(Form$,"%",p+3)
If p=0 : Break : EndIf
a$=Mid(Form$,p+1,2)
While *Str\c<48 Or *Str\c>57 : If *Str\c=0 : Break 2 : EndIf : *Str+1 : Sp+1 : Wend
p1=Sp
While *Str\c>47 And *Str\c<58 : *Str+1 : Sp+1 : Wend
Value=Val(Mid(Date$,p1+1,Sp-p1))
Select a$
Case "JJ" : Jahr=Value : If Jahr<1600 : Jahr+2000 : EndIf
Case "MM" : Monat=Value
Case "TT" : Tag=Value
Case "SS" : Stunde=Value
Case "MI" : Minute=Value
Case "SE" : Sekunde=Value
EndSelect
ForEver
EndIf
Monat-1
Tag-1
If Jahr>1600
For i=1600 To Jahr-1 Step 4
If ( i%4=0 And Not i%100=0 ) Or i%400=0
SchaltTage+1
EndIf
Next i
EndIf
If (( Jahr%4=0 And Not Jahr%100=0 ) Or Jahr%400=0) And Monat>1
SchaltTagJetzt=1
Else
SchaltTagJetzt=0
EndIf
Jahr-1600
MTag=PeekW(?MonatsTage+(Monat*2))
Sek.q=Jahr*365
Sek=(Sek+SchaltTage+MTag+SchaltTagJetzt+Tag)*24
Sek=(Sek+Stunde)*60
Sek=(Sek+Minute)*60
Sek+Sekunde
ProcedureReturn Sek.q
DataSection
MonatsTage:
Data.w 0,31,59,90,120,151,181,212,243,273,304,334,365
EndDataSection
EndProcedure
; #################################################################################
; SekToDate wandelt Sekunden (ausgehen vom 1.1.1600 0 Uhr) zurück in ein Datum ähnlich der
; FormatDate() Function von PureBasic.
; Z.B.: SekToDate(11632854310,"%WTAG, den %TT.%MM.%JJJJ um %SS Uhr %MI und %SE Sekunden")
; wird "Sonntag, den 18.08.1968 um 12 Uhr 25 und 10 Sekunden" zurück geben.
; Wird zusätzlich ein Pointer auf eine date-Structure mit übergeben, wird das Datum dort
; gespeichert.
; In Form$ werden folgende Zeichen entsprechende Werte zurück liefern:"
; %JJJJ -> 4 stellige Jahreszahl, z.B. 1968
; %JJ -> 2 stellige Jahreszahl, z.B. 68
; %MM -> Monat als Zahl 2 stellig
; %MMM -> Monat als abgekürztes Wort, z.B.: Aug
; %MMMM -> Monat als Wort, z.B.: August
; %TT -> Tag als 2 stellige Zahl, z.B.: 18
; %WTAG -> Wochentag, z.B.: Sonntag
; %WT -> Wochentag abgekürzt, z.B.: So
; %SS -> Stunden 2 stellig
; %MI -> Minuten 2 stellig
; %SE -> Sekunden 2 stellig
;
Procedure.s SekToDate(Sek.q,Form$,*Date=0)
#TagSek=86400
#JahrSek=365*#TagSek
#SchaltJahrSek=#JahrSek+#TagSek
Days=Sek/#TagSek
Day=(Days+6)%7
Jahr=1600
Repeat
If (( Jahr%4=0 And Not Jahr%100=0 ) Or Jahr%400=0)
If Sek-#SchaltJahrSek>=0
Jahr+1
Sek-#SchaltJahrSek
Else
Break
EndIf
Else
If Sek-#JahrSek>=0
Jahr+1
Sek-#JahrSek
Else
Break
EndIf
EndIf
ForEver
If (( Jahr%4=0 And Not Jahr%100=0 ) Or Jahr%400=0)
SchaltJahr=1
Else
SchaltJahr=0
EndIf
Tage=Sek/#TagSek
Zeit=Sek%#TagSek
For i=1 To 12
MTag=PeekW(?MonatsTageII+(i*2))
If SchaltJahr And i>1 : MTag+1 : EndIf
If MTag>Tage : Break : EndIf
vorMTag=MTag
Next i
Monat=i
Tag=Tage-vorMTag+1
Stunde=Zeit/3600 : Zeit=Zeit%3600
Minute=Zeit/60 : Sekunde=Zeit%60
If *Date
PokeL(*Date,Jahr)
PokeL(*Date+4,Monat)
PokeL(*Date+8,Tag)
PokeL(*Date+12,Stunde)
PokeL(*Date+16,Minute)
PokeL(*Date+20,Sekunde)
PokeL(*Date+24,Day)
EndIf
If Len(Form$)>3
MonatNr=Monat-1
Form$=ReplaceString(Form$,"%JJJJ",StrQ(Jahr))
Form$=ReplaceString(Form$,"%JJ",Right(StrQ(Jahr),2))
Form$=ReplaceString(Form$,"%MMMM",PeekS(?MonatStrings+MonatNr*10))
Form$=ReplaceString(Form$,"%MMM",PeekS(?MonatStrings+MonatNr*10,3))
Form$=ReplaceString(Form$,"%MM",RSet(StrQ(Monat),2,"0"))
Form$=ReplaceString(Form$,"%TT",RSet(StrQ(Tag),2,"0"))
Form$=ReplaceString(Form$,"%WTAG",PeekS(?WTagStrings+Day*11))
Form$=ReplaceString(Form$,"%WT",PeekS(?WTagStrings+Day*11,2))
Form$=ReplaceString(Form$,"%SS",RSet(StrQ(Stunde),2,"0"))
Form$=ReplaceString(Form$,"%MI",RSet(StrQ(Minute),2,"0"))
Form$=ReplaceString(Form$,"%SE",RSet(StrQ(Sekunde),2,"0"))
EndIf
ProcedureReturn Form$
DataSection
MonatsTageII:
Data.w 0,31,59,90,120,151,181,212,243,273,304,334,365
WTagStrings:
Data.c 'S','o','n','n','t','a','g',0,0,0,0,'M','o','n','t','a','g',0,0,0,0,0
Data.c 'D','i','e','n','s','t','a','g',0,0,0,'M','i','t','t','w','o','c','h',0,0,0
Data.c 'D','o','n','n','e','r','s','t','a','g',0,'F','r','e','i','t','a','g',0,0,0,0
Data.c 'S','a','m','s','t','a','g',0,0,0,0
MonatStrings:
Data.c 'J','a','n','u','a','r',0,0,0,0,'F','e','b','r','u','a','r',0,0,0
Data.c 'M','ä','r','z',0,0,0,0,0,0,'A','p','r','i','l',0,0,0,0,0
Data.c 'M','a','i',0,0,0,0,0,0,0,'J','u','n','i',0,0,0,0,0,0
Data.c 'J','u','l','i',0,0,0,0,0,0,'A','u','g','u','s','t',0,0,0,0
Data.c 'S','e','p','t','e','m','b','e','r',0,'O','k','t','o','b','e','r',0,0,0
Data.c 'N','o','v','e','m','b','e','r',0,0,'D','e','z','e','m','b','e','r',0,0
EndDataSection
EndProcedure
; #################################################################################
Sek.q=DateToSek(FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", Date()),"%TT%MM%JJ%SS%MI%SE")
;Sek.q=DateToSek("18.8.1968 12 Uhr 25 und 10 Sekunden","%TT%MM%JJ%SS%MI%SE")
PrintN("Jetziges Datum in Sekunden seit dem 01.01.1600 0 Uhr:")
PrintN(StrQ(Sek))
PrintN("")
PrintN("Und die Sekunden zurueck in ein lesbares Datum:")
PrintN(SekToDate(Sek,"%TT.%MM.%JJJJ %SS:%MI:%SE"))
PrintN("")
PrintN("oder mal anders ...")
PrintN(SekToDate(Sek,"%WTAG, den %TT. %MMMM %JJJJ um %SS Uhr %MI Minuten und %SE Sekunden",Datum.date))
PrintN("")
PrintN("Und das ganze noch bei bedarf aus der Structur date ausgelesen:")
PrintN("Jahr: "+StrQ(Datum\Jahr))
PrintN("Monat: "+StrQ(Datum\Monat))
PrintN("Tag: "+StrQ(Datum\Tag))
PrintN("Stunde: "+StrQ(Datum\Stunde))
PrintN("Minute: "+StrQ(Datum\Minute))
PrintN("Sekunde: "+StrQ(Datum\Sekunde))
PrintN("Wochentag: "+StrQ(Datum\WTag))
PrintN("")
PrintN("Uebergabe des Datums '18.08.1968 12:05:37' per Variable und Ausgabe aller moeglichen Formate ...")
Datum.date\Jahr=1968
Datum.date\Monat=8
Datum.date\Tag=18
Datum.date\Stunde=12
Datum.date\Minute=05
Datum.date\Sekunde=37
Sek.q=DateToSek("","",Datum.date)
Print("Jahreszahen: ")
PrintN(SekToDate(Sek,"%JJJJ und %JJ"))
Print("Monat: ")
PrintN(SekToDate(Sek,"%MM und %MMM und %MMMM"))
Print("Tag und Wochentag: ")
PrintN(SekToDate(Sek,"%WT oder %WTAG, den %TT."))
Print("Uhrzeit: ")
PrintN(SekToDate(Sek,"%SS Uhr %MI Minuten und %SE Sekunden"))
Input()
CloseConsole()