// Pour l'algorithme des fêtes, veuillez vous référer à "la comparaison entre le calendrier lunaire et le calendrier occidental, le calendrier perpétuel"
unité cnyear;
interface
utilise sysutils;
type tcndate = cardinal;
fonction decodeGregTocNDate (dtgreg: tdateTime): tcndate;
fonction getGregDateFromcn (cnyear, cnmonth, cnday: word; Bleap: boolean = false): tdatetime;
Fonction GregdateTocnstr (dtgreg: tdateTime): String;
Fonction iscnLeap (cnDate: tcnDate): booléen;
Mise en œuvre
const cstDateorg: entier = 32900;
const cstcnyearorg = 1990;
const cstcntable: array [cstcnyearorg..cstcnyearorg + 60] de word = (// non signé 16 bits
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);
// Méthode de création de table:
// 0101 111101010010 Les quatre chiffres élevés sont la position du mois de saut, les 12 derniers chiffres représentent le grand et le grand mois, le grand mois est de 30 jours et le petit mois est de 29 jours,
// Le mois Leap est généralement considéré comme un petit mois, mais il y a trois cas spéciaux 2017/06, 2036/06, 2047/05
// Pour les cas spéciaux, la représentation de position du mois le plus élevée du mois de saut du mois de LEAP à quatre chiffres est définie sur 1. Le traitement spécial utilise la variable wleapnormale
// // 2017/06 28330-> 61098 2036/06 27947-> 60715 2047/05 23133-> 55901
// Si vous souhaitez utiliser l'assemblage, voici un message: le calendrier lunaire ne sera pas à la traîne du calendrier grégorien pendant 2 mois.
// Convertir le calendrier grégorien en calendrier lunaire
// Retour: 12 chiffres + mois à 4 chiffres + date à 5 chiffres
fonction decodeGregTocNDate (dtgreg: tdateTime): tcndate;
var
idayleave: entier;
Wyear, Wmonth, wday: mot;
I, J: entier;
wbigsmalldist, wleap, wcount, wleapshift: word;
étiqueter OK;
Commencer
Résultat: = 0;
idayLeave: = trunc (dtgreg) - cstDateorg;
Décodédate (Incmonth (dtgreg, -1), Wyear, Wmonth, wday);
if (idayleave <0) ou (idayLeave> 22295) puis sortir;
// augmenter l'exception.Create («actuellement compte seulement comme 1990-01-27 après»);
// augmenter l'exception.Create («Actuellement, il ne peut être compté qu'avant 2051-02-11»);
pour i: = bas (cstcntable) à élevé (cstcntable) commence
wbigsmalldist: = cstcntable [i];
wleap: = wbigsmalldist shR 12;
Si wleap> 12 alors commencez
wleap: = wleap et 7;
wleapshift: = 1;
fin d'autre
wleapshift: = 0;
pour j: = 1 à 12
wCount: = (wbigsmalldist et 1) + 29;
Si j = wleap alors wCount: = wCount - wleapShift;
Si idayLeave <WCOUNT alors commencez
Résultats: = (i shl 9) + (j shl 5) + idayleave + 1;
Sortie;
fin;
idayLeave: = idayLeave - wCount;
Si j = wleap alors commencez
wCount: = 29 + wleapshift;
Si idayLeave <WCOUNT alors commencez
Résultats: = (i shl 9) + (j shl 5) + idayleave + 1 + (1 shl 21);
Sortie;
fin;
idayLeave: = idayLeave - wCount;
fin;
wbigsmalldist: = wbigsmalldist shR 1;
fin;
fin;
// Valeur de retour:
// Logo du mois de lampe à 1 chiffre + année à 12 chiffres + mois de 4 chiffres + Date de 5 chiffres (total 22 chiffres)
fin;
Fonction iscnLeap (cnDate: tcnDate): booléen;
Commencer
Résultat: = (CNDATE et 200000 $) <> 0;
fin;
fonction getGregDateFromcn (cnyear, cnmonth, cnday: word; Bleap: boolean = false): tdatetime;
var
I, J: entier;
DayCount: entier;
wbigsmalldist, wleap, wleapshift: word;
Commencer
// 0101 0100101111 Les quatre chiffres élevés sont la position du mois de saut, les 12 derniers chiffres représentent le grand et le grand mois, le grand mois est de 30 jours et le petit mois est de 29 jours,
DayCount: = 0;
if (cnyear <1990) ou (cnyear> 2050) alors commencez
Résultats: = 0;
Sortie;
fin;
pour i: = cstcnyearorg à cnyear-1 commencez
wbigsmalldist: = cstcntable [i];
if (wbigsmalldist et $ f000) <> 0 alors dayCount: = dayCount + 29;
DayCount: = DayCount + 12 * 29;
pour j: = 1 à 12
DayCount: = DayCount + Wbigsmalldist et 1;
wbigsmalldist: = wbigsmalldist shR 1;
fin;
fin;
wbigsmalldist: = cstcntable [cnyear];
wleap: = wbigsmalldist shR 12;
Si wleap> 12 alors commencez
wleap: = wleap et 7;
wleapshift: = 1;
fin d'autre
wleapshift: = 0;
pour j: = 1 à cnmonth-1 commencez
DayCount: = DayCount + (wbigsmalldist et 1) + 29;
Si j = wleap, alors DayCount: = DayCount + 29;
wbigsmalldist: = wbigsmalldist shR 1;
fin;
Si Bleap et (cnMonth = wleap) alors // est-ce un mois de saut?
DayCount: = DayCount + 30 - Wleapshift;
Résultat: = cStDateorg + DayCount + Cnday - 1;
fin;
// montre des dates sur les cordes lunaires.
Fonction GregdateTocnstr (dtgreg: tdateTime): String;
const hznumber: array [0..10] de String = («zéro», «one», «deux», «trois», «quatre», «cinq», «six», «sept», «huit», 'quatre-vingt-dix');
fonction convertymd (nombre: word; ymd: word): chaîne;
var
WTMP: mot;
Commencer
Résultat: = '';
Si ymd = 1 alors commencez // l'année
tandis que le numéro> 0 commence
Résultat: = HzNumber [Numéro Mod 10] + Résultat;
Numéro: = Numéro Div 10;
fin;
Sortie;
fin;
Si le nombre <= 10 alors commencez // un seul chiffre peut être utilisé
Si ymd = 2 alors // mois
Résultat: = hznumber [numéro]
sinon // jour
Résultat: = 'premier' + hznumber [numéro];
Sortie;
fin;
WTMP: = Numéro Mod 10;
Si wtmp <> 0 alors résultat: = hznumber [wtmp];
wtmp: = nombre div 10; // dix chiffres
Résultat: = 'dix' + résultat;
Si wtmp> 1 alors résultat: = hznumber [wtmp] + résultat;
fin;
var
Cnyear, Cnmonth, Cnday: mot;
CNDATE: TCNDATE;
strLeap: String;
Commencer
cNDate: = decodeGregTocNDate (dtgreg);
Si cndate = 0 alors commencez
Résultat: = 'entrée hors limites';
Sortie;
fin;
CNDAY: = CNDATE et 1F $;
cnmonth: = (cndate shR 5) et $ f;
CNYEAR: = (CNDATE SHR 9) et $ FFF;
// La 22e position du test est 1, ce qui signifie un mois de saut
Si iscnLeap (cndate) alors strLEAP: = '(leap)' else strleap: = '';
Résultat: = 'Lunar Calendar' + convertymd (Cnyear, 1) + 'année' + convertymd (cnmonth, 2) + 'mois'
+ strLeap + convertymd (cnday, 3);
fin;
fin.
////////////////////////////////////////////////////////////////////////// / ///////////////// ///////////////////
utilise cnyear;
Procédure tform1.button1Click (expéditeur: tobject);
Commencer
edit1.text: = gregdatetocnstr (dateTimePicker1.date);
fin;