Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Datumsangabe ab dem Jahr 0 - gibt es eine Konvention? (https://www.delphipraxis.net/196603-datumsangabe-ab-dem-jahr-0-gibt-es-eine-konvention.html)

messie 3. Jun 2018 11:20

Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Moin,

ich habe hier Daten mit einem Datumsstempel ab dem 0.Januar des Jahres 0.
Das kannte ich bisher nicht. Ist eine solche Datumskonvention bekannt und gibt es Algorithmen zur Berechnung?

Grüße, Messie

Bernhard Geyer 3. Jun 2018 11:26

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403740)
... ab dem 0.Januar ...

Den 0. Januar gibts doch gar nicht....
Und nach Christlicher Zeitrechnung auch kein Jahr 0.


Delphis TDateTime kann auch Datumswerte < 30. Dezember 1899 speichern. Und zwar als negative Double-Werte

http://docwiki.embarcadero.com/Libra...stem.TDateTime

Einfach mal

Delphi-Quellcode:
MyDate := ISO8601ToDate('0001-01-01') // bzw '0000-01-01'
aufrufen

p80286 3. Jun 2018 12:01

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403740)
ich habe hier Daten mit einem Datumsstempel ab dem 0.Januar des Jahres 0.

Das klingt aber sehr nach einem Dummy. handelt es sich um ein Binäres Format oder ist das Text z.B 0000-01-00?

Gruß
K-H

Alallart 3. Jun 2018 12:29

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Natürlich gibt es den Zeitpunkt 0, nur ist es kein 0'ter Januar. Aber das Jahr und den Tag 0 muss es geben, denn alles muss ja anfangen. Eine Sekunde später ist es aber der 1. Januar.

Das Problem wäre sonst, dass ohne dem Jahr 0 zwischen dem Jahr 5 v. Chr. und dem Jahr 5 n. Chr. nur 9 Jahre wären.

Bernhard Geyer 3. Jun 2018 12:52

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von Alallart (Beitrag 1403744)
Natürlich gibt es den Zeitpunkt 0, nur ist es kein 0'ter Januar. Aber das Jahr und den Tag 0 muss es geben, denn alles muss ja anfangen. Eine Sekunde später ist es aber der 1. Januar.

Das Problem wäre sonst, dass ohne dem Jahr 0 zwischen dem Jahr 5 v. Chr. und dem Jahr 5 n. Chr. nur 9 Jahre wären.

Genau das Problem gibt es aber mit der Christlichen Zeitrechnung das es kein Jahr 0 gibt:

https://de.wikipedia.org/wiki/Christ...esz%C3%A4hlung

In der astronomischen Zeitrechnung gibt es das schon, deshalb rechnen wir damit:

https://de.wikipedia.org/wiki/Jahr_null

MicMic 3. Jun 2018 21:32

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von Alallart (Beitrag 1403744)
... Eine Sekunde später ist es aber der 1. Januar.


Eine Femtosekunde später wäre das schon :)
Gerade im Internet entdeckt. Vorher selbst noch nie gehört.

Michael

messie 4. Jun 2018 08:58

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von p80286 (Beitrag 1403742)
Zitat:

Zitat von messie (Beitrag 1403740)
ich habe hier Daten mit einem Datumsstempel ab dem 0.Januar des Jahres 0.

Das klingt aber sehr nach einem Dummy. handelt es sich um ein Binäres Format oder ist das Text z.B 0000-01-00?

Gruß
K-H

Nee, das ist tatsächlich ein Integer, z.B. 736870. Wenn ich das vereinfacht mit 365.25 Tagen verheirate, komme ich etwa auf Mitte 2017. Das käme ungefähr hin, die Daten sind aus dem letzten Jahr. Das würde ich dann aber nicht als Konvention betrachten.

Grüße, Messie

himitsu 4. Jun 2018 12:12

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Das Jahr 0 gibt es nicht, in unserem Kalender (Gregorianisch und auch nicht im Julianischen).

xxx. bis 1. Jahr vor dem einen Typen
1. bis xxx. Jahr nach dem einen Typen

Sherlock 4. Jun 2018 14:35

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Und vor dem 1. Januar kommt immer der 31. Dezember, und nicht der 0. Januar.
Hab das grad nochmal in meinem Kalender überprüft....
:stupid:

Sherlock

messie 4. Jun 2018 20:31

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von Sherlock (Beitrag 1403847)
Und vor dem 1. Januar kommt immer der 31. Dezember, und nicht der 0. Januar.
Hab das grad nochmal in meinem Kalender überprüft....
:stupid:

Sherlock

Dein Kalender ist auch nicht von MatLab... ich hab's rausgefunden: Matlab datenum
Wenn ich von 365.25 Tagen pro Jahr ausgehe, kommen auch sinnvolle Werte raus.

Grüße, Messie

KodeZwerg 4. Jun 2018 20:42

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403740)
Ist eine solche Datumskonvention bekannt und gibt es Algorithmen zur Berechnung?

Irgendeine Konvention fand bereits statt, da Du ja
Zitat:

Zitat von messie (Beitrag 1403740)
ich habe hier Daten mit einem Datumsstempel ab dem 0.Januar des Jahres 0.

bekommst. Was soll jetzt noch Berechnet werden? Ob es den 0.Januar im Jahr 0 existiert hat?

p80286 4. Jun 2018 21:53

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Ich nehme an, die Frage lautet "kennt jemand einen Zeitstempel der nur Tage zählt (und ein 32bit-Integer ist)?"

Gruß
K-H

messie 5. Jun 2018 10:00

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Moin,

nein, die Frage lautete: wie wird mit dem 29.4. des Jahres 1415 umgegangen? Gibt es Algorithmen, die die Ungenauigkeit der 365.25 Tage ausgleichen?

Code:
A serial date number represents the whole and fractional number of days from a fixed, preset date (January 0, 0000) in the proleptic ISO calendar
Mal sehen, ob ich dazu etwas finde.

Grüße, Messie

Amateurprofi 5. Jun 2018 10:38

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von p80286 (Beitrag 1403891)
Ich nehme an, die Frage lautet "kennt jemand einen Zeitstempel der nur Tage zählt (und ein 32bit-Integer ist)?"

Gruß
K-H

Ja, ich kenne solch ein System.
Das wurde in den 70er Jahren von Texas Instruments benutzt.
Allerdings basiert das System auf dem 01.01.0000
Hier sind die Funktionen/Prozeduren die ich mal dazu geschrieben habe und oft und gern benutze.
Zum Beispiel hier https://www.delphipraxis.net/134885-rechenprogramm.html


Delphi-Quellcode:
interface

FUNCTION DayNum(Year,Month,Day:NativeInt):NativeInt;
FUNCTION DayOfWeek(Year,Month,Day:NativeInt):NativeInt; overload;
FUNCTION DayOfWeek(DayNumber:NativeInt):NativeInt; overload;
FUNCTION LeapYear(Year:NativeInt):Boolean;
FUNCTION DaysInMonth(Year,Month:NativeInt):NativeInt;
FUNCTION DaysInYear(Year:NativeInt):NativeInt;
FUNCTION WeeksInYear(Year:NativeInt):NativeInt;
PROCEDURE WeekNum(Year,Month,Day:NativeInt; var week,yearofweek:NativeInt);
PROCEDURE DayNumToDate(dn:NativeInt; var Year, Month, Day:NativeInt);
FUNCTION EasterSunday(Year:NativeInt; var Month,Day:NativeInt):NativeInt;
FUNCTION FirstAdvent(Year:NativeInt; var Month,Day:NativeInt):NativeInt;

implementation

{------------------------------------------------------------------------------}
{ DayNum                                                                      }
{ Gibt die Anzahl der Tage zurück, die seit dem fiktiven Datum 01.01.0000      }
{ vergangen sind.                                                             }
{ 01.01.0000 würde 0 ergeben                                                  }
{ 01.01.0001 würde 366 ergeben (0000 wäre ein Schaltjahr)                     }
{------------------------------------------------------------------------------}
FUNCTION DayNum(Year,Month,Day:NativeInt):NativeInt;
begin
   Result:=Year*365+Day+31*(Month-1);
   If Month>2 then Dec(Result,(23+4*Month) div 10)
      else if Year<>0 then Dec(Year)
         else Dec(Result);
   Inc(Result,Year div 4 - Year div 100 + Year div 400);
end;

{------------------------------------------------------------------------------}
{  DayOfWeek (Year, Month, Day)                                               }
{  Gibt den Wochentag für ein Datum zurück                                    }
{  0=Montag, 1=Dienstag... 6=Sonntag                                          }
{------------------------------------------------------------------------------}
FUNCTION DayOfWeek(Year,Month,Day:NativeInt):NativeInt;
begin
   Result:=(5+DayNum(Year,Month,Day)) mod 7;
end;

{------------------------------------------------------------------------------}
{  DayOfWeek (DayNumber)                                                      }
{  Gibt den Wochentag für eine Tagnummer zurück                               }
{  0=Montag, 1=Dienstag... 6=Sonntag                                          }
{------------------------------------------------------------------------------}
FUNCTION DayOfWeek(DayNumber:NativeInt):NativeInt;
begin
   Result:=(5+DayNumber) mod 7;
end;

{------------------------------------------------------------------------------}
{ LeapYear                                                                    }
{ Gibt True zurück, wenn year ein Schaltjahr ist                              }
{------------------------------------------------------------------------------}
FUNCTION LeapYear(Year:NativeInt):Boolean;
begin
   result:=(Year mod 4=0) and (Year mod 100<>0) or (Year mod 400=0);
end;

{------------------------------------------------------------------------------}
{ DaysInMonth                                                                 }
{ Gibt die Anzahl der Tage in Month in Year zurück                            }
{------------------------------------------------------------------------------}
FUNCTION DaysInMonth(Year,Month:NativeInt):NativeInt;
const DIM:array[1..12] of byte=(31,28,31,30,31,30,31,31,30,31,30,31);
begin
   if (Month=2) and LeapYear(Year) then Result:=29 else Result:=DIM[Month];
end;

{------------------------------------------------------------------------------}
{ DaysInYear                                                                  }
{ Gibt die Anzahl Tage in year zurück                                         }
{------------------------------------------------------------------------------}
FUNCTION DaysInYear(Year:NativeInt):NativeInt;
begin
   if LeapYear(Year) then Result:=366 else Result:=365;
end;

{------------------------------------------------------------------------------}
{  WeeksInYear                                                                }
{  Gibt die Anzahl der Wochen eines Jahres zurück                             }
{------------------------------------------------------------------------------}
FUNCTION WeeksInYear(Year:NativeInt):NativeInt;
var Dow:word;
begin
   Dow:=DayOfWeek(Year,1,1);
   Result:=52+Integer((Dow=3) or ((Dow=2) and LeapYear(Year)));
end;

{------------------------------------------------------------------------------}
{ WeekNum                                                                     }
{ Berechnet für ein Datum die Wochennumer und das Jahr zu der die Wochennummer }
{ gehört.
{ Results  : Week = Nummer der Woche                                           }
{             YearOfWeek = Jahr, zu dem die Woche gehört                              }
{------------------------------------------------------------------------------}
PROCEDURE WeekNum(Year,Month,Day:NativeInt; var Week,YearOfWeek:NativeInt);
var Dn:Integer; Dow:word;
begin
   Dn:=DayNum(Year,1,1);
   Dow:=(Dn+5) mod 7;
   Week:=(DayNum(Year,Month,Day)-Dn+Dow) div 7;
   YearOfWeek:=Year;
   if Dow<4 then begin
      Inc(Week);
   end else if Week=0 then begin
      Dec(YearOfWeek);
      Week:=WeeksInYear(YearOfWeek);
      Exit;
   end;
   if Week>WeeksInYear(YearOfWeek) then begin
      Week:=1;
      Inc(YearOfWeek);
   end;
end;

{------------------------------------------------------------------------------}
{ DayNumToDate                                                                }
{ Berechnet aus einer TagNummer das Datum                                     }
{------------------------------------------------------------------------------}
PROCEDURE DayNumToDate(Dn:NativeInt; var Year, Month, Day:NativeInt);
begin
   Year:=Dn div 366;
   Month:=1;
   Day:=1;
   Dec(Dn,DayNum(Year,1,1));
   while Dn>=DaysInYear(Year) do begin
      Dec(Dn,DaysInYear(Year));
      Inc(Year);
   end;
   while Dn>=DaysInMonth(Year,Month) do begin
      Dec(Dn,DaysInMonth(Year,Month));
      Inc(Month);
   end;
   Inc(Day,Dn);
end;

{------------------------------------------------------------------------------}
{ EasterSunday                                                                }
{ Berechnet den Monat und den Tag und die TagNummer des OsterSontages in year. }
{ year muß im Bereich 1583..2499 liegen,                                      }
{ Wenn year nicht in diesem Bereich liegt, ist das Funktionsergebnis = -1      }
{ und month und day sind undefiniert.                                         }
{ Sonst enthalten month und day das Datum und result die Tagnummer des        }
{ OsterSonntages in year.                                                     }
{------------------------------------------------------------------------------}
FUNCTION EasterSunday(Year:NativeInt; var Month,Day:NativeInt):NativeInt;
var A,B,C,D,E,H,L,M:word;
begin
   if (Year<1583) or (Year>2499) then Exit(-1);
   H:=Year div 100;
   L:=(4+H)-(H div 4);
   M:=(15+H)-(H div 4)-(((8*H)+13) div 25);
   A:=Year mod 4;
   B:=Year mod 7;
   C:=Year mod 19;
   D:=((19*C)+M) mod 30;
   E:=((2*A)+(4*B)+(6*D)+L) mod 7;
   Day:=22+D+E;
   if Day<=31 then begin
      Month:=3;
   end else begin
      Month:=4;
      if (D=29) and (E=6) then Day:=19
         else if (D=28) and (E=6) and (C>=11) then Day:=18
            else Day:=D+E-9;
   end;
   result:=DayNum(Year,Month,Day);
end;

{------------------------------------------------------------------------------}
{ FirstAdvent                                                                 }
{ Berechnet den Monat und den Tag und die TagNummer des Ersten Advent in year. }
{ year muß im Bereich 1582..9999 liegen                                       }
{ Benötigt für Berechnung des Datums des Buss und Bettages, der 11 Tage vor   }
{ Wenn year nicht im Bereich 1582..9999 liegt, wird -1 zurückgegeben und      }
{ month und day sind undefiniert.                                             }
{ Sonst enthalten month und day das Datum und result die Tagnummer des        }
{ Ersten Advent in year.                                                      }
{------------------------------------------------------------------------------}
FUNCTION FirstAdvent(Year:NativeInt; var Month,Day:NativeInt):NativeInt;
var Offset:NativeInt;
begin
   if (Year<1583) or (Year>9999) then Exit(-1);
   Result:=DayNum(Year,11,27);
   Offset:=6-DayOfWeek(Result);
   inc(Result,Offset);
   if Offset<=3 then begin
      Day:=27+Offset;
      Month:=11;
   end else begin
      Day:=Offset-3;
      Month:=12;
   end;
end;

{------------------------------------------------------------------------------}
{   CompleteYear                                                              }
{------------------------------------------------------------------------------}
FUNCTION CompleteYear(Year:NativeInt):NativeInt;
begin
   if Year<30 then Result:=Year+2000
      else if Year<100 then Result:=Year+1900
         else Result:=Year;
end;

{------------------------------------------------------------------------------}
{ WeekYearToDayNum                                                            }
{ Berechnet das Datum des Montages einer Woche in einem Jahr                  }
{ Result : True, wenn die Woche in dem Jahr existiert                         }
{ D     : Wenn Result=True, Nummer des Tages (siehe DayNum)                  }
{------------------------------------------------------------------------------}
FUNCTION WeekYearToDayNum(Wk,Y:NativeInt; var D:NativeInt):Boolean; register;
var Dn,Dow:NativeInt;
begin
   Result:=(Wk>=1) and (Wk<=WeeksInYear(Y));
   if not result then Exit;
   Dn:=DayNum(Y,1,1);
   Dow:=DayOfWeek(Dn);
   D:=Dn-Dow+7*(Wk-Integer(Dow<=Thursday));
end;

bcvs 5. Jun 2018 11:36

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403926)
Moin,

nein, die Frage lautete: wie wird mit dem 29.4. des Jahres 1415 umgegangen? Gibt es Algorithmen, die die Ungenauigkeit der 365.25 Tage ausgleichen?

Wie wäre es mit folgendem Ansatz:

Der 01.01.0001 ist als Delphi-TDateTime -693593

Da du am 01.01.0000 anfängst, sind es noch 365 Tage zurück, also -693958 (oder -693959, falls es wirklich der 0. Januar sein soll)

Der 29.04.1415 wäre demnach
Delphi-Quellcode:
StrToDate('29.04.1415') + 693958
= -177023 + 693958 = 516935

himitsu 5. Jun 2018 11:44

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403876)
Wenn ich von 365.25 Tagen pro Jahr ausgehe, kommen auch sinnvolle Werte raus.

Nach Julius Caesar hättest du Recht, aber wir richten uns inzwischen nach Papst Gregor und da sind es 365,2425. (1900 und 2100 sind keine Schaltjahre und 2000 war nur Eines, wegen der dritten Regel)

Alallart 5. Jun 2018 12:16

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403926)
Moin,

nein, die Frage lautete: wie wird mit dem 29.4. des Jahres 1415 umgegangen? Gibt es Algorithmen, die die Ungenauigkeit der 365.25 Tage ausgleichen?

Es gibt keine Ungenauigkeit, für alles gibt es Regeln. Die bekannteste ist die Berechnung des Schaltjahres alle vier Jahre. Teilt man das Jahr durch 4, und es gibt keine Nachkommastellen, ist es ein Schaltjahr.

Beispiel:
Delphi-Quellcode:
  if Frac(2020/4) = 0 then ShowMessage('Schaltjahr');

oder
Delphi-Quellcode:
  if (2020 mod 4) = 0 then ShowMessage('Schaltjahr');


Die nächste Regel ist, dass wenn die obere Regel ein Schaltjahr berechnet, man aber das Jahr durch 100 teilen kann (ohne Nachkommastellen), man das Schaltjahr auslässt.

Delphi-Quellcode:
  if (2000 mod 4) = 0 then ShowMessage('Schaltjahr');
  if (2000 mod 100) = 0 then ShowMessage('doch kein Schaltjahr');
Davon gibt es wiederum eine Ausnahme. Wenn es nach der 4 Jahres-Regel ein Schaltjahr ist, und nach der 100 Jahre-Regel kein Schaltjahr ist, man es aber durch 400 teilen kann (wieder ohne Nachkommastellen), dann ist es doch ein Schaltjahr.

Delphi-Quellcode:
var
  a: Integer;
begin
  a := 2300;

  if (a mod 400) = 0 then
    ShowMessage('Es ist ein Schlatjahr')
  else if (a mod 100) = 0 then
    ShowMessage('Es ist KEIN Schlatjahr')
  else if (a mod 4) = 0 then
    ShowMessage('Es ist ein Schlatjahr')
  else
    ShowMessage('Es ist KEIN Schlatjahr');
end;

bcvs 5. Jun 2018 13:36

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Zitat:

Zitat von messie (Beitrag 1403926)
Moin,

nein, die Frage lautete: wie wird mit dem 29.4. des Jahres 1415 umgegangen? Gibt es Algorithmen, die die Ungenauigkeit der 365.25 Tage ausgleichen?

Die gibt es. Als Ergänzung zu meinem vorigen Beitrag:

Schau dir mal den Quellcode der Function TryEncodeDate aus der Unit SysUtils an.
Da wird sogar zuerst dein Timestamp basierend auf dem 31.12.0000 errechnet und davon die Konstante DateDelta abgezogen.

DateDelta ist 693594, also genau der Wert, den ich in meinem vorigen Beitrag wieder hinzuaddiert habe. Wenn du also diese Function nimmst, kannst du durch Anpassen von DateDelta die Datumsbasis da hinlegen, wo du willst.

messie 6. Jun 2018 14:57

AW: Datumsangabe ab dem Jahr 0 - gibt es eine Konvention?
 
Moin,

wenn sich Matlab auch an die Berechnung der Schaltjahre hält, muss ich eigentlich nur die 693958 vom Eingangswert abziehen.
Danke für Eure Hilfe. Ist fast ein bisschen wie nach Hause kommen :wink:.

Grüße, Messie


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:43 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz