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
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Include - Quad-Timestamp

Beitrag von STARGÅTE »

Tachchen,

aus der Frage (Hier) heraus ob es irgendwo Datumsproceduren für Quads gibt habe ich hier mal was zusammen geschrieben:

Ein paar extra Proceduren fehlen noch, werden aber kommen :

Code: Alles auswählen



; Umrechungskonstanten

#MinuteSeconds = 60
#HourMinutes = 60
#DayHours = 24
#YearDays = 365

#HourSeconds = #HourMinutes*#MinuteSeconds
#DaySeconds = #DayHours*#HourSeconds

#StartYear = 1970



; Proceduren

Procedure DayOfYearQ(Time.q)
 Protected TempDays.q = Time / #DaySeconds
 Protected TempYear.q = TempDays / #YearDays
 ; Schaltjahre
 Protected SD = ((TempYear+1)/4)-((TempYear+69)/100)+((TempYear+369)/400)
 Protected TempDayOfYear = (TempDays - SD) % #YearDays +1
 Protected Year = (TempDays - SD) / #YearDays + #StartYear
 Protected AddDay
 If #YearDays-TempDayOfYear < SD
  If Not Year % 4   : AddDay + 1 : EndIf
  If Not Year % 100 : AddDay - 1 : EndIf
  If Not Year % 400 : AddDay + 1 : EndIf
 EndIf
 ProcedureReturn TempDayOfYear+AddDay
EndProcedure

Procedure DayOfWeekQ(Time.q)
 Protected TempDays.q = Time / #DaySeconds
 Protected DayOfWeek = (TempDays+4) % 7
 ProcedureReturn DayOfWeek
EndProcedure
   

Procedure YearQ(Time.q)
 Protected TempDays = Time / #DaySeconds
 Protected TempYear = TempDays / #YearDays
 Protected SD = ((TempYear+1)/4)-((TempYear+69)/100)+((TempYear+369)/400)
 Protected Year = (TempDays - SD) / #YearDays + #StartYear
 ProcedureReturn Year
EndProcedure

Procedure MonthQ(Time.q)
 Protected Year = YearQ(Time)
 Protected DayOfYear = DayOfYearQ(Time)
 Protected AddDay
 If DayOfYear > 31+28
  If Not Year % 4   : AddDay + 1 : EndIf
  If Not Year % 100 : AddDay - 1 : EndIf
  If Not Year % 400 : AddDay + 1 : EndIf
 EndIf
 Restore MonthDays
 Protected n
 For n = 1 To 12
  Read MonthDays
  If n = 2 : MonthDays+AddDay : EndIf
  If DayOfYear < MonthDays+1
   ProcedureReturn n
  EndIf
  DayOfYear - MonthDays
 Next 
EndProcedure

Procedure DayQ(Time.q)
 Protected Year = YearQ(Time)
 Protected DayOfYear = DayOfYearQ(Time)
 Protected AddDay
 If DayOfYear > 31+28
  If Not Year % 4   : AddDay + 1 : EndIf
  If Not Year % 100 : AddDay - 1 : EndIf
  If Not Year % 400 : AddDay + 1 : EndIf
 EndIf
 Restore MonthDays
 Protected n
 For n = 1 To 12
  Read MonthDays
  If n = 2 : MonthDays+AddDay : EndIf
  If DayOfYear < MonthDays+1
   ProcedureReturn DayOfYear
  EndIf
  DayOfYear - MonthDays
 Next 
EndProcedure

Procedure HourQ(Time.q)
 Protected Hour = (Time / #HourSeconds) % #DayHours
 ProcedureReturn Hour
EndProcedure

Procedure MinuteQ(Time.q)
 Protected Minute = (Time / #MinuteSeconds) % #HourMinutes
 ProcedureReturn Minute
EndProcedure

Procedure SecondQ(Time.q)
 Protected Second = (Time) % #MinuteSeconds 
 ProcedureReturn Second
EndProcedure



Procedure.q DateQ(Year,Month,Day,Hour,Minute,Second)
 Protected Time.q
 Protected TempYear = Year-#StartYear
 Time + TempYear*365*#DaySeconds
 Protected SD = ((TempYear+1)/4)-((TempYear+69)/100)+((TempYear+369)/400)
 Time + #DaySeconds*SD
 If Month > 2 :
  If Not Year % 4   : Time + #DaySeconds : EndIf
  If Not Year % 100 : Time - #DaySeconds : EndIf
  If Not Year % 400 : Time + #DaySeconds : EndIf
 EndIf
 Restore MonthDays
 Protected n
 For n = 1 To Month-1
  Read MonthDays
  Time + #DaySeconds*MonthDays
 Next 
 Time + (Day-1)*#DaySeconds
 Time + Hour*#HourSeconds
 Time + Minute*#MinuteSeconds
 Time + Second
 ProcedureReturn Time
EndProcedure



Procedure.s FormatDateQ(Maske$, Time.q)
 Maske$ = ReplaceString(Maske$, "%yyyy", StrQ(YearQ(Time)))
 Maske$ = ReplaceString(Maske$, "%yy", Right(StrQ(YearQ(Time)  ), 2)     )
 Maske$ = ReplaceString(Maske$, "%mm",  RSet(StrQ(MonthQ(Time) ), 2, "0"))
 Maske$ = ReplaceString(Maske$, "%dd",  RSet(StrQ(DayQ(Time)   ), 2, "0"))
 Maske$ = ReplaceString(Maske$, "%hh", RSet(StrQ(HourQ(Time)  ), 2, "0"))
 Maske$ = ReplaceString(Maske$, "%ii",  RSet(StrQ(MinuteQ(Time)), 2, "0"))
 Maske$ = ReplaceString(Maske$, "%ss",  RSet(StrQ(SecondQ(Time)), 2, "0"))
 ProcedureReturn Maske$
EndProcedure



DataSection
 MonthDays:
 Data.l 31,28,31,30,31,30,31,31,30,31,30,31
EndDataSection

Beispiel:

Code: Alles auswählen

Time = Date(2008,2,29,12,00,00) 
Debug "Long: "+Str(Time) 
TimeQ.q = DateQ(2008,2,29,12,00,00) 
Debug "Quad: "+StrQ(TimeQ) 
Debug "Long: "+FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", Time)
Debug "Quad: "+FormatDateQ("%dd.%mm.%yyyy %hh:%ii:%ss", Time)
TimeQ.q = DateQ(3333,3,3,3,33,33) 
Debug "NEU: "+StrQ(TimeQ) 
Debug "NEU: "+FormatDateQ("%dd.%mm.%yyyy %hh:%ii:%ss", TimeQ)
UPDATE 1.1 : 6.8.2008 17:42
DayOfWeekQ
DayOfYearQ

UPDATE 1.2 : 6.8.2008 18:00
Protected
FormatDateQ
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
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 »

Hier noch ein kleiner Testcode für die Zuverlässigkeit des Stempels:

Code: Alles auswählen

refDate.q = 0
y.l = 1970
m.l = 1
d.l = 1
dy.l = 1
dw.l = 4
cerrors.l = 0
Repeat
  error.s = ""
  date.q = DateQ(y, m, d, 0, 0, 0)
  If date <> refDate : error + "ref" : EndIf
  If DayOfYearQ(date) <> dy : error + " dy" : EndIf
  If DayOfWeekQ(date) <> dw : error + " dw" : EndIf
  If YearQ(date) <> y : error + " y" : EndIf
  If MonthQ(date) <> m : error + " m" : EndIf
  If DayQ(date) <> d : error + " d" : EndIf
  
  If m = 12 And d = 31 ;letzter Tag im Jahr
    dy = 1
    m = 1
    d = 1
    y + 1
  Else
    dy + 1
    Select m
      Case 1, 3, 5, 7, 8, 10, 12 : md.l = 31
      Case 4, 6, 9, 11 : md.l = 30
      Case 2 : If ((Not (y % 4)) And (y % 100)) Or Not (y % 400) : md = 29 : Else : md = 28 : EndIf
    EndSelect
    If d = md ;letzter Tag im Monat
      m + 1
      d = 1
    Else
      d + 1
    EndIf
  EndIf
  dw = (dw + 1) % 7
  refDate + 86400
  
  If error
    Debug "Errors: " + error + " - " + Str(d) + "." + Str(m) + "." + Str(y)
    cerrors + 1
  EndIf
Until y = 4000
Debug "Errors: " + Str(cerrors)
Er läuft ab dem 1.1.1970 tagweise vorwärts und überprüft, ob der
Zeitstempel richtig ist, indem er ihn mit einem Referenzstempel
vergleicht, der pro Tag um 84600 erhöht wird.
Dabei wird deutlich, dass das Ergebnis ab dem 2.1.3476 nicht mehr
stimmt. Die Abkürzungen der Fehlermeldungen lassen sich leicht dem
Code entnehmen.

///Edit:
84600 durch 86400 ersetzt. <)
Zuletzt geändert von NicTheQuick am 07.08.2008 00:36, insgesamt 1-mal geändert.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Der/Die Fehler treten ab 3476 auf, weil es dort beides so viele Schalttage gab, dass wieder ein ganzes Jahr gefüllt wurde.

Das problem liegt jedoch auf "beiden" Seiten, sowohl bei DateQ() als auch bei den rück Proceduren.

Das Problem wird demnächst behoben!
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: Include - Quad-Timestamp

Beitrag von AND51 »

STARGÅTE hat geschrieben:

Code: Alles auswählen

Procedure HourQ(Time.q)
 Protected Hour = (Time / #HourSeconds) % #DayHours
 ProcedureReturn Hour
EndProcedure
Warum aus sowas nicht Macros machen?

Man kann mit Makros die PB-Nativen Proceduren überschreiben. Wenn dein Macro also Hour() heißt, wird das Makro aufgerufen, nicht die PB-Prozedur.
Du solltest außerdem Makros verwenden, wenn du sowieso nur Einzeilerprozeduren hast.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
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 »

Man muss ja nicht aus allem Makros machen.
Ich find's so okay. :allright:
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

NicTheQuick hat geschrieben:Man muss ja nicht aus allem Makros machen.
Man muss auch nicht jeden Zehner vom Boden aufheben... :wink:
Und wenn er sich dir (wie hier der Performancegewinn) noch so aufdrängt.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

und man muss nicht bei jedem furz recht haben wollen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Andreas_S
Beiträge: 787
Registriert: 14.04.2007 16:48
Wohnort: Wien Umgebung
Kontaktdaten:

Beitrag von Andreas_S »

Was ist so schlimm daran?

Man soll doch auch noch die 32 Bit Methoden verwenden können...
Viele DLLs usw. haben auch hinten die Abkürzung vom Datentyp dran.
Ist auch besser so... so kann man nähmlich auch Performance sparen:
Wenns höher als das mögliche 32 Bit Datum wird, dann verwendest du 64 Bit.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Kaeru Gaman hat geschrieben:und man muss nicht bei jedem furz recht haben wollen.
Wo hab ich denn hier auf mein Recht beharrt? :wink:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

@Nic: 84600? 86400! :mrgreen:

Gruß
Helle
Antworten