// Untuk algoritma liburan, silakan merujuk ke "Perbandingan antara Kalender Lunar dan Kalender Barat, Kalender Abadi"
unit cnyear;
antarmuka
menggunakan sysutils;
ketik tcndate = kardinal;
fungsi decodegregtocndate (dtgreg: tdateTime): tcndate;
Fungsi getgregdateFromcn (cnyear, cnmonth, cnday: word; bleap: boolean = false): tdateTime;
fungsi gregdateToCnStr (dtgreg: tdateTime): string;
fungsi iscnleap (cndate: tcndate): boolean;
Pelaksanaan
Const CSTDateorg: Integer = 32900;
const cstcnyearg = 1990;
Const Cstcntable: array [cstcnyearg..cstcnyearg + 60] dari word = (// unsigned 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);
// Metode Pembuatan Tabel:
// 0101 111101010010 Tinggi empat digit adalah posisi bulan lompatan, 12 digit terakhir mewakili bulan besar dan besar, bulan besar adalah 30 hari, dan bulan kecil adalah 29 hari,
// Bulan lompatan umumnya dianggap sebulan kecil, tetapi ada tiga kasus khusus 2017/06, 2036/06, 2047/05
// Untuk kasus-kasus khusus, representasi posisi bulan lompatan tertinggi dari bulan lompatan tinggi empat digit ditetapkan ke 1. Pemrosesan khusus menggunakan variabel wleapnormal
// // 2017/06 28330-> 61098 2036/06 27947-> 60715 2047/05 23133-> 55901
// Jika Anda ingin menggunakan perakitan, berikut adalah pesan: Kalender Lunar tidak akan tertinggal di belakang kalender Gregorian selama 2 bulan.
// Konversi Kalender Gregorian ke Kalender Lunar
// Pengembalian: 12-Digit Tahun + Bulan 4 digit + Tanggal 5 digit
fungsi decodegregtocndate (dtgreg: tdateTime): tcndate;
var
Idayleave: Integer;
wyear, wonth, wday: word;
I, J: Integer;
wbigsmalldist, wleap, wcount, wleapshift: word;
Label OK;
Mulai
Hasil: = 0;
idayleave: = trunc (dtgreg) - cstdateorg;
Decodedate (incmonth (dtgreg, -1), wyear, wonth, wday);
if (idayleave <0) atau (idayleave> 22295) kemudian keluar;
// Naikkan Exception.Create ('Saat ini hanya dihitung sebagai 1990-01-27 setelah');
// Naikkan Exception.Create ('Saat ini, hanya dapat dihitung seperti sebelum 2051-02-11');
untuk i: = rendah (cstcntable) ke tinggi (cstcntable) mulai
wbigsmalldist: = cstcntable [i];
wleap: = wbigsmalldist shr 12;
Jika wleap> 12 maka mulailah
wleap: = wleap dan 7;
Wleapshift: = 1;
akhir yang lain
Wleapshift: = 0;
untuk j: = 1 hingga 12 mulai
wcount: = (wbigsmalldist dan 1) + 29;
jika j = wleap maka wcount: = wcount - wleapshift;
Jika idayleave <wcount maka mulailah
Hasil: = (i shl 9) + (j shl 5) + idayleave + 1;
KELUAR;
akhir;
idayleave: = idayleave - wcount;
Jika j = wleap maka mulailah
Wcount: = 29 + Wleapshift;
Jika idayleave <wcount maka mulailah
Hasil: = (i shl 9) + (j shl 5) + idayleave + 1 + (1 shl 21);
KELUAR;
akhir;
idayleave: = idayleave - wcount;
akhir;
wbigsmalldist: = wbigsmalldist shr 1;
akhir;
akhir;
// nilai pengembalian:
// 1 digit lompatan logo + 12 digit tahun + 4 digit bulan + 5 digit tanggal (total 22 digit)
akhir;
fungsi iscnleap (cndate: tcndate): boolean;
Mulai
Hasil: = (cndate dan $ 200000) <> 0;
akhir;
Fungsi getgregdateFromcn (cnyear, cnmonth, cnday: word; bleap: boolean = false): tdateTime;
var
I, J: Integer;
Daycount: bilangan bulat;
wbigsmalldist, wleap, wleapshift: word;
Mulai
// 0101 0100101111 Empat digit tinggi adalah posisi bulan lompatan, 12 digit terakhir mewakili bulan besar dan besar, bulan besar adalah 30 hari, dan bulan kecil adalah 29 hari,
Daycount: = 0;
if (cnyear <1990) atau (cnyear> 2050) lalu mulai
Hasil: = 0;
KELUAR;
akhir;
untuk i: = cstcnyearorg ke cnyear-1 dimulai
wbigsmalldist: = cstcntable [i];
if (wbigsmalldist dan $ f000) <> 0 lalu daycount: = daycount + 29;
Daycount: = daycount + 12 * 29;
untuk j: = 1 hingga 12 mulai
Daycount: = daycount + wbigsmalldist dan 1;
wbigsmalldist: = wbigsmalldist shr 1;
akhir;
akhir;
wbigsmalldist: = cstcntable [cnyear];
wleap: = wbigsmalldist shr 12;
Jika wleap> 12 maka mulailah
wleap: = wleap dan 7;
Wleapshift: = 1; // Bulan besar di bulan lompatan.
akhir yang lain
Wleapshift: = 0;
untuk j: = 1 hingga cnmonth-1 dimulai
Daycount: = daycount + (wbigsmalldist dan 1) + 29;
jika j = wleap maka daycount: = daycount + 29;
wbigsmalldist: = wbigsmalldist shr 1;
akhir;
Jika Bleap dan (cnmonth = wleap) maka // apakah ini bulan lompatan?
Daycount: = daycount + 30 - wleapshift;
Hasil: = cstdateorg + daycount + cnday - 1;
akhir;
// Tampilkan tanggal menjadi string bulan.
fungsi gregdateToCnStr (dtgreg: tdateTime): string;
const hznumber: array [0..10] dari string = ('nol', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'Sembilan puluh');
function convertymd (angka: kata; ymd: word): string;
var
WTMP: Word;
Mulai
Hasil: = '';
Jika ymd = 1 maka mulailah // tahun
Sedangkan nomor> 0 Mulai
Hasil: = Hznumber [Number Mod 10] + Hasil;
Angka: = angka div 10;
akhir;
KELUAR;
akhir;
Jika angka <= 10 maka mulailah // hanya 1 digit yang dapat digunakan
Jika ymd = 2 lalu // bulan
Hasil: = HZNumber [Nomor]
lain // hari
Hasil: = 'pertama' + hznumber [angka];
KELUAR;
akhir;
WTMP: = Number Mod 10; // Bit tunggal
jika wtmp <> 0 maka hasilnya: = hznumber [wtmp];
WTMP: = Nomor Div 10; // Sepuluh digit
Hasil: = 'sepuluh'+hasil;
jika wtmp> 1 maka hasilnya: = hznumber [wtmp] + hasil;
akhir;
var
cnyear, cnmonth, cnday: word;
cndate: tcndate;
strleap: string;
Mulai
cndate: = decodegregtocndate (dTreg);
Jika cndate = 0 maka mulailah
Hasil: = 'Input Out of Bounds';
KELUAR;
akhir;
cnday: = cndate dan $ 1f;
cnmonth: = (cndate shr 5) dan $ f;
cnyear: = (cndate shr 9) dan $ fff;
// Posisi 22 tes adalah 1, yang berarti bulan lompatan
jika iscnleap (cndate) maka strleap: = '(leap)' else strleap: = '';
Hasil: = 'Kalender Lunar' + ConvertyMd (Cnyear, 1) + 'Tahun' + Converymd (Cnmonth, 2) + 'Bulan'
+ strleap + convertymd (cnday, 3);
akhir;
akhir.
////////////////////////////////////////////////// THR ///////////////////////////////////////////
menggunakan cnyear;
Prosedur TFORM1.BUTTON1CLICK (Pengirim: Tobject);
Mulai
edit1.text: = gregDateToCnStr (datetimePicker1.date);
akhir;