;>>>>>>>>>>>农历计算函数原代码<<<<<<<<<<<<<<<<<
;作者:狂编
;
;本次公开愿代码,意在交流,绝对没有丝毫的炫耀的意思。
;希望大家有好的代码,拿出来赐教。
;=============检测阳历对应年份是否闰年==========
; 输入:年份
; 输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear proto dwYear:dword
;=============取阳历对应年月的天数==============
; 输入:年份,月份
; 输出:eax = 天数
_GetMonthDays proto dwYear:dword,dwMonth:dword
;=============取阳历对应星期几==================
; 输入:年份,月份,日
; 输出:eax=星期,星期日=0,星期一=1...
_GetWeekDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=============取对应阳历月的节气日==============
; 输入:年份,月份
; 输出:al =第一节气日,ah =第二节气日
_sTermOff proto dwYear:dword,dwMonth:dword
;=============取对应阳历日期的节气序号==========
; 输入:年份,月份,日
; 输出:eax=节气序号,小寒=1,大寒=2...
_GetHolDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=============取两个阳历日期之间的天数==========
; 输入:年份1,月份1,日1,年份2,月份2,日2(第一个为被减数)
; 输出:天数
_GetBetweenDays proto dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:dword,dwDay2:dword
;=============取农历年的天数====================
; 输入:年份
; 输出:天数
_GetLunarYearDays proto dwYear:dword
;=============取农历月的天数====================
; 输入:年份,月份
; 输出:天数
_GetLunarMonthDays proto dwYear:dword,dwMonth:dword
;=============填充农历数据结构==================
; 输入:农历数据结构指针(其中阳历必须已填好)
_GetLunarData proto _lpstLunarData:dword
;=============取农历月日字符串==================
; 输入:已填充好农历数据结构指针
; 输出:字符串缓冲区指针(最少13字节)
_GetLunarStr proto _lpstLunarData:dword,lpBuffer:dword
;=============干支序号转换成字符==================
; 输入:干支序号
; 输出:eax=字符
_GetGzStr proto GzNumber:dword
;=============干支序号转换五行生肖==============
; 输入:干支序号
; 输出:eax=低16位生肖,高16位五行
_GetSxStr proto GzNumber:dword
;=============节气序号转换字符=================
; 输入:节气序号
; 输出:eax=节气序号字符
_GetHDStr proto HdNumber:dword
;**************************************************
LUNARDATA struct
dwYear dw ? ;输入参数 - 年,十进制,例如 2000
dwMonth dw ? ;输入参数 - 月,十进制,例如 10
dwDay dw ? ;输入参数 - 日,十进制,例如 1
dwLunarYear dw ? ;农历年,如 2000
dbLunarMonth db ? ;农历月,如 12
dbLunarDay db ? ;农历日,如 31
dbWeekDay db ? ;星期,星期日=0,星期一=1...
dbIsLeapMonth db ? ;是否是闰月,返回 1 为农历闰月
noLunarYear db ? ;干支年,甲子=0,乙丑=1...
noLunarMonth db ? ;干支月,甲子=0,乙丑=1...
noLunarDay db ? ;干支日,甲子=0,乙丑=1...
noLunarHolDay db ? ;农历节气,小寒=1,大寒=2
LUNARDATA ends
;**************************************************
.code
LunarInfo dw 04bd8h,04ae0h,0a570h,054d5h,0d260h,0d950h,06554h,056a0h,09ad0h,055d2h
dw 04ae0h,0a5b6h,0a4d0h,0d250h,0d255h,0b540h,0d6a0h,0ada2h,095b0h,04977h
dw 04970h,0a4b0h,0b4b5h,06a50h,06d40h,0ab54h,02b60h,09570h,052f2h,04970h
dw 06566h,0d4a0h,0ea50h,06e95h,05ad0h,02b60h,086e3h,092e0h,0c8d7h,0c950h
dw 0d4a0h,0d8a6h,0b550h,056a0h,0a5b4h,025d0h,092d0h,0d2b2h,0a950h,0b557h
dw 06ca0h,0b550h,05355h,04da0h,0a5d0h,04573h,052d0h,0a9a8h,0e950h,06aa0h
dw 0aea6h,0ab50h,04b60h,0aae4h,0a570h,05260h,0f263h,0d950h,05b57h,056a0h
dw 096d0h,04dd5h,04ad0h,0a4d0h,0d4d4h,0d250h,0d558h,0b540h,0b5a0h,095a6h
dw 095b0h,049b0h,0a974h,0a4b0h,0b27ah,06a50h,06d40h,0af46h,0ab60h,09570h
dw 04af5h,04970h,064b0h,074a3h,0ea50h,06b58h,055c0h,0ab60h,096d5h,092e0h
dw 0c960h,0d954h,0d4a0h,0da50h,07552h,056a0h,0abb7h,025d0h,092d0h,0cab5h
dw 0a950h,0b4a0h,0baa4h,0ad50h,055d9h,04ba0h,0a5b0h,05176h,052b0h,0a930h
dw 07954h,06aa0h,0ad50h,05b52h,04b60h,0a6e6h,0a4e0h,0d260h,0ea65h,0d530h
dw 05aa0h,076a3h,096d0h,04bd7h,04ad0h,0a4d0h,0d0b6h,0d250h,0d520h,0dd45h
dw 0b5a0h,056d0h,055b2h,049b0h,0a577h,0a4b0h,0aa50h,0b255h,06d20h,0ada0h
dw 04b63h
leapBigTab db 00000010b,00000010b,00010000b,01000000b,00001010b
db 01001000b,00001001b,00000000b,00000000b,00000001b
db 00000000b,00000000b,00000000b,00000000b,00000100b
db 00000000b,00000000b,10000000b,00010010b
;=============检测对应年份是否闰年=============
; 输入:年份
; 输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear proc dwYear:dword
xor eax,eax
pushad
mov ebx,dwYear
mov eax,ebx
xor edx,edx
mov ecx,400
div ecx
or edx,edx
je loc002
mov eax,ebx
xor edx,edx
mov ecx,100
div ecx
or edx,edx
je loc001
mov eax,ebx
xor edx,edx
mov ecx,4
div ecx
or edx, edx
jne loc001
loc002: inc dword ptr [esp+1Ch] ;returnEAX
loc001: popad
ret
_IsLeapYear endp
;==============取对应阳历年月的天数============
; 输入:年份,月份
; 输出:eax = 天数
_GetMonthDays proc dwYear:dword,dwMonth:dword
mov ah,byte ptr dwMonth
cmp ah,8
setnc al
add al,ah ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
and al,1
add al,30
cmp ah,2
jne l01
invoke _IsLeapYear,dwYear
add al,28
l01: movzx eax,al
ret
_GetMonthDays endp
;==================================
_GetWeekDay proc dwYear:dword,dwMonth:dword,dwDay:dword
pushad
movzx esi,word ptr dwYear
mov bh,byte ptr dwMonth
mov bl,byte ptr dwDay
dec esi
mov edi,esi ;每年加1天(365/7余数是1)
cmp bh,3 ;以下计算闰年数
cmc
adc esi,0 ;2月份之前不含本年
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
movzx eax,bh ;以下计算前一月到年头的天数
dec al
shl eax,1
add edi,eax ;每月先以30计算(30/7余数是2)
cmp bh,8
setnc al
add al,bh ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr al,1 ;1~12月得数:(0),1,(1),2,(2),3,(3),(4),5,(5),6,(6)
add edi,eax ;大月天数
cmp bh,3
setnc al
shl al,1
sub edi,eax ;平月减二
mov al,bl
add eax,edi ;日数
xor edx,edx
mov ecx,7
div ecx
mov dword ptr [esp+1Ch],edx ;returnEAX
popad
ret
_GetWeekDay endp
;===============================================
HgnMs dq 31556925.9747 ;每回归年秒数
OneDay dd 86400 ;每天秒数
sTermInfo dw 0,0,51,212,505,974,1619,2465,3485,4679,5992,7405,8847,10285,\
11651,12913,14022,14958,15703,16258,16635,16856,16956,16974
_sTermOff proc dwYear:dword,dwMonth:dword
local @Temp1:dword,@Temp2
local @Rag1:word,@Rag2:word
pushad
xor eax,eax
mov @Temp1,eax
mov @Temp2,eax
cmp dwYear,1900
jb l002
cmp dwMonth,12
jae l002
finit
fstcw @Rag1
fwait
mov ax,@Rag1
and ah,0F3h ;清圆整控制
or ah,8 ;圆整控制=10(舍入)
mov @Rag2,ax
fldcw @Rag2
mov eax,dwYear
sub eax,1900
mov @Temp2,eax
fild @Temp2
fmul HgnMs ;回归年换算成秒
mov ebx,dwMonth
shl ebx,1
mov eax,21208
mul ebx
add eax,7325 ;5-2"5'
mov edx,eax
movzx ecx,sTermInfo[ebx*2]
add eax,ecx ;该月第一个节气距小寒的分数
imul eax,60
mov @Temp1,eax
fild @Temp1
fadd st,st(1)
fidiv OneDay
fwait
fistp @Temp1 ;输出
;====
mov eax,edx
add eax,21208
movzx ecx,sTermInfo[ebx*2+2]
add eax,ecx ;该月第一个节气距小寒的分数
imul eax,60
mov @Temp2,eax
fiadd @Temp2
fidiv OneDay
fwait
fistp @Temp2 ;输出
;====
mov esi,dwYear
dec esi
mov edi,esi
imul edi,365 ;每年365天
cmp dwMonth,2
cmc
adc esi,0
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
mov ah,byte ptr dwMonth
mov al,ah
inc al
cmp ah,2
jb l001
cmp ah,7
setnc al
inc al
add al,ah
shr al,1
dec al
l001: movzx ebx,al
dec ebx
mov al,30
mul ah
add bx,ax
add edi,ebx
sub edi,693595 ;1900.1.1总天数
fwait
sub @Temp1,edi
sub @Temp2,edi
fldcw @Rag1
l002: popad
mov eax,@Temp1
mov ah,byte ptr @Temp2
ret
_sTermOff endp
;=======================================
_GetHolDay proc dwYear:dword,dwMonth:dword,dwDay:dword
mov eax,dwMonth
dec eax
invoke _sTermOff,dwYear,eax
push ecx
mov ecx,eax
xor eax,eax
cmp cl,byte ptr dwDay
je loc01
cmp ch,byte ptr dwDay
jne loc02
inc eax
loc01: inc eax
mov ecx,dwMonth
dec ecx
shl ecx,1
add eax,ecx
loc02: pop ecx
ret
_GetHolDay endp
;===================================
_GetBetweenDays proc dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:dword,dwDay2:dword
pushad
movzx esi,word ptr dwYear1
mov bh,byte ptr dwMonth1
mov bl,byte ptr dwDay1
mov ebp,1
l01: dec esi
mov edi,esi
imul edi,365 ;每年365天
cmp bh,3 ;以下计算闰年数
cmc
adc esi,0 ;2月份之前不含本年
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
movzx eax,bh ;以下计算前一月到年头的天数
dec al
imul eax,30 ;每月先以30计算
add edi,eax
cmp bh,8
setnc al
mov ah,0
add al,bh ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr al,1
add edi,eax ;加大月天数
cmp bh,3
setnc al
shl al,1
sub edi,eax ;平月减二
mov al,bl
add edi,eax ;日数
or ebp,ebp
jz l02
mov [esp+1Ch],edi ;returnEAX
mov ebp,[esp+8]
movzx esi,word ptr dwYear2
mov bh,byte ptr dwMonth2
mov bl,byte ptr dwDay2
xor ebp,ebp
jmp l01
l02: sub [esp+1Ch],edi ;returnEAX
popad
ret
_GetBetweenDays endp
;=============================
_GetLunarYearDays proc dwYear:dword
pushad
mov edx,dwYear
cmp edx,2050
ja toerr
sub dx,1900
jb toerr
mov bx,LunarInfo[edx*2]
mov ecx,12
xor eax,eax
loc3: shl bx,1
adc eax,29
loop loc3
or bx,bx
jz loc4
mov cl,dl
and cl,7
inc cl
shr edx,3
mov dl,leapBigTab[edx]
shl dl,cl
adc eax,29
loc4: jmp toRet
toerr: mov eax,12*30
toRet: mov [esp+1Ch],eax ;returnEAX
popad
ret
_GetLunarYearDays endp
;=============================
_GetLunarMonthDays proc dwYear:dword,dwMonth:dword
pushad
mov edx,dwYear
cmp edx,2050
ja toerr
sub dx,1900
jb toerr
mov ecx,dwMonth
cmp ecx,12
ja toerr
cmp cl,1
jb toerr
movzx ebx,LunarInfo[edx*2]
mov esi,ebx
xor eax,eax
shl bx,cl
adc eax,29
and esi,0Fh
cmp esi,ecx
jnz toRet
mov cl,dl
and cl,7
inc cl
shr edx,3
mov dl,leapBigTab[edx]
shl dl,cl
adc ah,29
jmp toRet
toerr: mov eax,30
toRet: mov [esp+1Ch],eax ;returnEAX
popad
ret
_GetLunarMonthDays endp
;=====================================
_GetLunarData proc _lpstLunarData:dword
assume esi:ptr LUNARDATA
local AllDay:dword,ThisYear,ThisMonth,ThisDay,AllDays
mov eax,-1
pushad
mov esi,_lpstLunarData
lea edi,[esi].dwLunarYear
mov ecx,sizeof LUNARDATA-6
inc eax
cld
rep stosb
movzx edx,[esi].dwYear
cmp edx,1901
jb OverErr
cmp edx,2050
ja OverErr
movzx ebx,[esi].dwMonth
cmp ebx,1
jb OverErr
cmp ebx,12
ja OverErr
invoke _GetMonthDays,edx,ebx
movzx ecx,[esi].dwDay
cmp ecx,1
jb OverErr
cmp ecx,31
ja OverErr
invoke _GetBetweenDays,edx,ebx,ecx,1901,1,1
mov AllDays,eax
mov ThisYear,1900
mov ThisMonth,11
mov ecx,eax
add cl,11
mov ThisDay,ecx
cmp eax,19
jb loc07
sub eax,18
inc ThisMonth
mov ThisDay,eax
cmp eax,31
jb loc07
sub eax,31
inc ThisYear
mov ThisMonth,1
mov ThisDay,1
mov AllDay,eax
loc01: invoke _GetLunarYearDays,ThisYear
cmp AllDay,eax
jb loc02
sub AllDay,eax
inc ThisYear
jmp loc01
loc02: invoke _GetLunarMonthDays,ThisYear,ThisMonth
movzx edx,ah
mov ah,0
cmp AllDay,eax
jb loc06
sub AllDay,eax
cmp AllDay,edx
jb loc05
sub AllDay,edx
loc04: inc ThisMonth
jmp loc02
loc05: mov [esi].dbIsLeapMonth,1
loc06: mov eax,AllDay
add ThisDay,eax
loc07: mov eax,ThisYear
mov [esi].dwLunarYear,ax
mov eax,ThisMonth
mov [esi].dbLunarMonth,al
mov eax, dword ptr ThisDay
mov [esi].dbLunarDay,al
movzx edx,[esi].dwYear
movzx ebx,[esi].dwMonth
movzx ecx,[esi].dwDay
invoke _GetWeekDay,edx,ebx,ecx
mov [esi].dbWeekDay,al
invoke _GetHolDay,edx,ebx,ecx
mov [esi].noLunarHolDay,al
mov ecx,60
movzx eax,[esi].dwLunarYear
add eax,56
cdq
div ecx
mov [esi].noLunarYear,dl
movzx eax,[esi].dwLunarYear
imul eax,12
movzx edx,[esi].dbLunarMonth
add eax,edx
add eax,13
cdq
div ecx
mov [esi].noLunarMonth,dl
mov eax,AllDays
add eax,15
cdq
div ecx
mov [esi].noLunarDay,dl
mov dword ptr [esp+1Ch],0 ;returnEAX
OverErr: popad
ret
assume esi:nothing
_GetLunarData endp
;===========================
Hz_NumStr db '一二三四五六七八九'
Hz_TenStr db '十'
Hz_NumHStr db '初十廿'
_GetLunarStr proc _lpstLunarData:dword,lpBuffer:dword
assume esi:ptr LUNARDATA
pushad
mov esi,_lpstLunarData
mov edi,lpBuffer
cmp [esi].dbIsLeapMonth,1
jne l_002
mov ax,0F2C8h ;'闰'
stosw
l_002: movzx ebx,[esi].dbLunarMonth
cmp bl,12
ja l_005
cmp bl,1
jb l_005
mov ax,0FDD5h ;'正'
je l_004
cmp bl,11
jb l_003
mov ax,word ptr Hz_TenStr ;'十'
stosw
sub bl,10
l_003: dec bl
mov ax, word ptr Hz_NumStr[2*ebx]
l_004: stosw
mov ax, 0C2D4h ;'月'
stosw
l_005: mov bl,[esi].dbLunarDay
cmp bl,30
ja l_008
mov edx,9
mov ax, word ptr Hz_NumStr[4]
je l_007
mov ax, word ptr Hz_NumStr[2]
cmp bl,20
je l_007
mov al,bl
dec al
js l_008
movzx eax,al
cdq
mov ecx,10
div ecx
mov ax, word ptr Hz_NumHStr[2*eax]
l_007: stosw
mov ax, word ptr Hz_NumStr[2*edx]
stosw
l_008: mov al,0
stosb
popad
assume esi:nothing
ret
_GetLunarStr endp
;**************************************************
Tg_Str db '甲乙丙丁戊己庚辛壬癸'
Dz_Str db '子丑寅卯辰巳午未申酉戌亥'
_GetGzStr proc GzNumber:dword
pushad
mov eax,GzNumber
mov cl,10
div cl
movzx ebx,ah
mov eax,GzNumber
mov cl,12
div cl
movzx edx,ah
mov ax, word ptr Tg_Str[2*ebx]
mov word ptr [esp+1Ch],ax
mov ax, word ptr Dz_Str[2*edx]
mov word ptr [esp+1Ch][2],ax
popad
ret
_GetGzStr endp
;**************************************************
Sx_Str db '鼠牛虎免龙蛇马羊猴鸡狗猪'
Wx_Str db '金木水火土'
_GetSxStr proc GzNumber:dword
xor eax,eax
pushad
mov eax,GzNumber
mov cl,12
div cl
movzx edx,ah
mov ax, word ptr Sx_Str[2*edx]
mov word ptr [esp+1Ch],ax
mov ecx,GzNumber
shr ecx,1
cmp cl,15
jb l001
sub cl,15
l001: mov eax,42304130h
cmp cl,8
jb l002
sub cl,8
mov eax,2134210h
l002: shl cl,2
shr eax,cl
and al,0Fh
movzx eax,al
mov ax,word ptr Wx_Str[eax*2]
mov word ptr [esp+1Ch][2],ax
popad
ret
_GetSxStr endp
;=======================================
Hd_str db '小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至',\
'小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至'
_GetHDStr proc HdNumber:dword
mov eax,HdNumber
or eax,eax
jz l001
dec eax
mov eax,dword ptr Hd_str[eax*4]
l001: ret
_GetHDStr endp
;作者:狂编
;
;本次公开愿代码,意在交流,绝对没有丝毫的炫耀的意思。
;希望大家有好的代码,拿出来赐教。
;=============检测阳历对应年份是否闰年==========
; 输入:年份
; 输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear proto dwYear:dword
;=============取阳历对应年月的天数==============
; 输入:年份,月份
; 输出:eax = 天数
_GetMonthDays proto dwYear:dword,dwMonth:dword
;=============取阳历对应星期几==================
; 输入:年份,月份,日
; 输出:eax=星期,星期日=0,星期一=1...
_GetWeekDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=============取对应阳历月的节气日==============
; 输入:年份,月份
; 输出:al =第一节气日,ah =第二节气日
_sTermOff proto dwYear:dword,dwMonth:dword
;=============取对应阳历日期的节气序号==========
; 输入:年份,月份,日
; 输出:eax=节气序号,小寒=1,大寒=2...
_GetHolDay proto dwYear:dword,dwMonth:dword,dwDay:dword
;=============取两个阳历日期之间的天数==========
; 输入:年份1,月份1,日1,年份2,月份2,日2(第一个为被减数)
; 输出:天数
_GetBetweenDays proto dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:dword,dwDay2:dword
;=============取农历年的天数====================
; 输入:年份
; 输出:天数
_GetLunarYearDays proto dwYear:dword
;=============取农历月的天数====================
; 输入:年份,月份
; 输出:天数
_GetLunarMonthDays proto dwYear:dword,dwMonth:dword
;=============填充农历数据结构==================
; 输入:农历数据结构指针(其中阳历必须已填好)
_GetLunarData proto _lpstLunarData:dword
;=============取农历月日字符串==================
; 输入:已填充好农历数据结构指针
; 输出:字符串缓冲区指针(最少13字节)
_GetLunarStr proto _lpstLunarData:dword,lpBuffer:dword
;=============干支序号转换成字符==================
; 输入:干支序号
; 输出:eax=字符
_GetGzStr proto GzNumber:dword
;=============干支序号转换五行生肖==============
; 输入:干支序号
; 输出:eax=低16位生肖,高16位五行
_GetSxStr proto GzNumber:dword
;=============节气序号转换字符=================
; 输入:节气序号
; 输出:eax=节气序号字符
_GetHDStr proto HdNumber:dword
;**************************************************
LUNARDATA struct
dwYear dw ? ;输入参数 - 年,十进制,例如 2000
dwMonth dw ? ;输入参数 - 月,十进制,例如 10
dwDay dw ? ;输入参数 - 日,十进制,例如 1
dwLunarYear dw ? ;农历年,如 2000
dbLunarMonth db ? ;农历月,如 12
dbLunarDay db ? ;农历日,如 31
dbWeekDay db ? ;星期,星期日=0,星期一=1...
dbIsLeapMonth db ? ;是否是闰月,返回 1 为农历闰月
noLunarYear db ? ;干支年,甲子=0,乙丑=1...
noLunarMonth db ? ;干支月,甲子=0,乙丑=1...
noLunarDay db ? ;干支日,甲子=0,乙丑=1...
noLunarHolDay db ? ;农历节气,小寒=1,大寒=2
LUNARDATA ends
;**************************************************
.code
LunarInfo dw 04bd8h,04ae0h,0a570h,054d5h,0d260h,0d950h,06554h,056a0h,09ad0h,055d2h
dw 04ae0h,0a5b6h,0a4d0h,0d250h,0d255h,0b540h,0d6a0h,0ada2h,095b0h,04977h
dw 04970h,0a4b0h,0b4b5h,06a50h,06d40h,0ab54h,02b60h,09570h,052f2h,04970h
dw 06566h,0d4a0h,0ea50h,06e95h,05ad0h,02b60h,086e3h,092e0h,0c8d7h,0c950h
dw 0d4a0h,0d8a6h,0b550h,056a0h,0a5b4h,025d0h,092d0h,0d2b2h,0a950h,0b557h
dw 06ca0h,0b550h,05355h,04da0h,0a5d0h,04573h,052d0h,0a9a8h,0e950h,06aa0h
dw 0aea6h,0ab50h,04b60h,0aae4h,0a570h,05260h,0f263h,0d950h,05b57h,056a0h
dw 096d0h,04dd5h,04ad0h,0a4d0h,0d4d4h,0d250h,0d558h,0b540h,0b5a0h,095a6h
dw 095b0h,049b0h,0a974h,0a4b0h,0b27ah,06a50h,06d40h,0af46h,0ab60h,09570h
dw 04af5h,04970h,064b0h,074a3h,0ea50h,06b58h,055c0h,0ab60h,096d5h,092e0h
dw 0c960h,0d954h,0d4a0h,0da50h,07552h,056a0h,0abb7h,025d0h,092d0h,0cab5h
dw 0a950h,0b4a0h,0baa4h,0ad50h,055d9h,04ba0h,0a5b0h,05176h,052b0h,0a930h
dw 07954h,06aa0h,0ad50h,05b52h,04b60h,0a6e6h,0a4e0h,0d260h,0ea65h,0d530h
dw 05aa0h,076a3h,096d0h,04bd7h,04ad0h,0a4d0h,0d0b6h,0d250h,0d520h,0dd45h
dw 0b5a0h,056d0h,055b2h,049b0h,0a577h,0a4b0h,0aa50h,0b255h,06d20h,0ada0h
dw 04b63h
leapBigTab db 00000010b,00000010b,00010000b,01000000b,00001010b
db 01001000b,00001001b,00000000b,00000000b,00000001b
db 00000000b,00000000b,00000000b,00000000b,00000100b
db 00000000b,00000000b,10000000b,00010010b
;=============检测对应年份是否闰年=============
; 输入:年份
; 输出:eax = 1 是闰年,否则 eax = 0
_IsLeapYear proc dwYear:dword
xor eax,eax
pushad
mov ebx,dwYear
mov eax,ebx
xor edx,edx
mov ecx,400
div ecx
or edx,edx
je loc002
mov eax,ebx
xor edx,edx
mov ecx,100
div ecx
or edx,edx
je loc001
mov eax,ebx
xor edx,edx
mov ecx,4
div ecx
or edx, edx
jne loc001
loc002: inc dword ptr [esp+1Ch] ;returnEAX
loc001: popad
ret
_IsLeapYear endp
;==============取对应阳历年月的天数============
; 输入:年份,月份
; 输出:eax = 天数
_GetMonthDays proc dwYear:dword,dwMonth:dword
mov ah,byte ptr dwMonth
cmp ah,8
setnc al
add al,ah ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
and al,1
add al,30
cmp ah,2
jne l01
invoke _IsLeapYear,dwYear
add al,28
l01: movzx eax,al
ret
_GetMonthDays endp
;==================================
_GetWeekDay proc dwYear:dword,dwMonth:dword,dwDay:dword
pushad
movzx esi,word ptr dwYear
mov bh,byte ptr dwMonth
mov bl,byte ptr dwDay
dec esi
mov edi,esi ;每年加1天(365/7余数是1)
cmp bh,3 ;以下计算闰年数
cmc
adc esi,0 ;2月份之前不含本年
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
movzx eax,bh ;以下计算前一月到年头的天数
dec al
shl eax,1
add edi,eax ;每月先以30计算(30/7余数是2)
cmp bh,8
setnc al
add al,bh ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr al,1 ;1~12月得数:(0),1,(1),2,(2),3,(3),(4),5,(5),6,(6)
add edi,eax ;大月天数
cmp bh,3
setnc al
shl al,1
sub edi,eax ;平月减二
mov al,bl
add eax,edi ;日数
xor edx,edx
mov ecx,7
div ecx
mov dword ptr [esp+1Ch],edx ;returnEAX
popad
ret
_GetWeekDay endp
;===============================================
HgnMs dq 31556925.9747 ;每回归年秒数
OneDay dd 86400 ;每天秒数
sTermInfo dw 0,0,51,212,505,974,1619,2465,3485,4679,5992,7405,8847,10285,\
11651,12913,14022,14958,15703,16258,16635,16856,16956,16974
_sTermOff proc dwYear:dword,dwMonth:dword
local @Temp1:dword,@Temp2
local @Rag1:word,@Rag2:word
pushad
xor eax,eax
mov @Temp1,eax
mov @Temp2,eax
cmp dwYear,1900
jb l002
cmp dwMonth,12
jae l002
finit
fstcw @Rag1
fwait
mov ax,@Rag1
and ah,0F3h ;清圆整控制
or ah,8 ;圆整控制=10(舍入)
mov @Rag2,ax
fldcw @Rag2
mov eax,dwYear
sub eax,1900
mov @Temp2,eax
fild @Temp2
fmul HgnMs ;回归年换算成秒
mov ebx,dwMonth
shl ebx,1
mov eax,21208
mul ebx
add eax,7325 ;5-2"5'
mov edx,eax
movzx ecx,sTermInfo[ebx*2]
add eax,ecx ;该月第一个节气距小寒的分数
imul eax,60
mov @Temp1,eax
fild @Temp1
fadd st,st(1)
fidiv OneDay
fwait
fistp @Temp1 ;输出
;====
mov eax,edx
add eax,21208
movzx ecx,sTermInfo[ebx*2+2]
add eax,ecx ;该月第一个节气距小寒的分数
imul eax,60
mov @Temp2,eax
fiadd @Temp2
fidiv OneDay
fwait
fistp @Temp2 ;输出
;====
mov esi,dwYear
dec esi
mov edi,esi
imul edi,365 ;每年365天
cmp dwMonth,2
cmc
adc esi,0
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
mov ah,byte ptr dwMonth
mov al,ah
inc al
cmp ah,2
jb l001
cmp ah,7
setnc al
inc al
add al,ah
shr al,1
dec al
l001: movzx ebx,al
dec ebx
mov al,30
mul ah
add bx,ax
add edi,ebx
sub edi,693595 ;1900.1.1总天数
fwait
sub @Temp1,edi
sub @Temp2,edi
fldcw @Rag1
l002: popad
mov eax,@Temp1
mov ah,byte ptr @Temp2
ret
_sTermOff endp
;=======================================
_GetHolDay proc dwYear:dword,dwMonth:dword,dwDay:dword
mov eax,dwMonth
dec eax
invoke _sTermOff,dwYear,eax
push ecx
mov ecx,eax
xor eax,eax
cmp cl,byte ptr dwDay
je loc01
cmp ch,byte ptr dwDay
jne loc02
inc eax
loc01: inc eax
mov ecx,dwMonth
dec ecx
shl ecx,1
add eax,ecx
loc02: pop ecx
ret
_GetHolDay endp
;===================================
_GetBetweenDays proc dwYear1:dword,dwMonth1:dword,dwDay1:dword,dwYear2:dword,dwMonth2:dword,dwDay2:dword
pushad
movzx esi,word ptr dwYear1
mov bh,byte ptr dwMonth1
mov bl,byte ptr dwDay1
mov ebp,1
l01: dec esi
mov edi,esi
imul edi,365 ;每年365天
cmp bh,3 ;以下计算闰年数
cmc
adc esi,0 ;2月份之前不含本年
mov eax,esi
shr eax,2
add edi,eax ;每4年一闰
mov eax,esi
xor edx,edx
mov ecx,100
div ecx
sub edi,eax ;被100整除不闰
mov eax,esi
xor edx,edx
mov ecx,400
div ecx
add edi,eax ;被400整除还是要闰
movzx eax,bh ;以下计算前一月到年头的天数
dec al
imul eax,30 ;每月先以30计算
add edi,eax
cmp bh,8
setnc al
mov ah,0
add al,bh ;1~12月得数:(1),2,(3),4,(5),6,(7),(9),10,(11),12,(13)
shr al,1
add edi,eax ;加大月天数
cmp bh,3
setnc al
shl al,1
sub edi,eax ;平月减二
mov al,bl
add edi,eax ;日数
or ebp,ebp
jz l02
mov [esp+1Ch],edi ;returnEAX
mov ebp,[esp+8]
movzx esi,word ptr dwYear2
mov bh,byte ptr dwMonth2
mov bl,byte ptr dwDay2
xor ebp,ebp
jmp l01
l02: sub [esp+1Ch],edi ;returnEAX
popad
ret
_GetBetweenDays endp
;=============================
_GetLunarYearDays proc dwYear:dword
pushad
mov edx,dwYear
cmp edx,2050
ja toerr
sub dx,1900
jb toerr
mov bx,LunarInfo[edx*2]
mov ecx,12
xor eax,eax
loc3: shl bx,1
adc eax,29
loop loc3
or bx,bx
jz loc4
mov cl,dl
and cl,7
inc cl
shr edx,3
mov dl,leapBigTab[edx]
shl dl,cl
adc eax,29
loc4: jmp toRet
toerr: mov eax,12*30
toRet: mov [esp+1Ch],eax ;returnEAX
popad
ret
_GetLunarYearDays endp
;=============================
_GetLunarMonthDays proc dwYear:dword,dwMonth:dword
pushad
mov edx,dwYear
cmp edx,2050
ja toerr
sub dx,1900
jb toerr
mov ecx,dwMonth
cmp ecx,12
ja toerr
cmp cl,1
jb toerr
movzx ebx,LunarInfo[edx*2]
mov esi,ebx
xor eax,eax
shl bx,cl
adc eax,29
and esi,0Fh
cmp esi,ecx
jnz toRet
mov cl,dl
and cl,7
inc cl
shr edx,3
mov dl,leapBigTab[edx]
shl dl,cl
adc ah,29
jmp toRet
toerr: mov eax,30
toRet: mov [esp+1Ch],eax ;returnEAX
popad
ret
_GetLunarMonthDays endp
;=====================================
_GetLunarData proc _lpstLunarData:dword
assume esi:ptr LUNARDATA
local AllDay:dword,ThisYear,ThisMonth,ThisDay,AllDays
mov eax,-1
pushad
mov esi,_lpstLunarData
lea edi,[esi].dwLunarYear
mov ecx,sizeof LUNARDATA-6
inc eax
cld
rep stosb
movzx edx,[esi].dwYear
cmp edx,1901
jb OverErr
cmp edx,2050
ja OverErr
movzx ebx,[esi].dwMonth
cmp ebx,1
jb OverErr
cmp ebx,12
ja OverErr
invoke _GetMonthDays,edx,ebx
movzx ecx,[esi].dwDay
cmp ecx,1
jb OverErr
cmp ecx,31
ja OverErr
invoke _GetBetweenDays,edx,ebx,ecx,1901,1,1
mov AllDays,eax
mov ThisYear,1900
mov ThisMonth,11
mov ecx,eax
add cl,11
mov ThisDay,ecx
cmp eax,19
jb loc07
sub eax,18
inc ThisMonth
mov ThisDay,eax
cmp eax,31
jb loc07
sub eax,31
inc ThisYear
mov ThisMonth,1
mov ThisDay,1
mov AllDay,eax
loc01: invoke _GetLunarYearDays,ThisYear
cmp AllDay,eax
jb loc02
sub AllDay,eax
inc ThisYear
jmp loc01
loc02: invoke _GetLunarMonthDays,ThisYear,ThisMonth
movzx edx,ah
mov ah,0
cmp AllDay,eax
jb loc06
sub AllDay,eax
cmp AllDay,edx
jb loc05
sub AllDay,edx
loc04: inc ThisMonth
jmp loc02
loc05: mov [esi].dbIsLeapMonth,1
loc06: mov eax,AllDay
add ThisDay,eax
loc07: mov eax,ThisYear
mov [esi].dwLunarYear,ax
mov eax,ThisMonth
mov [esi].dbLunarMonth,al
mov eax, dword ptr ThisDay
mov [esi].dbLunarDay,al
movzx edx,[esi].dwYear
movzx ebx,[esi].dwMonth
movzx ecx,[esi].dwDay
invoke _GetWeekDay,edx,ebx,ecx
mov [esi].dbWeekDay,al
invoke _GetHolDay,edx,ebx,ecx
mov [esi].noLunarHolDay,al
mov ecx,60
movzx eax,[esi].dwLunarYear
add eax,56
cdq
div ecx
mov [esi].noLunarYear,dl
movzx eax,[esi].dwLunarYear
imul eax,12
movzx edx,[esi].dbLunarMonth
add eax,edx
add eax,13
cdq
div ecx
mov [esi].noLunarMonth,dl
mov eax,AllDays
add eax,15
cdq
div ecx
mov [esi].noLunarDay,dl
mov dword ptr [esp+1Ch],0 ;returnEAX
OverErr: popad
ret
assume esi:nothing
_GetLunarData endp
;===========================
Hz_NumStr db '一二三四五六七八九'
Hz_TenStr db '十'
Hz_NumHStr db '初十廿'
_GetLunarStr proc _lpstLunarData:dword,lpBuffer:dword
assume esi:ptr LUNARDATA
pushad
mov esi,_lpstLunarData
mov edi,lpBuffer
cmp [esi].dbIsLeapMonth,1
jne l_002
mov ax,0F2C8h ;'闰'
stosw
l_002: movzx ebx,[esi].dbLunarMonth
cmp bl,12
ja l_005
cmp bl,1
jb l_005
mov ax,0FDD5h ;'正'
je l_004
cmp bl,11
jb l_003
mov ax,word ptr Hz_TenStr ;'十'
stosw
sub bl,10
l_003: dec bl
mov ax, word ptr Hz_NumStr[2*ebx]
l_004: stosw
mov ax, 0C2D4h ;'月'
stosw
l_005: mov bl,[esi].dbLunarDay
cmp bl,30
ja l_008
mov edx,9
mov ax, word ptr Hz_NumStr[4]
je l_007
mov ax, word ptr Hz_NumStr[2]
cmp bl,20
je l_007
mov al,bl
dec al
js l_008
movzx eax,al
cdq
mov ecx,10
div ecx
mov ax, word ptr Hz_NumHStr[2*eax]
l_007: stosw
mov ax, word ptr Hz_NumStr[2*edx]
stosw
l_008: mov al,0
stosb
popad
assume esi:nothing
ret
_GetLunarStr endp
;**************************************************
Tg_Str db '甲乙丙丁戊己庚辛壬癸'
Dz_Str db '子丑寅卯辰巳午未申酉戌亥'
_GetGzStr proc GzNumber:dword
pushad
mov eax,GzNumber
mov cl,10
div cl
movzx ebx,ah
mov eax,GzNumber
mov cl,12
div cl
movzx edx,ah
mov ax, word ptr Tg_Str[2*ebx]
mov word ptr [esp+1Ch],ax
mov ax, word ptr Dz_Str[2*edx]
mov word ptr [esp+1Ch][2],ax
popad
ret
_GetGzStr endp
;**************************************************
Sx_Str db '鼠牛虎免龙蛇马羊猴鸡狗猪'
Wx_Str db '金木水火土'
_GetSxStr proc GzNumber:dword
xor eax,eax
pushad
mov eax,GzNumber
mov cl,12
div cl
movzx edx,ah
mov ax, word ptr Sx_Str[2*edx]
mov word ptr [esp+1Ch],ax
mov ecx,GzNumber
shr ecx,1
cmp cl,15
jb l001
sub cl,15
l001: mov eax,42304130h
cmp cl,8
jb l002
sub cl,8
mov eax,2134210h
l002: shl cl,2
shr eax,cl
and al,0Fh
movzx eax,al
mov ax,word ptr Wx_Str[eax*2]
mov word ptr [esp+1Ch][2],ax
popad
ret
_GetSxStr endp
;=======================================
Hd_str db '小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至',\
'小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至'
_GetHDStr proc HdNumber:dword
mov eax,HdNumber
or eax,eax
jz l001
dec eax
mov eax,dword ptr Hd_str[eax*4]
l001: ret
_GetHDStr endp
浙公网安备 33010602011771号