Seite 4 von 4

Verfasst: 11.08.2008 10:32
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

Verfasst: 11.08.2008 11:16
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

Verfasst: 11.08.2008 11:31
von Little John
Vielen Dank für das Herausfinden der Ursache, Helle!!

Gruß, Little John

Verfasst: 11.08.2008 11:41
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!

Verfasst: 11.08.2008 12:00
von Helle
Ja, ja, im Urlaub werde ich fleißig :mrgreen: !

Gruß
Helle

Verfasst: 27.10.2008 16:12
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:

Verfasst: 27.10.2008 16:21
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.

Verfasst: 27.10.2008 16:58
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.