Code : Tout sélectionner
; DWORD DateToAbsDayNum(DWORD Y, DWORD M, DWORD D, DWORD Gregorian)
;
; This function calculates the absolute day number for the given date.
;
; Parameters:
; Y - year,
; M - month,
; D - day,
; Gregorian - chosen calendar (0 - Julian, 1 - Gregorian).
;
; Returned values:
; * 1, 2, ..., 2^32-1 for the valid date in the chosen calendar,
; * 0 for the invalid parameters.
;
;proc DateToAbsDayNum, Y, M, D, Gregorian
Procedure.l DateToAbsDayNum( Y.l, M.l, D.l, Gregorian.l)
;;PUSHFD
;PUSH ebx ecx edx
Protected X.l
EnableASM
TEST Gregorian, -2 ; 0 <= Gregorian <= 1
JNZ l_datetoabsdaynum_error ;
IsLeapYear(Y, Gregorian) ;
CMP eax, -1 ; eax := IsLeapYear(Y, Gregorian)
JE l_datetoabsdaynum_error ;
; Y <> 0
;MOV ebx, eax ; ebx := eax
MOV X, eax
MDToDayNum(M, D, X) ;ebx
CMP eax, -1 ; eax := MDToDayNum(M, D, ebx) = n
JE l_datetoabsdaynum_error ;
MOV ecx, Y ;
CMP ecx, 0 ; ecx := Y
JG l_datetoabsdaynum_calculatedaynum ;
INC ecx ; Y < 0
; ecx := ecx + 1 = Y + 1 = Y + [Y < 0]
calculatedaynum:
; Global k = 30
; Global J = 194796 ; The constants J and G are equal to the numbers of the complete years
; Global G = 194800 ; of the Julian and Gregorian calendars respectively contained in the
; time interval given by "Great Cycle" T.
ADD ecx, 5843880; k*J ;
CMP Gregorian, 0 ; ecx := ecx + kJ + k(G-J)[Gregorian = 1] =
JE l_datetoabsdaynum_yprim0 ; = Y + [Y < 0] + kJ + k(G-J)[Gregorian = 1] = Y'
ADD ecx, 120; k*(G-J) ;
; Global k = 30
; Global J = 194796 ; The constants J and G are equal to the numbers of the complete years
; Global G = 194800 ; of the Julian and Gregorian calendars respectively contained in the
; time interval given by "Great Cycle" T.
yprim0:
CMP ecx, 0 ;
JNE l_datetoabsdaynum_yprimpositive ; Y' = 0
SUB eax, 364 ; eax := eax - 364 = n - 364
JMP l_datetoabsdaynum_theend ;
yprimpositive: ; Y' > 0
;
DEC ecx ; ecx := ecx - 1 = Y' - 1
;MOV ebx, eax ; ebx := eax = n
MOV X, eax
MOV eax, 365 ; eax := 365
MUL ecx ; eax := 365 * ecx = 365(Y' - 1);(EDX:EAX <- EAX * r/m32
SHR ecx, 2 ; ecx := E(ecx / 4) = E((Y' - 1) / 4)
ADD eax, ecx ; eax := eax + ecx = 365(Y' - 1) + E((Y' - 1) / 4)
;ADD eax, ebx ; eax := eax + ebx = eax + n =
ADD eax, X ; = 365(Y' - 1) + E((Y' - 1) / 4) + n
CMP Gregorian, 0
JZ l_datetoabsdaynum_theend
gregorian:
;PUSH eax ; X := eax
MOV X, eax ; Sauvegarde de eax
;Debug X
XOR edx, edx ;
MOV eax, ecx ; eax := ecx = E((Y' - 1) / 4)
MOV ecx, 25 ;
DIV ecx ; eax := E(eax / 25) = E(E((Y' - 1) / 4) / 25) =
; = E((Y' - 1) / 100)
;Unsigned divide EDX:EAX by r/m32, with
;result stored IN EAX <- Quotient, EDX <- Remainder.
MOV ecx, eax ; ecx := eax = E((Y' - 1) / 100)
;POP eax ; eax := X = 365(Y' - 1) + E((Y' - 1) / 4) + n
MOV eax, X
SUB eax, ecx ; eax := eax - ecx = 365(Y' - 1) + E((Y' - 1) / 4) + n -
; - E((Y' - 1) / 100)
SHR ecx, 2 ; ecx : = E(ecx / 4) = E(E((Y' - 1) / 100) / 4) =
; = E((Y' - 1) / 400)
ADD eax, ecx ; eax := eax + ecx = 365(Y' - 1) + E((Y' - 1) / 4) + n -
; - E((Y' - 1) / 100) + E((Y' - 1) / 400)
ADD eax, 2 ; eax := eax + 2 = 365(Y' - 1) + E((Y' - 1) / 4) + n -
; - E((Y' - 1) / 100) + E((Y' - 1) / 400) + 2 =
; = N
JMP l_datetoabsdaynum_theend
error:
;Debug "err"
XOR eax, eax
theend:
;POP edx ecx ebx
;POPFD
DisableASM
ProcedureReturn
EndProcedure
Debug DateToAbsDayNum( 2000, 1, 1, 1);Y.l, M.l, D.l, Gregorian.l