Include - Quad-Timestamp

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Test mit der V4.10 ergab: Die Addition in SplitDateQ() "*dt\year + count" ist falsch (will jetzt hier nicht mit Code hantieren). count=1, *dt\year=1969, Summe aber auch 1969 (V4.20=1970). Also inzwischen beseitigter Bug.

Gruß
Helle
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

So, ASM-Output zu Gemüte geführt. Kann mit älteren Versionen nur funktionieren, wenn in der Structure DateTime year als Quad definiert wird.

Gruß
Helle
Little John

Beitrag von Little John »

Vielen Dank für das Herausfinden der Ursache, Helle!!

Gruß, Little John
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Hab mittlerweile auch herausgefunden, dass AntiVir nur anspringt, wenn ich
den Code mit V4.00 kompiliere. Mit den Nachfolgeversionen funktioniert es
ohne Virenmeldung.

Jetzt bin ich aber auch beruhigt, dass der Fehler nicht an mir lag. Dachte
schon, ich wäre jetzt total plemplem.

Also danke Helle!
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Ja, ja, im Urlaub werde ich fleißig :mrgreen: !

Gruß
Helle
Benutzeravatar
Pelagio
Beiträge: 424
Registriert: 11.11.2004 17:52
Computerausstattung: AMD Ryzen 5 7600 6-Core Prozessor 3.80 GHz
16,0 GB Arbeitsspeicher
Windows 11 Pro Betriebssystem
Wohnort: Bremen

Beitrag von Pelagio »

Hallo PB'ler

warum ist es notwendig, ein Startdatum zu setzen, was für mich bedeutet das die Zeitrechnung erst 1970 beginnt, was für mich selber natürlich nicht schlecht ist da ich dann einige Jährchen jünger bin. Aber trotz dieses Aspektes sollte man schon korrekt mit dem Jahr 0 beginnen. Ich habe deshalb mich ein bisschen mit dem Source Stargate beschäftigt und darauf aufbauend das folgende Programm, was sicherlich noch verbesserungsfähig ist, programmiert (PB4.3).

Code: Alles auswählen

; Gregorianischer Kalender
;~~~~~~~~~~~~~~~~~~~~~~~~~~

;{- Konstanten 

#CT_Date_SekMin   = 60 
#CT_Date_MinStd   = 60 
#CT_Date_StdTag   = 24 
#CT_Date_TagJahr  = 365
#CT_Date_SekStd   = #CT_Date_MinStd * #CT_Date_SekMin 
#CT_Date_SekTag   = #CT_Date_StdTag * #CT_Date_SekStd 
#CT_Date_TagMon   = "31,28,31,30,31,30,31,31,30,31,30,31"
#CT_Date_Monate   = "Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember"
#CT_Date_Tage     = "Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag"

Enumeration
   #CT_Date_Year
   #CT_Date_Month
   #CT_Date_Week 
   #CT_Date_Day  
   #CT_Date_Hour 
   #CT_Date_Minute
   #CT_Date_Second
EndEnumeration

;} EndKonstanten

;{- Proceduren 

Procedure.l CT_DayOfYear(Zeitwert.q) 
   Protected n.b, Tage.l, Jahre.l, SchaltTag.w
   
   Tage = Zeitwert/#CT_Date_SekTag
   While (Tage>0)
      For n=1 To 12
         Tage - Val(StringField(#CT_Date_TagMon, n, ","))
      Next n
      If Not Jahre%400 Or (Not Jahre%4 And Jahre%100): SchaltTag + 1: Tage - 1: EndIf 
      Jahre + 1
   Wend
   Zeitwert = Zeitwert - (Jahre * #CT_Date_TagJahr + SchaltTag) * #CT_Date_SekTag
   Tage     = Round(Zeitwert/#CT_Date_SekTag, #PB_Round_Up) + #CT_Date_TagJahr
   ProcedureReturn Tage
EndProcedure 

Procedure.q CT_Date(Jahr.l = 0, Monat.b = 0, Tag.b = 0, Stunde.b = 0, Minute.b = 0, Sekunde.b = 0) 
   Protected n.l, ZeitWert.q, SchaltTag.w

   If (Jahr=0) And (Monat=0) And (Tag=0) And (Stunde=0) And (Minute=0) And (Sekunde=0)
      Jahr = Year(Date()): Monat = Month(Date()): Tag = Day(Date())
      Stunde = Hour(Date()): Minute = Minute(Date()): Sekunde = Second(Date())
   EndIf      
;Jahresrechnung:
   For n=0 To (Jahr-1)
      If Not n%400 Or (Not n%4 And n%100): SchaltTag + 1: EndIf
   Next n
   ZeitWert = ((Jahr-1) * #CT_Date_TagJahr + SchaltTag) * #CT_Date_SekTag

;Monatsberechnung:
   For n=1 To (Monat-1)
      Zeitwert + (Val(StringField(#CT_Date_TagMon, n, ",")) * #CT_Date_SekTag)
   Next n
   If (Monat>2) Or ((Monat=2) And (Tag=29))
      If Not Jahr%400 Or (Not Jahr%4 And Jahr%100): ZeitWert + #CT_Date_SekTag: EndIf
   EndIf
   
;Tagesberechnung: 
   Zeitwert + (Tag-1)* #CT_Date_SekTag
    
;Zeitberechnung:
   Zeitwert + Stunde * #CT_Date_SekStd 
   Zeitwert + Minute * #CT_Date_SekMin 
   Zeitwert + Sekunde
   
   ProcedureReturn Zeitwert 
EndProcedure 

Procedure.l CT_Year(Zeitwert.q) 
   Protected n.b, Tage.l, Jahr.l
   
   Tage = Zeitwert/#CT_Date_SekTag
   While (Tage>0)
      For n=1 To 12
         Tage - Val(StringField(#CT_Date_TagMon, n, ","))
      Next n
      If Not Jahr%400 Or (Not Jahr%4 And Jahr%100): Tage - 1: EndIf 
      Jahr + 1
   Wend
   ProcedureReturn Jahr
 EndProcedure 

Procedure.l CT_Month(Zeitwert.q) 
   Protected Jahr.l = CT_Year(Zeitwert) 
   Protected Tage.l = CT_DayOfYear(Zeitwert) 
   Protected Monat.b
   
   If (Tage>59) 
      If Not Jahr%400 Or (Not Jahr%4 And Jahr%100): Tage - 1: EndIf 
   EndIf 
   For Monat=1 To 12
      Tage - Val(StringField(#CT_Date_TagMon, Monat, ","))
      If (Tage<=0): Break: EndIf
   Next Monat
   ProcedureReturn Monat
EndProcedure 

Procedure.b CT_DayOfWeek(Zeitwert.q, wStart.c = #False) 
   Protected Tage.q = Zeitwert / #CT_Date_SekTag 
   Protected Wochentag.b
 
   If wStart
      WochenTag = (Tage%7)
      If Not WochenTag: WochenTag = 7: EndIf
   Else
      WochenTag = (Tage%7)+1
   EndIf 
  
   ProcedureReturn WochenTag
EndProcedure 

Procedure.l CT_Day(Zeitwert.q)
   Protected Jahr.l  = CT_Year(Zeitwert) 
   Protected Monat.l = CT_Month(Zeitwert) 
   Protected Tage.l  = CT_DayOfYear(Zeitwert) 
   
   If (Tage>59) 
      If Not Jahr%400 Or (Not Jahr%4 And Jahr%100): SchaltTag + 1: EndIf 
   EndIf
   For n=1 To (Monat-1)
      Tage - Val(StringField(#CT_Date_TagMon, n, ","))
      If (n=2): Tage - SchaltTag: EndIf
   Next n
   
   ProcedureReturn Tage
EndProcedure

Procedure.l CT_Hour(Zeitwert.q) 
   Protected Stunde.l = (Zeitwert / #CT_Date_SekStd) % #CT_Date_StdTag 
   ProcedureReturn Stunde
EndProcedure 

Procedure.l CT_Minute(Zeitwert.q) 
   Protected Minute.l = (Zeitwert / #CT_Date_SeKMin) % #CT_Date_MinStd 
   ProcedureReturn Minute
EndProcedure 

Procedure.l CT_Second(Zeitwert.q) 
   Protected Sekunde.l = (Zeitwert) % #CT_Date_SekMin 
   ProcedureReturn Sekunde 
EndProcedure 

Procedure.s CT_FormatDate(Maske.s, ZeitWert.q) 
 Maske = ReplaceString(Maske, "%yyyy",       Str(CT_Year  (Zeitwert))) 
 Maske = ReplaceString(Maske, "%yy"  , Right(Str(CT_Year  (Zeitwert)), 2)) 
 Maske = ReplaceString(Maske, "%mmmm", StringField(#CT_Date_Monate, CT_Month(Zeitwert), ",")) 
 Maske = ReplaceString(Maske, "%mm"  , RSet (Str(CT_Month (Zeitwert)), 2, "0")) 
 Maske = ReplaceString(Maske, "%dddd", StringField(#CT_Date_Tage , CT_DayOfWeek(Zeitwert), ","))
 Maske = ReplaceString(Maske, "%dd"  , RSet (Str(CT_Day   (Zeitwert)), 2, "0")) 
 Maske = ReplaceString(Maske, "%hh"  , RSet (Str(CT_Hour  (Zeitwert)), 2, "0")) 
 Maske = ReplaceString(Maske, "%ii"  , RSet (Str(CT_Minute(Zeitwert)), 2, "0")) 
 Maske = ReplaceString(Maske, "%ss"  , RSet (Str(CT_Second(Zeitwert)), 2, "0")) 
 ProcedureReturn Maske 
EndProcedure 

Procedure.q CT_ParseDate(Maske.s, ZeitWert.s)
   Protected Jahr.l, Mon.b, Tag.b, Std.b, Min.b, Sek.b
   Protected Separator.s, n.b, DZ.q
   n = FindString(Maske," ", 1) 
   Protected DMask.s = Left(Maske   , n-1)
   Protected ZMask.s = Mid (Maske   , n+1)
   n = FindString(ZeitWert," ", 1)
   Protected Datum.s = Left(ZeitWert, n-1)
   Protected Zeit.s  = Mid (ZeitWert, n+1)
   
   Separator = Mid(DMask, FindString(DMask, "%", 2)-1,1)
   For n=1 To (CountString(DMask, Separator)+1)
      Select LCase(StringField(DMask, n, Separator))
         Case "%dd"  : Tag  = Val(StringField(Datum, n, Separator))
         Case "%mm"  : Mon  = Val(StringField(Datum, n, Separator))
         Case "%yy"  : Jahr = 2000 + Val(StringField(Datum, n, Separator))
         Case "%yyyy": Jahr = Val(StringField(Datum, n, Separator))
      EndSelect
   Next n
   Separator = Mid(ZMask, FindString(ZMask, "%", 2)-1,1)
   For n=1 To (CountString(ZMask, Separator)+1)
      Select LCase(StringField(ZMask, n, Separator))
         Case "%hh": Std = Val(StringField(Zeit, n, Separator))
         Case "%ii": Min = Val(StringField(Zeit, n, Separator))
         Case "%ss": Sek = Val(StringField(Zeit, n, Separator))
      EndSelect
   Next n
   DZ = CT_Date(Jahr, Mon, Tag, Std, Min, Sek)
   
   ProcedureReturn DZ
EndProcedure

Procedure.q CT_AddDate(Datum.q, Feld.c, ZeitWert.l)
   Protected Jahr.l = CT_Year  (Datum)
   Protected Mon.b  = CT_Month (Datum)
   Protected Tag.b  = CT_Day   (Datum)
   Protected Std.b  = CT_Hour  (Datum)
   Protected Min.b  = CT_Minute(Datum)
   Protected Sek.b  = CT_Second(Datum)
         
   Select Feld
      Case #CT_Date_Year
         Jahr + Zeitwert
         Datum = CT_Date(Jahr, Mon, Tag, Std, Min, Sek) 
      Case #CT_Date_Month
         Mon + Zeitwert
         If (Mon>12): Jahr + (Mon/12): Mon % 12: EndIf
         Datum = CT_Date(Jahr, Mon, Tag, Std, Min, Sek) 
      Case #CT_Date_Week,#CT_Date_Day
         If (Feld=#CT_Date_Week): ZeitWert * 7: EndIf
         Repeat 
            If (ZeitWert>Val(StringField(#CT_Date_TagMon, Mon, ",")))
               ZeitWert - Val(StringField(#CT_Date_TagMon, Mon, ","))
               Mon + 1 
               Select Mon
                  Case 02: If Not Jahr%400 Or (Not Jahr%4 And Jahr%100): Tag - 1: EndIf       
                  Case 13: Jahr + 1: Mon = 1
               EndSelect
            Else
               Tag + ZeitWert: Break
            EndIf
         ForEver
         Datum = CT_Date(Jahr, Mon, Tag, Std, Min, Sek)
      Case #CT_Date_Hour
          Datum + (Zeitwert * #CT_Date_SekTag)
      Case #CT_Date_Minute
          Datum + (Zeitwert * #CT_Date_SekMin)
      Case #CT_Date_Second
          Datum + ZeitWert
   EndSelect
   
   ProcedureReturn Datum
EndProcedure

;} EndProceduren
Ich habe Ihn auch geprüft und keine keine Fehler gefunden, was natürlich nichts heißt.

Code: Alles auswählen

; Gregorianischer Kalender
;~~~~~~~~~~~~~~~~~~~~~~~~~~

IncludeFile "PB43Date.pbi"
;- Programm

Jahr.l   = 2009
Monat.b  = 02
Tag.b    = 07
Stund.b  = 15
Minute.b = 00
Sekund.b = 00

Datum.q = CT_Date(Jahr, Monat, Tag, Stund, Minute, Sekund)
Debug Str(Jahr)   + " = " + Str(CT_Year(Datum))
Debug Str(Monat)  + " = " + Str(CT_Month(Datum))
Debug Str(Tag)    + " = " + Str(CT_Day(Datum))
Debug Str(Stund)  + " = " + Str(CT_Hour(Datum))
Debug Str(Minute) + " = " + Str(CT_Minute(Datum))
Debug Str(Sekund) + " = " + Str(CT_Second(Datum))
Debug CT_FormatDate ("%dddd, %dd.%mmmm %yyyy %hh:%ii:%ss", Datum)
Datum = CT_AddDate(datum, #CT_Date_Week, 52)
Debug CT_FormatDate ("%dddd, %dd.%mm.%yyyy %hh:%ii:%ss", Datum)
Datum = CT_Parsedate("%dd.%mm.%yyyy %hh:%i%ss", "07.02.1959 15:00:00")
Debug CT_FormatDate ("%dddd, %dd.%mm.%yyyy %hh:%ii:%ss", Datum)
Debug CT_FormatDate ("%dddd, %dd.%mm.%yyyy %hh:%ii:%ss", CT_Date())
Debug CT_Year(CT_AddDate(CT_Date(), #CT_Date_Year, -CT_Year(Datum)))
Debug CT_Year(CT_Date())-CT_Year(Datum)
End
Ich hoffe jemand kann es gebrauchen :allright:
Ohne Zeit kein Fleiß
Auf neustem Stand zu sein ist eine Kunst die nicht jeder perfektioniert [Win11Pro; PB6.20 LTS]. :allright:
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Die Zeitrechnung ab dem Jahre 0 geht so einfach nicht, weil es zu viele
Ausnahmen und sogar ganze Jahresausfälle gab. Das liegt unter anderem
an nicht korrekten Kalendern und an Politik, Kirche und Wissenschaft, die
alle gerne anders gerechnet haben.
Unsere Zeitrechnung, wie sie jetzt ist, gibt es noch nicht so lange.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

wie wärs mit dem Chinesischen Kalender?
der müßte ja sauber fortlaufend sein seit irgendwas über 1000 BC.

auf den jüdischen Kalender würde ich mich auch nicht verlassen,
weil Jerusalem ja 70 AD von den Römern vernichtet wurde.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten