Julianischen und Gregorianischen Kalender berechnen mit C

Eine kleine aber mächtige C-Libray zum Rechnen mit Datierungen nach dem Gregorianischen und Julianischen Kalender

Die Umrechnung von Datierungen verschiedener Kalender erfolgt über fortlaufende Tage. Das ist auch die Grundvoraussetzung dafür, daß sich Datierungen überhaupt von einem auf einen anderen Kalender übertragen lassen. Die hier vorgestellte C-Library verwendet für fortlaufende Tage den auch allgemein bekannten Begriff Julianische Tage. Somit kennzeichnet ein Julianischer Tag ein eindeutiges Datum was wir in beiden Kalendern per Tag, Monat und Jahr ausdrücken. Diese und weitere Angaben werden in der Anwendung meiner Library zu einem struct zusammengefasst, was wir auch auch als ein Objekt bezeichnen können:

// 1.1.-4713 to Anno Domini
typedef struct SCA{
    int jd;     // Julianday
    int day;
    int month;
    int year;   // -4713..AD
    int leap;   // 1 || 0
    char age;   // J || G
    int wd;     // 1..7(0)
    int hour;
    int minute;
    int second;
} SCA;

Die Namensgebung ist vom Namen desjenigen Gelehrten abgeleitet der im 16. Jh die Grundlagen zu Berechnung fortlaufender Tage schuf: Josef Justus Scaliger. Nun gibt es verschiedene Möglichkeiten, ein solches Scaliger-Objekt zu erstellen. Diese seien im Folgenden vorgestellt.

SCA *scaliger_day(int julianday)

Übergeben wird der Julianische Tag. Der Wert 0 für diesen Tag ergibt das Datum 1.1.-4713, also 4713 Jahre BC (Before Christ, vor unserer Zeitrechnung). Das Minuszeichen ist dem Umstand geschuldet, daß es das Jahr 0 nicht gibt, auf den 31.12.-1 (Ein Jahr vor Christi) folgt also der 1.1.1 (Jahr Eins Anno Domini). Beispiel:

SCA *sca = scaliger_day(0);
printf("Age: %c\nJD: %d\nDate: %d.%d.%d\nWD: %d\nTime: %d:%d:%d\nLeap: %d\n%s\n",
    sca->age, sca->jd, sca->day, sca->month, sca->year, sca->wd,
    sca->hour, sca->minute, sca->second, sca->leap, wochentag(sca->wd)
);

Age: J
JD: 0
Date: 1.1.-4713
WD: 1
Time: 0:0:0
Leap: 1
Montag

SCA *scaliger_date(char age, int day, int month, int year)

Mit dieser Funktion kann das Zeitalter, die Julianische oder die Gregorianische Epoche mit 'J' bzw. 'G' vorgegeben werden. Darüber hinaus kann diese Funktion die Epoche auch automatisch bestimmen, hierzu wird beim Aufruf ein '?' (Fragezeichen) übergeben. Beispiel:

SCA *sca = scaliger_date( '?', 4, 10, 1582 );

Age: J
JD: 2299160
Date: 4.10.1582
WD: 4
Time: 0:0:0
Leap: 0
Donnerstag

Beachte: Mit der Vorgabe 'J' oder 'G' ist der 5.10.1582 eine gültige Datierung, mit der Vorgabe '?' hingegen sind die Datierungen vom 5.10.1582 bis 14.10.1582 ungültig aufgrund der gregorianischen Kalenderreform. Letzere legt ja fest, daß auf den 4.10.1582 (Donnerstag) der 15.10.1582 (Freitag) folgt.

SCA *scaliger_time(int secsince)

Die Zeitrechnung des Computerzeitalters zählt die Sekunden seit dem 1.1.1970. Auch damit lässt sich das Objekt erstellen, Beispiel:

sca = scaliger_time(0);

Age: G
JD: 2440588
Date: 1.1.1970
WD: 4
Time: 0:0:0
Leap: 0
Donnerstag

Kommen wir nun zum eigentlichen Sinn fortlaufender Tage, zum Rechnen mit Datierungen.

sca = add_inepoch(sca, 1)

Diese Funktion berechnet ein neues Objekt anhand der zur Addition oder Subtraktion übergebenen Tage. Der Zusatz _inepoch bedeutet, daß die bei der Objekterstellung festgelegte Epoche 'J' oder 'G' beibehalten wird. Das heißt beispielsweise, daß beim Addieren eines Tages auf das Datum 4.10.1582/G der 5.10.1582/G folgt.

sca = add_seamless(sca, 1)

Mit dieser Funktion ergibt sich ein nahtloser Übergang bezüglich fortlaufender Tage über die Gregorianische Reform hinweg. Konkret ergibt sich beim Addieren eines Tages auf das Datum 4.10.1582/J der 15.10.1582/G.

SCA *sca = scaliger_date( '?', 4, 10, 1582 );

Age: J
JD: 2299160
Date: 4.10.1582
WD: 4
Time: 0:0:0
Leap: 0
Donnerstag

sca = add_seamless(sca, 1);

Age: G
JD: 2299161
Date: 15.10.1582
WD: 5
Time: 0:0:0
Leap: 0
Freitag

Hinweis: Mit beiden Funktionen bleibt das übergebene Datum-Objekt erhalten und es wird ein neues Objekt erzeugt.

int validate(SCA *sca)

Wie der Name der Funktion schon sagt, sie prüft ob das bei der Objekterstellung angegebene Datum gültig ist, hierzu wird das ganze Objekt übergeben.

Umrechnen von Datierungen

Zum Umrechen von Datierung über beide Kalender dient eine vereinfachte Datenstruktur:

typedef struct DMY{
    int day;
    int month;
    int year;   // -4713..AD
} DMY;

In Verbindung mit der Funktion scaliger_base('J', sca->jd), Anwendung siehe Beispiel untenstehend:

time_t t;
time(&t); // Erstelle ein Objekt mit dem
// aktuellen Datum
SCA *sca = scaliger_time(t);

// Rechne heutiges Datum auf den Julianischen Kalender um
DMY *jul = scaliger_base('J', sca->jd);
printf("%d.%d.%d\n", jul->day, jul->month, jul->year);

Datenschutzerklärung: Diese Seite dient rein privaten Zwecken. Auf den für diese Domäne installierten Seiten werden grundsätzlich keine personenbezogenen Daten erhoben. Das Loggen der Zugriffe mit Ihrer Remote Adresse erfolgt beim Provider soweit das technisch erforderlich ist. s​os­@rolf­rost.de.