Wrapping Up the DateStampConvert.ahk Script (AutoHotkey Tips)

In Previous Blogs, I Used Regular Expressions to ID Dates Formats in Documents and Simulated Case/Switch Statements to Convert Month Names to Numbers. Now, I Build the Standard DateTime Stamp, Check for Valid Dates, and Deal with Two-digit Years, Plus Use the Function ByRef Method to Bypass Local Variables.

While in conversations with a reader who uses AutoHotkey to calculate the time span between two dates for figuring out new leases, I realized that a tool which captures formatted dates from any document and converts them into the DateTime Stamp format (yyyymmdd) would make using the HowLongYearsMonthsDays.ahk script even easier. That prompted me to write the DateStampConvert.ahk script.

I included two Hotkey combinations for inserting the converted DateTime Stamp into the StartDate (CTRL+ALT+microsoft_key(WIN)+d ⇒ ^!#d) and the StopDate (CTRL+ALT+microsoft_key(WIN)+z ⇒ ^!#z) respectively into the Calculate How Long GUI (see image below). To put these Hotkeys into effect, add the #Include directive with the DateStampConvert.ahk script at the end of the HowLongYearMonthsDays.ahk script:

#Include [path]DateStampConvert.ahk

Note: Be sure to comment out the MsgBox command in the first Hotkey combination (^!#d) in the DateStampConvert.ahk script by placing a semicolon ( ; ) in front of it.

Select a formatted date in any document and use the Hotkey combinations CTRL+ALT+WIN+d or CTRL+ALT+WIN+z to convert the date to DateTime Stamp format and send it to the Date One or Date Two GUI control, respectively, in the HowLongYearsMonthsDays.ahk timespan calculation script.

You can modify the HowLongYearMonthsDays.ahk script any way you like to produce alternative results (e.g. lease calculations?) rather than popping-up a MsgBox.

Features of the DateStampConvert.ahk Script

The last two blogs dealt with pieces of the DateStampConvert.ahk script: Regular Expressions for identifying date formats and cascading Ternary operators to simulate Case/Switch statements found in other programming languages. These next snippets cover other routines required to complete the script.

Creating the DateTime Stamp

We put together the DateTime Stamp by merely concatenating the four-digit year, two-digit month, and two-digit day:

; if two-digit year, convert to four-digit year

    If StrLen(Year) = 2
       Year := YearCheck(Year)

; concatenate DateTime Stamp

    DateStamp := Year . Format("{:02}", Month) . Format("{:02}", Day)

First, we change any two-digit year into a four-digit year using the YearCheck() function (discussed below).

The DateTime Stamp requires the following concatenation code for piecing together the standard format:

DateStamp := Year . Format("{:02}", Month) . Format("{:02}", Day)

The month and day must always use two digits in the DateTime Stamp. In the past, I’ve implemented slightly convoluted string manipulations to ensure that single-digit numbers (1 through 9) appear as two digits (01 through 09). The Format function shown above solves the problem—automatically padding any single-digit with a preceding 0.

Note: The Format function provides a wide variety of solutions for formatting numeric strings. I found the online documentation a little bit confusing, but, by working with the examples, I began to understand how the function works. The Format function certainly deserves more attention in a future blog.

Library Benefits

Check for Valid Date

The script could easily generate an invalid date (e.g. a day value over 31). We use a specialized If var is Type conditional to ensure we produce a valid date:

; Check for valid date

    If DateStamp is not Date
       MsgBox Invalid date! %DateStamp%
       Return DateStamp

If not a valid date (e.g. February 30), it returns false.

Version 2.0 Note: V2.0 uses a similar expression to determine the type of a variable or expression (Var is Type) which you can use in conjunction with the If (expression) statement.

Two-Digit Years

The problem which occurs when we encounter two-digit years involves the ambiguity between the centuries. If we see a date in a letter, then we generally know to use the current year. However, with many dates, we may not know which century to use from context alone. We could set up a MsgBox selection option (similar to what we use for ambiguous US/British date formats) but we can also let the script make a reasonable guess. In the routine below, any year greater than 40 uses the last century. Otherwise, it assumes the 2000s:

  If Year > 40
    Year := "19" . Year
    Year := "20" . Year
  Return Year

The actual cut-off date you use depends upon how you plan to use the results. The reader doing lease calculations preferred a date point of 60 for any two-digit year allowing for current 30 and 40-year leases.

Returning Variable Values from Functions

Most commonly we either use the Return command (as shown above) to send a value back to the calling function or create global variables accessible from everywhere. The Function ByRef technique gives us an alternative method for manipulating and saving variables without either declaring them global or using the Return command:

YearCheck(ByRef Year)
If Year > 40
      Year := "19" . Year
      Year := "20" . Year

The Return command only allows for one variable value. Although a function can access multiple global variables, they require prior declaration either in the main script or inside the function. The ByRef method allows for multiple variables by directly accessing variables without making copies for use locally within the function. From the AutoHotkey documentation:

Since return can send back only one value to a function’s caller, ByRef can be used to send back extra results. This is achieved by having the caller pass in a variable (usually empty) in which the function stores a value.

This technique can solve a number of problems associated with function variables—especially when working with multiple variables or those generated on-the-fly.

To get a better understanding of how ByRef works, run this example taken from the AutoHotkey online documentation:

MsgBox % A "," B "," C

returnByRef(ByRef val1, ByRef val2, ByRef val3)
    val1 := "A"
    val2 := 100
    val3 := 1.1

I can see how this approach can add more universality to AutoHotkey functions.


This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s