// Für den Urlaubsalgorithmus siehe "Vergleich zwischen dem Mondkalender und dem westlichen Kalender, ewiger Kalender", bitte
Einheit CNYEAR;
Schnittstelle
verwendet Systeme;
Typ tcndate = kardinal;
Funktion decodegregTocndate (dtgreg: tdatetime): tcndate;
Funktion getgregdateFromcn (cnyear, cnmonth, cnday: wort; Bleap: boolean = false): tdatetime;
Funktion Gregdatetocnstr (dtgreg: tdatetime): String;
Funktion iscnleap (CNDATE: TCNDATE): boolean;
Durchführung
const cstdateorg: Integer = 32900;
const cstcnyearorg = 1990;
const cstcntable: Array [cstcnyearorg..cstcnyearorg + 60] von Word = (// vorzeichenlos 16-Bit
24402, 3730, 3366, 13614, 2647, 35542, 858, 1749, // 1997
23401, 1865, 1683, 19099, 1323, 2651, 10926, 1386, // 2005
32213, 2980, 2889, 23891, 2709, 1325, 17757, 2741, // 2013
39850, 1490, 3493, 61098, 3402, 3221, 19102, 1366, // 2021
2773, 10970, 1746, 26469, 1829, 1611, 22103, 3243, // 2029
1370, 13678, 2902, 48978, 2898, 2853, 60715, 2635, // 2037
1195, 21179, 1453, 2922, 11690, 3474, 32421, 3365, // 2045
2645, 55901, 1206, 1461, 14038);
// Tabellenerstellungsmethode:
// 0101 111101010010 Die hohen vier Ziffern sind die Position des Schaltmonats, die letzten 12 Ziffern repräsentieren den großen und großen Monat, der große Monat beträgt 30 Tage und der kleine Monat beträgt 29 Tage.
// Der Schaltmonat wird im Allgemeinen als kleiner Monat angesehen, aber es gibt drei Sonderfälle 2017/06, 2036/06, 2047/05
// Für Sonderfälle ist die höchste Position der Position des Leap-Monats des vierstelligen Hochschaltmonats auf 1. Spezielle Verarbeitung verwendet wleApnormale Variable
// // 2017/06 28330-> 61098 2036/06 27947-> 60715 2047/05 23133-> 55901
// Wenn Sie Assembly verwenden möchten, finden Sie hier eine Nachricht: Der Mondkalender bleibt 2 Monate lang nicht hinter dem gregorianischen Kalender zurück.
// Gregorianischen Kalender in den Mondkalender konvertieren
// Rückkehr: 12-stelliges Jahr + 4-stelliger Monat + 5-stelliges Datum
Funktion decodegregTocndate (dtgreg: tdatetime): tcndate;
var
Idayleave: Ganzzahl;
wyear, wonth, wday: Wort;
Ich, J: Ganzzahl;
WBIGSmalldist, Wleap, WCount, Wleapshift: Word;
Label OK;
Beginnen
Ergebnis: = 0;
idayleave: = trunc (dtgreg) - cstdateorg;
Decodedat (incmonth (dtgreg, -1), wyear, wonth, wday);
if (idayleave <0) oder (idayleave> 22295) dann beenden;
// Exception.create ('derzeit erst 1990-01-27 nach' nach ');
// Ausnahme erhöhen.create ('Derzeit kann es nur wie vor 2051-02-11' gezählt werden);
Für i: = niedrig (cstcntable) bis hoch (cstcntable) beginnen
wbigsmalldist: = cstcntable [i];
WLEAP: = WBIGSMalldist SHR 12;
Wenn Wleap> 12 dann beginnen
wleap: = wleap und 7;
wleapShift: = 1;
Ende sonst
wleapShift: = 0;
Für J: = 1 bis 12 beginnen
WCount: = (WBIGSmalldist und 1) + 29;
Wenn J = Wleap dann WCount: = WCount - WleApShift;
Wenn idayleave <wcount dann beginnen
Ergebnisse: = (i SHL 9) + (J SHL 5) + idayleave + 1;
Ausfahrt;
Ende;
idayleave: = idayleave - wCount;
Wenn j = wleap dann beginnen
WCOUNT: = 29 + wleapshift;
Wenn idayleave <wcount dann beginnen
Ergebnisse: = (I SHL 9) + (J SHL 5) + idayleave + 1 + (1 SHL 21);
Ausfahrt;
Ende;
idayleave: = idayleave - wCount;
Ende;
wbigsmalldist: = wbigsmalldist shr 1;
Ende;
Ende;
// Rückgabewert:
// 1 ZIGITITEL LEP MONTH LOGO + 12 ZIGITISCHE JAHRE + 4 ZIGITISCHE MONTIGE + 5 ZIGITETE DATUM (Gesamt 22 Ziffern)
Ende;
Funktion iscnleap (CNDATE: TCNDATE): boolean;
Beginnen
Ergebnis: = (CNDATE und $ 200000) <> 0;
Ende;
Funktion getgregdateFromcn (cnyear, cnmonth, cnday: wort; Bleap: boolean = false): tdatetime;
var
Ich, J: Ganzzahl;
Daycount: Ganzzahl;
wbigsmalldist, wleap, wleapshift: word;
Beginnen
// 0101 0100101111 Die hohen vier Ziffern sind die Position des Schaltmonats, die letzten 12 Ziffern repräsentieren den großen und großen Monat, der große Monat beträgt 30 Tage und der kleine Monat beträgt 29 Tage.
Daycount: = 0;
if (cnyear <1990) oder (cnyear> 2050) beginnen
Ergebnisse: = 0;
Ausfahrt;
Ende;
für i: = cstcnyearorg zu cnyear-1 beginnen
wbigsmalldist: = cstcntable [i];
if (wbigsmalldist und $ f000) <> 0, dann DayCount: = DayCount + 29;
Daycount: = Daycount + 12 * 29;
Für J: = 1 bis 12 beginnen
DayCount: = Daycount + WBIGSmalldist und 1;
wbigsmalldist: = wbigsmalldist shr 1;
Ende;
Ende;
wbigsmalldist: = cstcntable [cnyear];
WLEAP: = WBIGSMalldist SHR 12;
Wenn Wleap> 12 dann beginnen
wleap: = wleap und 7;
wleapshift: = 1; // Der große Monat ist im Schaltmonat.
Ende sonst
wleapShift: = 0;
für J: = 1 bis cnmonth-1 beginnen
Daycount: = DayCount + (WBIGSmalldist und 1) + 29;
Wenn J = Wleap dann DayCount: = Daycount + 29;
wbigsmalldist: = wbigsmalldist shr 1;
Ende;
Wenn Bleap und (cnmonth = wleap) dann // ist es ein Schaltmonat?
Daycount: = Daycount + 30 - WleApShift;
Ergebnis: = CSTDATEORG + DAYCOUNT + CNDAY - 1;
Ende;
// Zeigen Sie Daten in Mondstränge.
Funktion Gregdatetocnstr (dtgreg: tdatetime): String;
const HzNumber: Array [0..10] von String = ('Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Sieben', 'acht',,,,, 'neunzig');
Funktion Convertymd (Nummer: Wort; YMD: Wort): String;
var
WTMP: Wort;
Beginnen
Ergebnis: = '';
Wenn ymd = 1 dann beginnen // Jahr
während die Nummer> 0 beginnt
Ergebnis: = HzNumber [Zahlenmod 10] + Ergebnis;
Nummer: = Zahl Div 10;
Ende;
Ausfahrt;
Ende;
Wenn Zahl <= 10 dann beginnt // nur 1 Ziffer kann verwendet werden
Wenn ymd = 2 dann // Monat
Ergebnis: = HzNumber [Nummer]
sonst // Tag
Ergebnis: = 'First' + HzNumber [Nummer];
Ausfahrt;
Ende;
wtmp: = nummer mod 10;
Wenn wtmp <> 0 dann Ergebnis: = HzNumber [WTMP];
wtmp: = number Div 10;
Ergebnis: = 'zehn'+Ergebnis;
Wenn WTMP> 1 dann Ergebnis: = HzNumber [WTMP] + Ergebnis;
Ende;
var
cnyear, cnmonth, cnday: wort;
CNDATE: TCNDATE;
Stleap: String;
Beginnen
CNDATE: = decodegregTocndate (dtgreg);
Wenn cndate = 0 dann beginnen
Ergebnis: = 'Eingabe außerhalb der Grenzen';
Ausfahrt;
Ende;
CNDAY: = CNDATE und $ 1F;
cnmonth: = (cndate shr 5) und $ f;
CNYEAR: = (CNDATE SHR 9) und $ FFF;
// Die 22. Position des Tests beträgt 1, was einen Schaltmonat bedeutet
wenn iscnleap (cndate) dann stleap: = '(lap)' else stleap: = '';
Ergebnis: = 'Mondkalender' + Convertymd (cnyear, 1) + 'Jahr' + Convertymd (CNMONTH, 2) + 'Monat' '
+ stleap + Convertymd (CNDAY, 3);
Ende;
Ende.
////////////////////////////////////////////////// ////////////////// //////////////////////////////////////////////////////////////////////////.
verwendet CNYEAR;
Procedure tform1.button1click (Absender: tobject);
Beginnen
edit1.text: = gregdatetocnstr (DateTimePicker1.Date);
Ende;