Subtract a month from a date?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Subtract a month from a date?

09 Feb 2017, 14:19

@FanaticGuru Your instincts are good on both counts,
I would do both the things that you state,
but I don't because of AHK v2 future compatibility.
Which changes the nature of SubStr,
and which requires both options in a ternary operator!

[EDIT:]
I'm still considering the best way to do this, perhaps:

Code: Select all

q::
vDay := vMonth := 1
vIsAhkV1 := (SubStr(A_AhkVersion,1,2) = "1.")
vMonth := SubStr("0" vMonth, vIsAhkV1-2)
vDay := SubStr("0" vDay, vIsAhkV1-2)
MsgBox % vMonth " " vDay
Return
I think I will probably change it to this!
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Subtract a month from a date?

26 Jul 2017, 23:08

Improved version:

Code: Select all

q:: ;date add months
vDate := A_Now
;vFormat := "HH:mm dd/MM/yyyy"
vFormat := "yyyy-MM-dd HH-mm-ss"
vNum := 3
vDate1 := JEE_DateAddMonths(vDate, -vNum, vFormat)
vDate2 := JEE_DateAddMonths(vDate, 0, vFormat)
vDate3 := JEE_DateAddMonths(vDate, vNum, vFormat)
MsgBox % vDate1 "`r`n" vDate2 "`r`n" vDate3
return

JEE_DateAddMonths(vDate, vNum, vFormat="yyyyMMddHHmmss")
{
	;make date the standard 14-character format:
	vDate .= SubStr(19990101000000, StrLen(vDate)+1)
	vYear := SubStr(vDate, 1, 4), vMonth := SubStr(vDate, 5, 2)
	vDay := SubStr(vDate, 7, 2), vTime := SubStr(vDate, 9)

	vMonths := (vYear*12) + vMonth + vNum
	vYear := Floor(vMonths/12)
	vMonth := Mod(vMonths,12)
	(!vMonth) && (vYear -= 1, vMonth := 12)

	if (vMonth = 2) && (vDay > 28)
		if !Mod(vYear,4) && (Mod(vYear,100) || !Mod(vYear,400)) ;4Y AND (100N OR 400Y)
			vDay := 29
		else
			vDay := 28
	if (vDay = 31) && RegExMatch(vMonth, "^(4|6|9|11)$")
		vDay := 30

	vDate := Format("{:04}{:02}{:02}" vTime, vYear, vMonth, vDay)
	if !(vFormat == "yyyyMMddHHmmss")
		FormatTime, vDate, % vDate, % vFormat
	return vDate
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: Subtract a month from a date?

05 Sep 2017, 09:23

jeeswg wrote: [EDIT 2:]
improved version (simplified code):

Code: Select all

q:: ;date add months
vDate := A_Now
vFormat := "HH:mm dd/MM/yyyy"
vNum := 3
vDate0 := JEE_DateAddMonths(vDate, 0, vFormat)
vDate1 := JEE_DateAddMonths(vDate, -vNum, vFormat)
vDate2 := JEE_DateAddMonths(vDate, vNum, vFormat)
MsgBox % vDate1 "`r`n" vDate0 "`r`n" vDate2
Return

;==================================================

JEE_DateAddMonths(vDate, vNum, vFormat="")
{
vDate += 0, Seconds ;make date the standard 14-character format
vYear := SubStr(vDate, 1, 4)
vMonth := SubStr(vDate, 5, 2)
vDay := SubStr(vDate, 7, 2)
vTime := SubStr(vDate, 9)

vMonths := (vYear*12) + vMonth + vNum
vYear := Floor(vMonths/12)
vMonth := Mod(vMonths,12)
(!vMonth) ? (vYear -= 1, vMonth := 12) : ""

if (vMonth = 2) && (vDay > 28)
if !Mod(vYear,4) && (Mod(vYear,100) || !Mod(vYear,400)) ;4Y AND (100N OR 400Y)
vDay := 29
else
vDay := 28

if (vDay = 31)
if vMonth in 4,6,9,11
vDay := 30

(StrLen(vMonth)=1) ? (vMonth := "0" vMonth) : ""
(StrLen(vDay)=1) ? (vDay := "0" vDay) : ""
vDate := vYear vMonth vDay vTime
if !(vFormat = "")
FormatTime, vDate, % vDate, % vFormat
Return vDate
}
Hi, jeeswg, how do i supposed to put this code to subtract months from a date then do something else?
;already created GUI edit box to put numberic date in my script, such as i run the gui, then simply type 20170903

Code: Select all

M1:
GuiControlGet, Date,, MyEdit
if (StrLen(Date) != 8)
	return
FormatTime, Date, %Date%, MMM.,dd.yyyy
StringUpper, Date, Date
GuiControl,, Date1, %Date% ;GUI will now shown: SEP.,03.2017
-----------;EDIT2 attached----------
;need to substract 2 months, then save the new date(JUL.,03.2017) as %Date02%
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Subtract a month from a date?

05 Sep 2017, 09:48

Code: Select all

GuiControlGet, Date,, MyEdit
if (StrLen(Date) != 8)
	return
Date02 := JEE_DateAddMonths(Date, -2, "MMM.,dd.yyyy")
MsgBox, % Date02
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
just me
Posts: 9482
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Subtract a month from a date?

06 Sep 2017, 10:15

Date-time calculations should be reversible, but they are'nt in case of months:

Code: Select all

vDate := 20170331000000
vNum := 1
vDateNew := JEE_DateAddMonths(JEE_DateAddMonths(vDate, -vNum), vNum)

MsgBox % "Date:`r`n" . vDate . "`r`nAfter first subtracting then adding 1 month:`r`n" . vDateNew
return

JEE_DateAddMonths(vDate, vNum, vFormat := "yyyyMMddHHmmss")
{
	;make date the standard 14-character format:
	vDate .= SubStr(19990101000000, StrLen(vDate)+1)
	vYear := SubStr(vDate, 1, 4), vMonth := SubStr(vDate, 5, 2)
	vDay := SubStr(vDate, 7, 2), vTime := SubStr(vDate, 9)

	vMonths := (vYear*12) + vMonth + vNum
	vYear := Floor(vMonths/12)
	vMonth := Mod(vMonths,12)
	(!vMonth) && (vYear -= 1, vMonth := 12)

	if (vMonth = 2) && (vDay > 28)
		if !Mod(vYear,4) && (Mod(vYear,100) || !Mod(vYear,400)) ;4Y AND (100N OR 400Y)
			vDay := 29
		else
			vDay := 28
	if (vDay = 31) && RegExMatch(vMonth, "^(4|6|9|11)$")
		vDay := 30

	vDate := Format("{:04}{:02}{:02}" vTime, vYear, vMonth, vDay)
	if !(vFormat == "yyyyMMddHHmmss")
		FormatTime, vDate, % vDate, % vFormat
	return vDate
}
Consider carefully before you use this function!
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: Subtract a month from a date?

11 Sep 2017, 22:32

jeeswg wrote:Improved version:

Code: Select all

q:: ;date add months
vDate := A_Now
;vFormat := "HH:mm dd/MM/yyyy"
vFormat := "yyyy-MM-dd HH-mm-ss"
vNum := 3
vDate1 := JEE_DateAddMonths(vDate, -vNum, vFormat)
vDate2 := JEE_DateAddMonths(vDate, 0, vFormat)
vDate3 := JEE_DateAddMonths(vDate, vNum, vFormat)
MsgBox % vDate1 "`r`n" vDate2 "`r`n" vDate3
return

JEE_DateAddMonths(vDate, vNum, vFormat="yyyyMMddHHmmss")
{
	;make date the standard 14-character format:
	vDate .= SubStr(19990101000000, StrLen(vDate)+1)
	vYear := SubStr(vDate, 1, 4), vMonth := SubStr(vDate, 5, 2)
	vDay := SubStr(vDate, 7, 2), vTime := SubStr(vDate, 9)

	vMonths := (vYear*12) + vMonth + vNum
	vYear := Floor(vMonths/12)
	vMonth := Mod(vMonths,12)
	(!vMonth) && (vYear -= 1, vMonth := 12)

	if (vMonth = 2) && (vDay > 28)
		if !Mod(vYear,4) && (Mod(vYear,100) || !Mod(vYear,400)) ;4Y AND (100N OR 400Y)
			vDay := 29
		else
			vDay := 28
	if (vDay = 31) && RegExMatch(vMonth, "^(4|6|9|11)$")
		vDay := 30

	vDate := Format("{:04}{:02}{:02}" vTime, vYear, vMonth, vDay)
	if !(vFormat == "yyyyMMddHHmmss")
		FormatTime, vDate, % vDate, % vFormat
	return vDate
}
Hello again, Jeeswg, is it possible to add or substract 1 day based on vDate := JEE_DateAddMonths(vDate, -vNum1, vFormat)

vDate:=20170803
vFormat := "yyyyMMdd"
vNum1 := 1
vDate2 := JEE_DateAddMonths(vDate, -vNum1, vFormat) ;result: 20170703
;vDate3 := ; how to add 1 day from 20170703 to 20170704
;vDate4 := ; how to subtract 1 day from 20170703 to 20170702
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Subtract a month from a date?

12 Sep 2017, 01:06

I at appears that you can't use JEE_DateAddMonths to add/subtract days, e.g. I tried 1/28 in case it would work, but it doesn't appear to. I've written a function called JEE_DateAddDays that can do this however:

Code: Select all

q::
vDate := 20170803
vFormat := "yyyyMMdd"
vNum1 := 1
vDate2 := JEE_DateAddMonths(vDate, -vNum1, vFormat) ;20170703
vDate3 := JEE_DateAddDays(20170703, 1, vFormat) ;20170704
vDate4 := JEE_DateAddDays(20170703, -1, vFormat) ;20170702
MsgBox, % vDate2 "`r`n" vDate3 "`r`n" vDate4
return

JEE_DateAddDays(vDate, vNum, vFormat:="yyyyMMddHHmmss")
{
	EnvAdd, vDate, % vNum, Days
	;vDate += vNum, Days
	if !(vFormat == "yyyyMMddHHmmss")
		FormatTime, vDate, % vDate, % vFormat
	return vDate
}
Potentially of interest also are the DateAdd/DateDiff functions, available in AHK v2, or via a custom function in AHK v1:
commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 80#p166980
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
ivill
Posts: 124
Joined: 13 May 2016, 02:23

Re: Subtract a month from a date?

13 Sep 2017, 08:06

jeeswg wrote:I at appears that you can't use JEE_DateAddMonths to add/subtract days, e.g. I tried 1/28 in case it would work, but it doesn't appear to. I've written a function called JEE_DateAddDays that can do this however:

Code: Select all

q::
vDate := 20170803
vFormat := "yyyyMMdd"
vNum1 := 1
vDate2 := JEE_DateAddMonths(vDate, -vNum1, vFormat) ;20170703
vDate3 := JEE_DateAddDays(20170703, 1, vFormat) ;20170704
vDate4 := JEE_DateAddDays(20170703, -1, vFormat) ;20170702
MsgBox, % vDate2 "`r`n" vDate3 "`r`n" vDate4
return

JEE_DateAddDays(vDate, vNum, vFormat:="yyyyMMddHHmmss")
{
	EnvAdd, vDate, % vNum, Days
	;vDate += vNum, Days
	if !(vFormat == "yyyyMMddHHmmss")
		FormatTime, vDate, % vDate, % vFormat
	return vDate
}
Potentially of interest also are the DateAdd/DateDiff functions, available in AHK v2, or via a custom function in AHK v1:
commands as functions (AHK v2 functions for AHK v1) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 80#p166980
Thanks @jeeswg, i found your AddMonths works very great, and about add/subtract days, i use the built in AddDays function, it works for me.
ibiscus
Posts: 4
Joined: 09 Feb 2020, 12:57

Re: Subtract a month from a date?

09 Feb 2020, 13:15

jeeswg I can't thank you enough, you saved my day. I started with a function to add months which went great until I've tried to subtract months. Without a reference date I couldn't figure it out. I'm no programmer but I find your solution and code quite elegant. Much much thanks. And also for all the employees who are going to have their raise on time :facepalm:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Chunjee, jollyjoe, mikeyww and 333 guests