3

I was looking for an inbuild ahk function that allows the user to add days, months, years or even time to an existing day thus converting it correctly to a new month if the day count reaches 32. I didn't find anything, so I came up with this little solution:

; returns an array [year, month, day, hour, minute, second]
DateTimeAdd(v_a_now,yearPlus=0,monthPlus=0,dayPlus=0,hrPlus=0,minPlus=0,secPlus=0) {
daysInMonth := { 1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31 }

; Parse data from an A_NOW type format
; If you pass your custom "A_NOW" format remember that numbers < 10 are expected to have a leading 0

day := SubStr(v_a_now,7,2) + dayPlus
month := SubStr(v_a_now,5,2) + monthPlus
year := SubStr(v_a_now,1,4) + yearPlus

hours := SubStr(v_a_now,9,2) + hrPlus
minutes := SubStr(v_a_now,11,2) + minPlus
seconds := SubStr(v_a_now,13,2) + secPlus

; Start formatting

if(seconds >= 60) {
    tadd := seconds / 60
    seconds -= Floor(tadd) * 60
    minutes += Floor(tadd)
}

if(minutes >= 60) {
    tadd := minutes / 60
    minutes -= Floor(tadd) * 60
    hours += Floor(tadd)
}

if(hours >= 24) {
    tadd := hours / 24
    hours -= Floor(tadd) * 24
    day += Floor(tadd)
}

; We have to format the month first in order to be able to format the days later on
if(month >= 13) {
    tadd := month / 12
    month -= Floor(tadd) * 12
    year += Floor(tadd)
}

; Assmuning the number of days is an absurd number like 23424 we need to go through each month and subtract the max. amount of days from that month
cond := true
while(cond) {
    ; Get the number of max. days in this current month (sadly no loop years included :< )
    max_days_in_this_month := daysInMonth[month]

    ; If the number of days i.e. 42 is great than 31 for example in January
    if(day > max_days_in_this_month) {
        ; Subtract max. allowed days in month from day
        day -= max_days_in_this_month

        ; New Year?
        if(month == 12) {
            month := 1
            year++
        } else {
            month++
        }
    } else {
        cond := false
    }
}

; Add leading zero to numbers

return_array := [year, month, day, hours, minutes, seconds]

i := 2
while(i != return_array.MaxIndex()+1) {
    thisIteration := return_array[i]

    if(thisIteration <= 9) {
        return_array[i] := "0" thisIteration
    }
    i++
}

; Done formatting

; For testing
;~ msg := return_array[1] "/" return_array[2] "/" return_array[3] " " return_array[4] ":" return_array[5] ":" return_array[6]
;~ msgbox % msg

return return_array
}

Sadly this function does not take loop years into aspect. Do you guys know any better alternatives?

Dean
  • 301
  • 1
  • 3
  • 13

1 Answers1

2

Check out EnvAdd at https://autohotkey.com/docs/commands/EnvAdd.htm

EnvAdd, Var, Value, TimeUnits

equivalent to

Var += Value, TimeUnits

EnvAdd sets a date variable Var (in YYYYMMDDHH24MISS format) to the sum of itself plus the given date value Value using the timeunits parameter.

Example:

newDate := %A_Now% ; or whatever your starting date is 
EnvAdd, newDate, 20, days
NewDate += 11, days
MsgBox, %newDate%  ; The answer will be the date 31 days from now.
PGilm
  • 2,262
  • 1
  • 14
  • 26
  • Perfect! Thank you :) – Dean Feb 27 '19 at 12:28
  • You're welcome. I certainly appreciated your effort and might have been able to help with the Leap years part, but the AHK date processing does all the heavy lifting, so, there is no point. – PGilm Feb 27 '19 at 15:09