Manage dates as numbers

From NSIS Wiki
Jump to navigationJump to search
Author: fabiochelly (talk, contrib)


Description

These functions help you to work with dates by converting them into an integer like the date type used in Excel or Delphi (in fact the number of days since 1900). Like that, you can easilly add or subtract days.

Date2Serial

This function converts a date into an integer

Example

Push "day"          ; 30
Push "month"        ; 8
Push "year"         ; 2007
Call Date2Serial
Pop "serial number" ; 39324 (approx ((2007-1900) * 12) + 8) * 30)

The Function

Function Date2Serial
  Pop $R0 ;year
  Pop $R1 ;month
  Pop $R2 ;day
  IntOp $R3 0 + 1
  Loop:
    IntCmp $R1 $R3 OutLoop 
    Push $R3
    Push $R0
    Call DaysInMonth
    Pop $R4
    IntOp $R2 $R2 + $R4
    IntOp $R3 $R3 + 1
    Goto Loop
  OutLoop:
    IntOp $R3 $R0 - 1
    IntOp $R5 $R3 * 365
    IntOp $R6 $R3 / 4
    IntOp $R5 $R5 + $R6
    IntOp $R6 $R3 / 100
    IntOp $R5 $R5 - $R6
    IntOp $R6 $R3 / 400
    IntOp $R5 $R5 + $R6
    IntOp $R5 $R5 + $R2
    IntOp $R5 $R5 - 693594
    Push $R5
FunctionEnd

Serial2Date

Description

This function converts an integer into an date

Example

Push "serial number"
Call Serial2Date
Pop "day"
Pop "month"
Pop "year"

The Function

Function Serial2Date
  Pop $R0
  IntOp $R0 $R0 + 693593
  IntOp $R1 0 + 1
  Loop:
    IntCmp $R0 146097 ok1 OutLoop ok1
    ok1:
    IntOp $R0 $R0 - 146097
    IntOp $R1 $R1 + 400
    Goto Loop
  OutLoop:
    IntOp $R2 $R0 / 36524
    IntOp $R3 $R0 % 36524
    IntCmp $R2 4 e4 diff4 diff4
    e4:
    IntOp $R2 $R2 - 1
    IntOp $R3 $R3 + 36524
  diff4:
    IntOp $R4 $R2 * 100
    IntOp $R1 $R1 + $R4
 
    IntOp $R2 $R3 / 1461
    IntOp $R3 $R3 % 1461
 
    IntOp $R4 $R2 * 4
    IntOp $R1 $R1 + $R4
 
    IntOp $R2 $R3 / 365
    IntOp $R3 $R3 % 365
 
    IntCmp $R2 4 e4_2 diff4_2 diff4_2
    e4_2:
    IntOp $R2 $R2 - 1
    IntOp $R3 $R3 + 365
  diff4_2:
    IntOp $R1 $R1 + $R2
    IntOp $R5 0 + 1
  Loop2:
    Push $R5
    Push $R1
    Call DaysInMonth
    Pop $R2
    IntCmp $R3 $R2 ok2 OutLoop2 ok2
    ok2:
    IntOp $R3 $R3 - $R2
    IntOp $R5 $R5 + 1
    Goto Loop2
  OutLoop2:
    IntOp $R3 $R3 + 1
    Push $R1 ;year
    Push $R5 ;month
    Push $R3 ;day
FunctionEnd

IsLeapYear

Description

This function returns 0 if a year is a leap year.

Example

Push 2004
Call IsLeapYear
Pop $0            ; 1 = yes, 0 = no

The Function

Function IsLeapYear
  Pop $0
  IntOp $1 $0 % 4
  IntCmp $1 0 test2
  Goto ko
  test2:
    IntOp $1 $0 % 100
    IntCmp $1 0 test3
    Goto ok
  test3:
    IntOp $1 $0 % 400
    IntCmp $1 0 ok
    Goto ko
  ok:
    Push 1
    Goto end
  ko:
    Push 0
  end:
FunctionEnd

DaysInMonth

Description

This function returns the number of days in a month

Usage

Push "month"
Push "year"
Call DaysInMonth
Pop "number of days"

The Function

Function DaysInMonth
  Pop $0 ;annee
  Pop $1 ;mois
 
  IntCmp $1 1 m31
  IntCmp $1 2 m28
  IntCmp $1 3 m31
  IntCmp $1 4 m30
  IntCmp $1 5 m31
  IntCmp $1 6 m30
  IntCmp $1 7 m31
  IntCmp $1 8 m31
  IntCmp $1 9 m30
  IntCmp $1 10 m31
  IntCmp $1 11 m30
  IntCmp $1 12 m31
 
  m31:
    Push 31
    Goto end
  m30:
    Push 30
    Goto end
  m28:
    Push $0
    Call IsLeapYear
    Pop $0
    IntCmp $0 1 m29
      Push 28
      Goto end
    m29:
     Push 29
  end:
FunctionEnd

Today

Description

This function returns the current date

Usage

Call Today
Pop "day"
Pop "month"
Pop "year"

The Function

Function Today
  System::Alloc 128
  Pop $0
  System::Call "Kernel32::GetSystemTime(i) v (r0)"
  System::Call "*$0(&i2 .r1, &i2 .r2, &i2 .r3, &i2 .r4, &i2 .r5, &i2 .r6, &i2 .r7, &i2 .r8)"
  System::Free $0
 
  Push $1
  Push $2
  Push $4
FunctionEnd

TodaySerial

Description

This function returns the current date in a serial format

Usage

Call TodaySerial
Pop "serial number"

The Function

Function TodaySerial
  Call Today
  Exch 2
  Call Date2Serial
FunctionEnd