// لخوارزمية العطلات ، يرجى الرجوع إلى "المقارنة بين التقويم القمري والتقويم الغربي ، التقويم الدائم"
وحدة cnyear.
واجهة
يستخدم sysutils.
اكتب tcndate = الكاردينال ؛
دالة decodegregtocndate (dtgreg: tdatetime): tcndate ؛
وظيفة getGregdateFromcn (cnyear ، cnmonth ، cnday: كلمة ؛ bleap: boolean = false): tdatetime ؛
وظيفة gregdatetocnstr (dtgreg: tdatetime): سلسلة ؛
وظيفة iscnleap (cndate: tcndate): منطقية ؛
تطبيق
Const Cstdateorg: integer = 32900 ؛
const cstcnyearorg = 1990 ؛
const cstcntable: صفيف [cstcnyearorg..cstcnyearorg + 60] من كلمة = (// غير موقعة 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) ؛
طريقة إنشاء الجدول:
.
// يعتبر شهر القفزة عمومًا شهرًا صغيرًا ، ولكن هناك ثلاث حالات خاصة 2017/06 ، 2036/06 ، 2047/05
// للحالات الخاصة ، يتم تعيين أعلى مستوى في شهر Leap Month الذي تم تعيينه لشهر القفزات العالية المكونة من أربعة أرقام إلى 1.
// // 2017/06 28330-> 61098 2036/06 27947-> 60715 2047/05 23133-> 55901
// إذا كنت ترغب في استخدام التجميع ، فإليك رسالة: لن يتخلف التقويم القمري عن التقويم الغريغوري لمدة شهرين.
// تحويل التقويم الغريغوري إلى التقويم القمري
// العائد: مكون من 12 رقمًا + 4 أرقام شهر + موعد 5 أرقام
دالة decodegregtocndate (dtgreg: tdatetime): tcndate ؛
var
idayleave: عدد صحيح ؛
Wyear ، Wmonth ، Wday: Word ؛
أنا ، ي: عدد صحيح ؛
wbigsmalldist ، wleap ، wcount ، wleapshift: word ؛
تسمية موافق ؛
يبدأ
النتيجة: = 0 ؛
idayleave: = trunc (dtgreg) - cstdateorg ؛
decodedate (inconth (dtgreg ، -1) ، wyear ، wmonth ، wday) ؛
إذا (idayleave <0) أو (idayleave> 22295) ثم الخروج ؛
// رفع استثناء. إنشاء ('حاليًا فقط يُحسب كـ 1990-01-27 بعد ") ؛
// رفع استثناء. إنشاء ('حاليًا ، لا يمكن حسابه إلا قبل 2051-02-11') ؛
ل I: = منخفض (cstcntable) إلى ارتفاع (cstcntable) تبدأ
wbigsmalldist: = cstcntable [i] ؛
WLEAP: = WBIGSMALLDIST SHR 12 ؛
إذا كان WLEAP> 12 ثم ابدأ
WLEAP: = WLEAP و 7 ؛
wleapshift: = 1 ؛
إنهاء آخر
wleapshift: = 0 ؛
لـ J: = 1 إلى 12 تبدأ
wcount: = (wbigsmalldist و 1) + 29 ؛
إذا كان j = wleap ثم wcount: = wcount - wleapshift ؛
إذا idayleave <wcount ثم ابدأ
النتائج: = (i shl 9) + (j shl 5) + idayleave + 1 ؛
مخرج؛
نهاية؛
idayleave: = idayleave - wcount ؛
إذا كان j = wleap ثم ابدأ
wcount: = 29 + wleapshift ؛
إذا idayleave <wcount ثم ابدأ
النتائج: = (i shl 9) + (j shl 5) + idayleave + 1 + (1 shl 21) ؛
مخرج؛
نهاية؛
idayleave: = idayleave - wcount ؛
نهاية؛
wbigsmalldist: = wbigsmalldist shr 1 ؛
نهاية؛
نهاية؛
// قيمة الإرجاع:
// 1 Leap Month Logo Logo + 12 رقمًا + 4 أرقام الشهر + 5 أرقام تاريخ (إجمالي 22 رقمًا)
نهاية؛
وظيفة iscnleap (cndate: tcndate): منطقية ؛
يبدأ
النتيجة: = (cndate و 200000 دولار) <> 0 ؛
نهاية؛
وظيفة getGregdateFromcn (cnyear ، cnmonth ، cnday: كلمة ؛ bleap: boolean = false): tdatetime ؛
var
أنا ، ي: عدد صحيح ؛
Daycount: عدد صحيح ؛
wbigsmalldist ، wleap ، wleapshift: كلمة ؛
يبدأ
.
Daycount: = 0 ؛
إذا (cnyear <1990) أو (cnyear> 2050) ثم ابدأ
النتائج: = 0 ؛
مخرج؛
نهاية؛
لأني: = cstcnyearorg to cnyear-1 تبدأ
wbigsmalldist: = cstcntable [i] ؛
if (wbigsmalldist و $ f000) <> 0 ثم DayCount: = DayCount + 29 ؛
DayCount: = DayCount + 12 * 29 ؛
لـ J: = 1 إلى 12 تبدأ
DayCount: = DayCount + Wbigsmalldist و 1 ؛
wbigsmalldist: = wbigsmalldist shr 1 ؛
نهاية؛
نهاية؛
wbigsmalldist: = cstcntable [cnyear] ؛
WLEAP: = WBIGSMALLDIST SHR 12 ؛
إذا كان WLEAP> 12 ثم ابدأ
WLEAP: = WLEAP و 7 ؛
WLEAPSHIFT: = 1 ؛
إنهاء آخر
wleapshift: = 0 ؛
ل j: = 1 إلى cnmonth-1 تبدأ
DayCount: = DayCount + (wbigsmalldist و 1) + 29 ؛
إذا كان j = wleap ثم DayCount: = DayCount + 29 ؛
wbigsmalldist: = wbigsmalldist shr 1 ؛
نهاية؛
إذا كان bleap و (cnmonth = wleap) ثم // هل هو شهر قفزة؟
DayCount: = DayCount + 30 - Wleapshift ؛
النتيجة: = cstdateorg + daycount + cnday - 1 ؛
نهاية؛
// عرض التواريخ في سلاسل القمر.
وظيفة gregdatetocnstr (dtgreg: tdatetime): سلسلة ؛
const hznumber: Array [0..10] من String = ('Zero' ، 'One' ، 'اثنين' ، 'Three' ، 'Four' ، 'Five' ، 'Six' ، 'Seven' ، 'Eight' ، 'تسعون')؛
دالة convertymd (الرقم: كلمة ؛ ymd: كلمة): سلسلة ؛
var
WTMP: كلمة ؛
يبدأ
النتيجة: = '' ؛
إذا كان YMD = 1 ثم ابدأ /عام
بينما الرقم> 0 تبدأ
النتيجة: = hznumber [رقم mod 10] + نتيجة ؛
الرقم: = رقم Div 10 ؛
نهاية؛
مخرج؛
نهاية؛
إذا كان الرقم <= 10 ثم ابدأ // فقط يمكن استخدام رقم واحد فقط
إذا ymd = 2 ثم // الشهر
النتيجة: = hznumber [رقم]
آخر / /يوم
النتيجة: = 'first' + hznumber [number] ؛
مخرج؛
نهاية؛
WTMP: = الرقم Mod 10 ؛
إذا كان wtmp <> 0 ثم النتيجة: = hznumber [wtmp] ؛
WTMP: = الرقم 10 ؛
النتيجة: = 'ten'+نتيجة ؛
إذا كان wtmp> 1 ثم النتيجة: = hznumber [wtmp] + نتيجة ؛
نهاية؛
var
cnyear ، cnmonth ، cnday: Word ؛
cndate: tcndate ؛
Strleap: سلسلة.
يبدأ
cndate: = decodegregtocndate (dtgreg) ؛
إذا cndate = 0 ثم ابدأ
النتيجة: = "إدخال من الحدود" ؛
مخرج؛
نهاية؛
cnday: = cndate و $ 1F ؛
cnmonth: = (cndate sh 5) و $ f ؛
cnyear: = (cndate shr 9) و $ fff ؛
// الموقف 22 من الاختبار هو 1 ، مما يعني شهر قفزة
إذا كان iscnleap (cndate) ثم strleap: = '(قفزة)' else strleap: = '' ؛
النتيجة: = 'lunar calendar' + convertymd (cnyear ، 1) + 'year' + convertymd (cnmonth ، 2) + 'month'
+ strleap + convertymd (cnday ، 3) ؛
نهاية؛
نهاية.
////////////////////////////////////////////////////////////// //////////////////////////////////
يستخدم cnyear.
الإجراء tform1.button1click (المرسل: tobject) ؛
يبدأ
edit1.text: = gregdatetocnstr (datetimepicker1.date) ؛
نهاية؛