| Index | Manual | Download | Source | Macros | Embedded word Case ins.
Sitemap | Links | Forum | Tests | Projects

# time.htm
Constants
Structures
FILETIME
SYSTEMTIME
TIMESPEC
Macros
Time1970
Time2SystemTime

This file can be included to program for Windows or Linux written in EuroAssembler.

It declares the most often used constant symbols and structures used for time and date functions.

    time HEAD

↑ FILETIME
  The FILETIME structure used in MS Windows is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.

    FILETIME STRUC
    .dwLowDateTime  D DWORD
    .dwHighDateTime D DWORD
      ENDSTRUC FILETIME

↑ TIMESPEC
  The TIMESPEC structure used in Linux specifies a sleep time.
Example
  `TimeSpec DS TIMESPEC, .tv_sec=3, tv_nsec=200_000_000
  LinABI nanosleep, TimeSpec, 0 ; Sleep for 3.2 seconds.`

    TIMESPEC STRUC
    .tv_sec         D QWORD  ; Seconds.
    .tv_nsec        D QWORD  ; Nanoseconds (0..999_999_999).
      ENDSTRUC TIMESPEC

↑ SYSTEMTIME
  Calendary date and time converted to WORD variables.

    SYSTEMTIME STRUC
    .wYear                D WORD
    .wMonth               D WORD ; 1..12
    .wDayOfWeek           D WORD ; 0=Sunday, 1=Monday etc.
    .wDay                 D WORD ; 1..31
    .wHour                D WORD ; 0..23
    .wMinute              D WORD ; 0..59
    .wSecond              D WORD ; 0..59
    .wMilliseconds        D WORD ; 0..999
     ENDSTRUC SYSTEMTIME

↑ Time2SystemTime aSystemTime, TZ=0
  Convert the time as returned by LinABI time or WinABI GetSystemTime to the SystemTime memory variable.
  This macro works in 32bit and 64bit mode in Linux and in Windows.
Input
  EAX or RAX is the number of seconds since midnight 1.1.1970 UTC.
  aSystemTime is a pointer to the target structured memory variable SYSTEMTIME.
  TZ=0 is the number of seconds of the time zone, which will be added to the input number.
  TZ=0 for UTC, TZ=1*86400 for Prague, TZ=2*86400 for Moscow etc.
Output
  aSystemTime is filled with the current time..

    Time2SystemTime %MACRO aSystemTime, TZ=0
         %IF %^WIDTH=64
           PUSHQ %TZ
           PUSH %aSystemTime
         %ELSE
           PUSHD %TZ
           PUSH %aSystemTime
         %ENDIF
         CALL Time2SystemTime@RT:
    Time2SystemTime@RT: PROC1
         %IF %^WIDTH=64
           PUSH RAX,RBX,RCX,RDX,RSI,RDI,RBP
           MOV RBX,[RSP+9*8]   ; %TZ
           MOV RDI,[RSP+8*8]   ; %aSystemTime
         %ELSE
           PUSH EAX,EBX,ECX,EDX,ESI,EDI,EBP
           MOV EBX,[ESP+9*4]   ; %TZ
           MOV EDI,[ESP+8*4]   ; %aSystemTime
         %ENDIF
         ADD EAX,EBX
         MOV EBX,EAX
         MOV ECX,7*86400
         ADD EAX,4*86400       ; Compute day of the week.
         XOR EDX,EDX
         %IF %^WIDTH=64
           DIV RCX
         %ELSE
           DIV ECX
         %ENDIF
         MOV EAX,EDX
         MOV ECX,86400
         XOR EDX,EDX
         %IF %^WIDTH=64
           DIV RCX
         %ELSE
           DIV ECX
         %ENDIF
         MOV EBP,EAX           ; Save the day of the week.
         MOV EAX,EBX           ; Restore the number of seconds.
         MOV ECX,365*86400     ; Seconds in a nonleap year.
         MOV EDX,366*86400     ; Seconds in a leap year.
         MOV EBX,1970          ; 1970.
    .10: SUB EAX,ECX
         JB .25:
         INC EBX               ; 1971,1975,1979,1983,1987,1991,1995,1999,2003,2007,2011,2015,2019,2023,2027,2031,,
         SUB EAX,ECX
         JB .25:
         INC EBX               ; 1972,1976,1980,1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,2024,2028,2032,,
         SUB EAX,EDX
         JB .20:
         INC EBX               ; 1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,,
         SUB EAX,ECX
         JB .25:
         INC EBX               ; 1974,1978,1982,1986,1990,1994,1998,2002,2006,2010,2014,2018,2022,2026,2030,2034,,
         JMPS .10:
    .20: ADD EAX,EDX
         JMPS .30:
    .25: ADD EAX,ECX
    .30: XCHG EBX,EAX
         STOSW                 ; Year is computed in BX.
         XCHG EBX,EAX
         MOV ECX,31*86400      ; Days in a long month.
         MOV EDX,30*86400      ; Days in a short month.
         MOV ESI,28*86400      ; Days in February in a nonleap year.
         TEST BL,3
         JNZ .35:
         ADD ESI,86400         ; Days in February in a leap year.
    .35: MOV EBX,1             ; January.
    .40: SUB EAX,ECX
         JB .60:
         INC EBX               ; February.
         SUB EAX,ESI
         JB .55:
         INC EBX               ; March.
         SUB EAX,ECX
         JB .60:
         INC EBX               ; April.
         SUB EAX,EDX
         JB .50:
         INC EBX               ; May.
         SUB EAX,ECX
         JB .60:
         INC EBX               ; June.
         SUB EAX,EDX
         JB .50:
         INC EBX               ; July.
         SUB EAX,ECX
         JB .60:
         INC EBX               ; August.
         SUB EAX,ECX
         JB .60:
         INC EBX               ; September.
         SUB EAX,EDX
         JB .50:
         INC EBX               ; October.
         SUB EAX,ECX
         JB .60:
         INC EBX               ; November.
         SUB EAX,EDX
         JB .50:
         INC EBX               ; December.
         SUB EAX,ECX
         JB .60:
         JMP .65:
    .50: ADD EAX,EDX
         JMP .65:
    .55: ADD EAX,ESI
         JMP .65:
    .60: ADD EAX,ECX
    .65: XCHG EBX,EAX          ; Month is computed in BX (1..12).
         STOSW
         XCHG EAX,EBP          ; Restore the day of the week.
         STOSW
         XCHG EAX,EBX          ; Restore the rest to RAX.
         MOV ECX,86400         ; Seconds in a day.
         XOR EDX,EDX
         %IF %^WIDTH=64
           DIV RCX
         %ELSE
           DIV ECX
         %ENDIF
         INC EAX
         STOSW                 ; Day in the month.
         MOV EAX,EDX
         MOV ECX,3600          ; Seconds in an hour.
         XOR EDX,EDX
         %IF %^WIDTH=64
           DIV RCX
         %ELSE
           DIV ECX
         %ENDIF
         STOSW                 ; Hour.
         MOV EAX,EDX
         MOV ECX,60            ; Second in a minute.
         XOR EDX,EDX
         %IF %^WIDTH
           DIV RCX
         %ELSE
           DIV ECX
         %ENDIF
         STOSW                 ; Minute.
         MOV EAX,EDX
         STOSW                 ; Second.
         XOR EAX,EAX
         STOSW                 ; Miliseconds are not supported.
         %IF %^WIDTH=64
           POP RBP,RDI,RSI,RDX,RCX,RBX,RAX
           RET 2*8
         %ELSE
           POP EBP,EDI,ESI,EDX,ECX,EBX,EAX
           RET 2*4
         %ENDIF
        ENDPROC1 Time2SystemTime@RT
       %ENDMACRO Time2SystemTime

Time1970 DateTime32, DateTimeString

  Macro Time1970 converts the time from 32bit C-time (number of seconds since midnight Jan 1st 1970 UTC) in 64bit Linux or Windows to the ASCIIZ format `yyyy/mm/dd hh:mm:ss`.

Input
  DateTime32 is register with time in the lower 32 bits.
  DateTimeString is pointer to the output string. It must be at least 20 bytes long.
Output
  DateTimeString is filled with the date and time `yyyy/mm/dd hh:mm:ss`, zero-terminated.
Expands
  StoD. Be sure to INCLUDE1 cpuext64.htm.

    Time1970  %MACRO DateTime32, DateTimeString
        PUSH %DateTimeString, %DateTime32
        CALL Time1970@RT
    Time1970@RT PROC1
        PUSH RAX,RBX,RCX,RDX,RSI,RDI
         SUB RSP,16
    %month %SETA 0
    DaysInMonth %FOR 31,28,31,30,31,30,31,31,30,31,30,31
          MOVB [RSP+%month],%DaysInMonth
          %month %SETA %month+1
         %ENDFOR DaysInMonth
         MOV RDI,[RSP+10*8]                ; %DateTimeString
         MOV RAX,[RSP+ 9*8]                ; %DateTime32
         XOR EDX,EDX
         MOV ECX,24*60*60
         DIV RCX
         ; RAX is whole days since Jan 1st 1970.  RDX is seconds since midnight.
         MOV RSI,RDX
         MOV ECX,365+365+366+365
         XOR EDX,EDX
         DIV RCX
         LEA RBX,[4*RAX+1970]              ; RBX is four-year. EDX is number of days since RBX (0..4*365)
         SUB EDX,365
         JB .30:
         INC EBX
         SUB EDX,365
         JB .30:
         INC EBX
         SUB EDX,366
         JB .20:
         INC EBX
         JMPS .40:
    .20: INC EDX
    .30: ADD EDX,365
    .40: TEST BL,3                         ; RBX is year. EDX is number of days since RBX (0..365)
         JNZ .50:
         MOVB [RSP+1],29
    .50: MOV EAX,EBX
         StoD RDI,Size=4
         MOV AL,'/'
         STOSB
         XOR EBX,EBX
         XOR ECX,ECX
    .60: MOVZXB EAX,[RSP+RBX]              ; 31,28|29,31,30,,,
         ADD ECX,EAX                       ; 31,59|60,90|91,,,
         INC EBX                           ; RBX is month (1..12).
         CMP ECX,EDX
         JNA .60:
         SUB ECX,EAX
         SUB EDX,ECX
         INC EDX                           ; RBX is month, RDX is day (1..31).
         MOV EAX,EBX
         StoD RDI,Size=2,Align=right,LeadingZeroes=yes  ; Store month.
         MOV AL,'/'
         STOSB
         MOV EAX,EDX
         StoD RDI,Size=2,Align=right,LeadingZeroes=yes  ; Store days.
         MOV AL,' '
         STOSB
         MOV EAX,ESI                                    ; EAX is seconds since midnight.
         XOR EDX,EDX
         MOV ECX,60*60
         DIV RCX
         StoD RDI,Size=2,Align=right,LeadingZeroes=yes  ; Store hours.
         MOV AL,':'
         STOSB
         MOV EAX,EDX
         XOR EDX,EDX
         MOV ECX,60
         DIV RCX
         StoD RDI,Size=2,Align=right,LeadingZeroes=yes  ; Store minutes.
         MOV AL,':'
         STOSB
         MOV EAX,EDX
         StoD RDI,Size=2,Align=right,LeadingZeroes=yes  ; Store seconds.
         XOR EAX,EAX
         STOSB
         ADD RSP,16
        POP RDI,RSI,RDX,RCX,RBX,RAX
        RET 2*8
       ENDP1 Time1970@RT
      %ENDMACRO Time1970

      ENDHEAD string64

↑ Constants
  Encoding of constant symbols used in WinAPI derived from header files in [WindowsSDK].

     ENDHEAD time

▲Back to the top▲