Obsah / Utility / CALENDAR / Inkrementace a dekrementace data
Zdrojový kód:
INCLUDE\UTIL\CALENDAR.INC, UTIL\CALENDAR.ASM
Inkrementace
a dekrementace data
; -----------------------------------------------------------------------------
; Increase date-time by one day
; -----------------------------------------------------------------------------
; INPUT: EBX = date-time structure (see DATETIME)
; OUTPUT: CY = invalid date (structure has not been changed)
; NOTES: Date entries are verified only partially.
; -----------------------------------------------------------------------------
; ------------- Push registers
DateTimeAddDay: push eax ; push EAX
push ecx ; push ECX
push edx ; push EDX
; ------------- Increase day in month
mov eax,[ebx+DATETIME_Date] ; EAX <- date
inc eax ; increase day in month
cmp eax,(SPLITYEAR*256 + 10)*256 + 5 ; date 10/5/1582
setne dl ; DL <- 0=date 10/5/1582, 1=not
dec edx ; DL <- 0ffh=date 10/5/1582, 0=not
and dl,10 ; DL <- 10=date 10/5/1582, 0=not
add al,dl ; date correction for 10/5/1582
cmp al,28 ; maximal date we need not to check
jbe DateTimeAddDay6 ; new date is OK
; ------------- Check day in month
shld ecx,eax,16 ; CX <- year
xchg al,ah ; AL <- month, AH <- day in month
xchg eax,edx ; DL <- month, DH <- day in month
call GetLastDayMonth ; get last day in month -> AL
xchg eax,edx ; AL <- month, AH <- day, DL<-last day
xchg al,ah ; AL <- day in month, AH <- month
jc DateTimeAddDay8 ; invalid month or year
cmp al,dl ; check day in month
jbe DateTimeAddDay6 ; new day is OK
; ------------- Increase month
mov al,1 ; AL <- 1, first day in next month
inc ah ; AH <- next month
cmp ah,12 ; check month
jbe DateTimeAddDay6 ; next month is OK
; ------------- Increase year
mov ah,1 ; AH <- 1, first month in next year
inc ecx ; increase year
cmp cx,MAXYEAR ; maximal year
stc ; set error flag
jg DateTimeAddDay8 ; invalid year
add eax,10000h ; increase year
; ------------- Set new date
DateTimeAddDay6:mov [ebx+DATETIME_Date],eax ; store new date
clc ; clear error flag
; ------------- Pop registers
DateTimeAddDay8:pop edx ; pop EDX
pop ecx ; pop ECX
pop eax ; pop EAX
ret
|
Pomocí funkce
DateTimeAddDay je možné zvýšit datum ve struktuře DATETIME o
jeden den. Ukazatel na strukturu DATETIME je funkci předán v
registru EBX. Funkce mění pouze položky den v měsíci,
měsíc a rok, ostatní položky (např. den v týdnu)
zůstávají neovlivněny. Funkce provádí pouze nejnutnější
testy platnosti položek. Při chybě navrátí nastavený
chybový příznak CF a obsah struktury DATETIME zůstane
nezměněn. Jsou-li potřebné i rozšiřující informace o
datu, je možné dodatečně zavolat funkci DateTimeExt.
Funkce nejdříve
načte datum ze struktury DATETIME. Pokud se jedná o speciální
případ 5.10.1582, zvýší se den v měsíci o 10 dnů, jinak
se zvýší o 1 den. Pro den v měsíci 28 nebo nižší není
potřeba dělat další obsluhu a funkce se ukončí.
Pro den 29 a vyšší
je nutné provést test přetečení data do dalšího měsíce.
Pomocí funkce GetLastDayMonth se zjistí číslo posledního dne
v měsíci a porovnáním se zjistí, zda den v měsíci přetekl
do dalšího měsíce. Pokud ano, nastaví se den v měsíci na 1
a zvýší se číslo měsíce.
Pokud měsíc
přetekl přes hodnotu 12, nastaví se měsíc na hodnotu 1 a
zvýší se číslo roku. Pokud by i rok přetekl přes povolenou
maximální hodnotu, funkce navrátí nastavený příznak chyby
CF a datum ve struktuře se nezmění. Při úspěšné operaci
se uloží nová hodnota data do struktury DATETIME.
; -----------------------------------------------------------------------------
; Decrease date-time by one day
; -----------------------------------------------------------------------------
; INPUT: EBX = date-time structure (see DATETIME)
; OUTPUT: CY = invalid date (structure has not been changed)
; NOTES: Date entries are verified only partially.
; -----------------------------------------------------------------------------
; ------------- Push registers
DateTimeSubDay: push eax ; push EAX
push edx ; push EDX
; ------------- Decrease day in month
mov eax,[ebx+DATETIME_Date] ; EAX <- date
cmp eax,(SPLITYEAR*256 + 10)*256 + 15 ; date 10/15/1582
setne dl ; DL <- 0=date 10/15/1582, 1=not
dec edx ; DL <- 0ffh=date 10/15/1582, 0=not
and dl,10 ; DL <- 10=date 10/15/1582, 0=not
inc edx ; DL <- correction + 1 day
sub al,dl ; decrease day in month
jnz DateTimeSubDay6 ; new date is OK
; ------------- Push registers 2
push ecx ; push ECX
; ------------- Decrease month
shld ecx,eax,16 ; CX <- year
dec ah ; decrease month
jnz DateTimeSubDay2 ; new month is OK
; ------------- Decrease year
dec ecx ; decrease year
sub eax,0F400h ; decrease year, set month to 12
; ------------- Get last day in previous month
DateTimeSubDay2:mov dl,ah ; DL <- month
call GetLastDayMonth ; get last day in month -> AL
; ------------- Pop registers 2
pop ecx ; pop ECX
jc DateTimeSubDay8 ; invalid month or year
; ------------- Set new date
DateTimeSubDay6:mov [ebx+DATETIME_Date],eax ; store new date
clc ; clear error flag
; ------------- Pop registers
DateTimeSubDay8:pop edx ; pop EDX
pop eax ; pop EAX
ret
|
Pomocí funkce
DateTimeSubDay je možné snížit datum ve struktuře DATETIME o
jeden den. Ukazatel na strukturu DATETIME je funkci předán v
registru EBX. Funkce mění pouze položky den v měsíci,
měsíc a rok, ostatní položky (např. den v týdnu)
zůstávají neovlivněny. Funkce provádí pouze nejnutnější
testy platnosti položek. Při chybě navrátí nastavený
chybový příznak CF a obsah struktury DATETIME zůstane
nezměněn. Jsou-li potřebné i rozšiřující informace o
datu, je možné dodatečně zavolat funkci DateTimeExt.
Funkce nejdříve
načte datum ze struktury DATETIME. Pokud se jedná o speciální
případ 15.10.1582, sníží se den v měsíci o 10 dnů, jinak
se sníží o 1 den. Pokud den v měsíci nedosáhl hodnoty nula,
nedošlo k přetečení do předešlého měsíce a funkce se
ukončí.
Při dosažení dne 0
se do registru ECX připraví číslo roku a sníží se číslo
měsíce. Pokud měsíc dosáhl hodnoty 0, dochází k
přetečení do předešlého roku. V tom případě se sníží
číslo roku a měsíc se nastaví na hodnotu 12.
Pomocí funkce
GetLastDayMonth se zjistí číslo posledního dne v předešlém
měsíci a toto číslo se stane novým dnem v měsíci. Pokud
funkce nevrátí chybový kód (indikující neplatný rok nebo
měsíc), uloží se nové datum a funkce se ukončí. Při
chybě se funkce ukončí bez změny struktury DATETIME.
Obsah / Utility / CALENDAR / Inkrementace a dekrementace data