Hi DateTime Fans;
If you have downloaded MASM32 you should have Datetime it's a bunch
of files that manipulate the date and time. Alex Lyon made these files.
\masm32\datetime
Please Console Build we are using inkey which is Console Keyboard
input!
This program DOW.ASM uses this Library Datetime. DOW i e Day of Week.
; DoW.ASM Thursday, August 29, 2013 5:01:42 AM
; Day of Week
INCLUDE \masm32\include\masm32rt.inc
INCLUDE \masm32\include\DateTime.inc
INCLUDELIB \masm32\lib\DateTime.lib
.DATA
stUtc SYSTEMTIME<>; Local Time
dtUtc SYSTEMTIME<>
Ptext dd 0
Buff db 120 dup(0)
db 0
dateformat db " dddd MMMM dd, yyyy", 0
timeformat db "hh:mm:ss tt",0
pzTitle db "Your Local Time & Time Zone "
date_buf db 260 dup (?)
db 20 dup (?)
db 0
FirstSpace db " " ; Add a Space!
StdOutBuf db 148 dup(0)
db 0
CrLf db 13, 10, 0
TDow db " Day of Week ",0
TMoy db " Month of Year ",0
SB db " ",0 ; Single SPace
ST_DOWName equ $
db "Sunday ",0
db "Monday ",0
db "Tuesday ",0
db "Wednesday ",0
db "Thursday ",0
db "friday ",0
db "Saturday ",0
db 0
ST_MOYName equ $
db "January ",0
db "February ",9
db "March ",0
db "April ",0
db "May ",0
db "June ",0
db "july ",0
db "August ",0
db "September ",0
db "October ",0
db "November ",0
db "December ",0
db 0
.CODE
align 4
PCrLf proc
invoke StdOut, addr CrLf
ret
PCrLf endp
align 4
PSp proc uses esi
mov esi, offset SB
call P
ret
PSp endp
align 4
DayOfWeek PROC pdt:PTR DATETIME
; Return in eax
; Sunday = 0, Monday = 1, ... Saturday = 6
LOCAL _st:SYSTEMTIME
INVOKE FileTimeToSystemTime, pdt, ADDR _st
.IF eax == 0
mov eax, -1
.ELSE
movzx eax, _st.wDayOfWeek
.ENDIF
ret
DayOfWeek ENDP
align 4
CX_TH proc
; ESI > Table
; ECX is entry in table we
; want.
; find cx_th entry in table
test ecx, ecx
jz cx_th_exit
dec ecx ; is it first entry
jz cx_th_exit; is first then exit
@@:
lodsb
and al,al ; is byte equal zero
jnz @B; search for zero
dec ecx
jnz @B; find cx_th zero
cx_th_exit:
; cx_th zero found exit
ret
CX_TH endp
align 4
CX_TH_Entry proc uses ecx
call CX_TH
ret
CX_TH_Entry endp
align 4
P proc uses ecx ; Print to Console ESI
invoke StdOut, esi
ret
P endp
align 4
NL proc uses esi ; Print CrLf to Console
mov esi, offset CrLf
call P
ret
NL endp
align 4
; Copy ESI byte to EDI byte until ESI byte = Zero
;
copy_till_byte_Zero proc
lodsb ; esi = source
stosb ; edi = destination
and al, al
jz @f
jmp copy_till_byte_Zero
@@: ; Zero Exit
ret
copy_till_byte_Zero endp
align 4
start proc
INVOKE GetLocalTime, ADDR stUtc
INVOKE SystemTimeToFileTime, ADDR stUtc, ADDR dtUtc
cld ; Direction Flag Up
mov esi, offset StdOutBuf
INVOKE CurrentTimeZoneName, esi
inc eax
jz err_tz
@@:
lodsb
and al, al
jnz @B
mov byte ptr [ esi ], 0
invoke GetDateFormat, 0, 0, \
ADDR stUtc, ADDR dateformat, ADDR date_buf, 240
mov ecx, offset date_buf
add ecx, eax; add length returned by GetDateFormat
mov byte ptr [ ecx-1 ], ' '; replace null with space
invoke GetTimeFormat, 0, 0, \
ADDR stUtc, ADDR timeformat, ecx, 20
invMess:
invoke lstrcat, addr date_buf, addr FirstSpace
invoke MessageBox, 0, addr pzTitle, addr date_buf, MB_OK
call PCrLf
invoke StdOut, addr date_buf
call PCrLf
inkey " $$ You Must Hit Any Key to END process! $$ "
call PCrLf
invoke DayOfWeek, ADDR dtUtc
inc eax
jz @F
mov ecx, eax
mov esi, offset ST_DOWName
call CX_TH
mov Ptext, esi
push esi
call PSp
call P
call PCrLf
pop esi
mov edi, offset StdOutBuf
call copy_till_byte_Zero
invoke MessageBox, 0, addr FirstSpace, addr TDow, MB_OK
mov esi, offset ST_MOYName
mov ax, stUtc.wMonth
and ax, ax
jz er_month
dec eax
mov ecx, eax
call CX_TH
push esi
call PSp
call P
call PCrLf
pop esi
mov edi, offset StdOutBuf
call copy_till_byte_Zero
invoke MessageBox, 0, addr FirstSpace, addr TMoy, MB_OK
inkey
exit
ret
@@:
inkey " ** Day of Week - Range Error < 0 or > 6 ** "
call PCrLf
exit
ret
er_month:
inkey " ** Month of Year - Range Error = 0 ** "
exit
ret
start endp
align 8
err_tz:
print "Time Zone Not Set",7,13,10; 7 = Bell Noise i e Alarm
exit
ret
align 8
end_here equ $
end start
That's All Rubber Duck and DateTime Fans.
A few suggestions..
If you have a list of strings and want to select a particular one by index, you can store a list of their offsets and then index directly into that instead of searching to find the end of each string.
.data
day_name dd OFFSET day0,OFFSET day1,OFFSET day2,OFFSET day3,OFFSET day4,OFFSET day5,OFFSET day6
day0 db "Sunday ",0
day1 db "Monday ",0
day2 db "Tuesday ",0
day3 db "Wednesday ",0
day4 db "Thursday ",0
day5 db "Friday ",0
day6 db "Saturday ",0
.code
...
invoke DayOfWeek, ADDR dtUtc
mov edx,OFFSET day_name
mov ecx,[edx+4*eax]
invoke StdOut, ecx
...
Month names can be done in the same way.
Although, GetDateFormat can actually provide you with the day and month names anyway, and in the correct language.
Calling a function that only calls another function seems a little indirect, even better when that function only really then calls yet another function.
If for readability, try defining the canned function call as a macro.
Hi Tedd:
Good suggestions. I still have not figured out Datetime completely yet I get the
year 1601 and the time is out to lunch. I think iit's a problem at my end not
understnding some concept.
Quote from: Tedd on August 29, 2013, 11:51:27 PMIf you have a list of strings and want to select a particular one by index, you can store a list of their offsets and then index directly into that instead of searching to find the end of each string.
Good solution for a Million loops, but searching for the end is shorter from 3 items upwards:
Thursday is day 4
Thursday is day 4
Thursday is day 4
Thursday is day 4
Sunday is day 0
Sunday is day 0
Sunday is day 0
Sunday is day 0
28 bytes for data
11 bytes for GetDay0 <<< the offsets solution: with 3 items = 11+12=23
29 bytes for GetDay1 <<< herge
28 bytes for GetDay2 <<< repne scasb
22 bytes for GetDay3 <<< shortest lodsb solution
Quote from: jj2007 on August 30, 2013, 10:53:41 PM
Quote from: Tedd on August 29, 2013, 11:51:27 PMIf you have a list of strings and want to select a particular one by index, you can store a list of their offsets and then index directly into that instead of searching to find the end of each string.
Good solution for a Million loops, but searching for the end is shorter from 3 items upwards:
Assuming your intention is to save a small proportion of bytes in a file whose size will be rounded up to at least 512 bytes and at least 4k when loaded, rather than the obvious efficiency gain. Obviously, for a small number of strings, you can argue it makes little noticeable difference whichever method you use, but for larger numbers of strings the additional data overhead will be much less significant, not to mention the exponentially increasing time to find the required string.
Quote from: Tedd on August 30, 2013, 11:21:27 PM... for larger numbers of strings the additional data overhead will be much less significant
While the extra overhead for GetDay3 is a fixed 11 bytes, the size increase is proportional to the number of strings (plus one DWORD per string), so it becomes more significant for larger numbers of strings.
Quotenot to mention the exponentially increasing time to find the required string.
The time increases linearly, not exponentially. And, as I wrote above, your solution is better for a Million loops - finding Saturday a Million times costs already 0.17 seconds.
Hi Datetime Fans;
Latest version of Showtima.asm
console BuildPlease.
; REM SHOWTIMA.ASM Saturday, August 31, 2013 10:40:13 AM
; Console Build Please
; January 25, 2011 8:22 AM
; Author: Herge
; Location: Waterloo, Ontario, CANADA
.XCREF ; XCREF = NO cross Reference
;.XLIST ; XLIST = NO listing - Windows.inc is kind of massive man!
include \masm32\include\masm32rt.inc
INCLUDE \masm32\include\DateTime.inc
INCLUDELIB \masm32\lib\DateTime.lib
.LIST
.CREF
.data
stm SYSTEMTIME<>
StdOutBuf db 120 dup (0)
db 0
dateformat db " dddd, MMMM, dd, yyyy", 0
timeformat db "hh':'mm':'ss tt ",0
date_buf db 240 dup (0)
db 21 dup (0)
wDofW equ $
db "Sunday ",0
db "Monday ",0
db "Tuesday ",0
db "Wednesday ",0
db "Thursday ",0
db "Friday ",0
db "Saturday ",0
db 0
wMonthName equ $
db "January ",0
db "February ",0
db "March ",0
db "April ",0
db "May ",0
db "Jume ",0
db "July ",0
db "August ",0
db "September ",0
db "October ",0
db "November ",0
db "December ",0
db 0
DyMonth db "Zero ", 0
db "One ", 0
db "Two ", 0
db "Three ", 0
db "Four ", 0
db "Five ", 0
db "Six ", 0
db "Seven ", 0
db "Eight ", 0
db "Nine ", 0
db "Ten ", 0
db "Eleven ", 0
db "Twelve ", 0
db "Thirteen ", 0
db "Fourteen ", 0
db "Fifteen ", 0
db "Sixteen ", 0
db "Seventeen ", 0
db "Eighteen ", 0
db "Nineteen ", 0
db "Twenty ", 0
db "Twenty-One ", 0
db "Twenty-Two ", 0
db "Twenty-Three ", 0
db "TWO-FOUR (24) ", 0; Was Twenty-Four
; a case of beer (24 bottles)
db "Twenty-Five ", 0
db "Twenty-Six ", 0
db "Twenty-Seven ", 0
db "Twenty-Eight ", 0
db "Twenty-Nine ", 0
db "Thirty ", 0
db "Thirty-Ome ", 0
db 0
CrLf db 13,10,0
Space db " ",0
morning db " AM ",0
afternoon db " PM ",0
db 0
.code
CX_TH proc
; ESI > Table
; ECX is entry in table we
; want.
; find cx_th entry in table
test ecx, ecx
jz cx_th_exit
dec ecx ; is it first entry
jz cx_th_exit; is first then exit
@@:
lodsb
and al,al ; is byte equal zero
jnz @B; search for zero
dec ecx
jnz @B; find cx_th zero
cx_th_exit:
; cx_th zero found exit
ret
CX_TH endp
CX_TH_Entry proc uses ecx
call CX_TH
ret
CX_TH_Entry endp
public P
P proc uses ecx ; Print to Console ESI
invoke StdOut, esi
ret
P endp
NL proc uses esi ; Print CrLf to Console
mov esi, offset CrLf
call P
ret
NL endp
Pentry proc uses ecx
call CX_TH_Entry
call P
ret
Pentry endp
Pentry3 proc uses ecx esi
mov ECX, 3
CALL CX_TH_Entry
@@:
lodsb
and al,al
jz @F ; Test End of String
mov dl, al
;call put
dec ecx
jnz @B
@@:
; Premature Exit i e Entry is Not Three
; Bytes Long or we got Three Bytes.
ret
Pentry3 endp
PutSpace proc uses esi
mov esi, offset Space
call StdOut
ret
PutSpace endp
start proc
invoke GetLocalTime, addr stm; put Values in stm
movzx ecx, stm.wDayOfWeek
inc ecx
mov esi, offset wDofW
call Pentry
movzx ecx, word ptr stm.wDay
inc ecx
mov esi, offset DyMonth
call Pentry
movzx ecx, word ptr stm.wMonth
mov esi, offset wMonthName
call Pentry
movzx eax, word ptr stm.wYear
print ustr$(eax), " "
movzx eax, word ptr stm.wHour
print ustr$(eax),":"
movzx eax, word ptr stm.wMinute
print ustr$(eax),":"
movzx eax, word ptr stm.wSecond
print ustr$(eax)
movzx eax, word ptr stm.wHour
sub eax, 12
jz Pmorn
jc Pmorn
mov esi, offset afternoon
call P
jmp PTZ
Pmorn:
mov esi, offset morning
call P
PTZ:
cld ; Direction Flag Up
mov esi, offset StdOutBuf
INVOKE CurrentTimeZoneName, esi
inc eax
jz err_tz
@@:
lodsb
and al, al
jnz @B
mov byte ptr [ esi ], 0
mov esi, offset StdOutBuf
call P; Time Zone Name
call NL
inkey "Hit The Space Bar to End!"
invoke ExitProcess, 0
err_tz:
print "Time Zone Not Set",7,13,10; 7 = Bell Noise i e Alarm
exit
ret
align 8
end_here equ $
start endp
end start
Note Twenty-four is Two-four i e number
of bottles in Case of beer Or May Two-Four the Queen's
birthday and cottage opening Holiday here in Ontario,
CANADA. Close them some time in October on
Thanksgiving Day.