In "Don't Let Daylight Saving Time Sneak Up on You" (November 2006, InstantDoc ID 93485), I mentioned that the basic engine of the GetDLSDates.vbs script could be used (with a few modifications) to find specific occurrences of days within given months. I specifically pointed out that you could use it to display the second Tuesday of a given month to get a "heads up" on when Microsoft was going to release its patches. Now I've put together a utility that displays the dates of what we call around the office "Super Tuesdays" for up to 72 months —in a new version of GetDLSDates.vbs called HTA-Super-Tuesday.
Finding a Day's Date
HTA-SuperTuesday isn't limited to finding Super Tuesdays. You can select any day of the week and any month of the year. You can also specify from the first to the fifth occurrence. For instance, if you want to display the fourth Monday in December, you can open the Super Tuesday dialog box (which Figure 1, shows), select "4th" in the first drop-down box, select "Monday" in the second drop-down box, and select "December" in the third drop-down box. Then, clear the Show check box and click RunScript. If you want to display the fourth Monday in several consecutive months, select the Show check box and enter the number of consecutive months.
As I mentioned earlier, HTASuperTuesday is driven by basically the same engine that drives GetDLSDates.vbs, with a few minor modifications. Notably, I removed the dependence on the same year from the DLS function that made the function specific to the current year. You can't use GetDLSDates.vbs's DLS function to determine previous or future daylight saving time start and end dates because the properties that represent those dates are specific to the current year.
However, in HTA-SuperTuesday, I'm not looking at the Win32 _TimeZone Class, so I can venture into the future if I choose to and even back into the past (well, at least back to January of the current year). The Win32 _TimeZone class contains specific first and last date properties that are specific to the current year. Because I'm no longer confined to using the current year, the year variable is not set in the HTA-SuperTuesday DLS function, as it was in the original DLS function. It is now set in the main program and used in the function. There is one other slight change to the function. Instead of using the arDOW array in the function, I simply pass the appropriate array element value from the main program to the function. This array contains days-of-the-week values Sunday through Saturday.
Because I describe the DLS function in the previous article, I won't get into DLS's inner workings in any great detail here, but I will point out some of the key features that incorporate DLS into HTA-SuperTuesday.
As you might have guessed from the name, HTA-SuperTuesday is in HTML Application (HTA) format. (If you're not familiar with HTAs, check out "Hooked on HTAs," August 2005, InstantDoc ID 46795.) When a user first launches HTA-SuperTuesday, the month value is set to the current month and the main subroutine runs so that the Super Tuesday UI displays the second Tuesday of the current month as well as the second Tuesdays of the next six consecutive months, as Figure 1 shows.
Listing 1 shows an excerpt from HTASuperTuesday. (Not shown is the code that defines the Super Tuesday dialog box.) The code at callout D shows the startup subroutine, which is automatically executed whenever an HTA is launched. This subroutine is a great place to put your up-front action code. The first line of the subroutine's four lines of code,
simply places the application window in front of other open windows by giving it focus. The second line sizes the application window: The first number represents the width in pixels and the second number indicates the height in pixels. The third line sets the month value in the month drop-down box to the current month, and the fourth line actually runs the main script with the default parameters as seen in Figure 1.
The code at callout A shows the various input values of the application. Each of the drop-down input box objects has a distinct name, and I access the values of those objects by—you guessed it—referring to the value property of the object. For instance, I assign the value of the month drop-down box to a variable called Mth by using the following assignment statement:
Mth = mth1.Value
Mth1 is the name of the month drop-down box object, and by simply using the value property, I can access the contents of that field.
The next two lines perform a similar assignment task, assigning the value of the occurrence drop-down box to the variable occr1 and assigning the value of the day-of-the-week drop-down box to the variable DOTW. These three elements are the key parameters used in the DLS function. With these three parameters and the DLS function, I can find any occurrence of any day in any month.
Showing the Dates
The code at callout B determines whether to show one or multiple dates. If the user selected the Show check box (i.e., the Multimonth object), the code assigns the value stored in the NumOfMonths object to a variable called nofm and adds the value of Mth to that. You'll see the reason for that in a minute. If the Show check box isn't selected, the code stores the value of Mth in the nofm variable. Then the code stores the value of the current year in a variable called yr and gets ready to step into a looping routine.
The Looping Routine
The For Next routine (at callout C) is a little complicated, so bear with me as I step through it. I use x as my stepping variable name and Mth as my starting number. Remember that Mth contains the number of the month selected in the month drop-down box. For instance, if the user chose September, then the value of Mth is 9. My For Next ending point is nofm. As you'll recall, this variable holds a number equal to the month (Mth) number plus, if the Show box is selected, the number of consecutive months the user entered. Therefore, the For Next statement would look like the following if the user selected a combination of September, the Show check box, and six months:
For x = 9 to 15
This technique lets me easily pass the selected month to the DLS function and continue to pass consecutive months. However, 15 doesn't sound like a value representing a month, does it? That's where the If logic checks at callout C come into play. Stepping through the code at callout C, you'll see that it uses the Mod function to determine whether x divided by 12 has a remainder of 1.
If the Mod function does have a remainder of 1 and x isn't equal to 1, then the code can safely assume that x is 13, 25, 37, 49, or some other multiple of 12, plus 1. This result in turn indicates that the function is moving into another year. So, the code adds 1 to the yr variable and sets the mm month variable to 1—in essence, January of the next year.
If x divided by 12 doesn't have a remainder of 1, the code checks whether x is greater than 12. If it is, the Mod function finds the month number. For example,
14 Mod 12
returns a value of 2, which is assigned to mm and represents the month of February.
The next If statement determines whether the Mod function returned the value of 0. If it did, then the month is December and the mm value is set to 12. 12 Mod 12 returns 0, as does 24 mod 12, and so on. Finally, if x is less than 12, mm is assigned the value of x.
At this point, all the parameters are in place and can be passed to the DLS function. The final piece of the For Next routine puts the routine's return value(s) into a variable called SupTue. When all the cycles of the For Next loop are complete, the contents of SupTue are assigned to the application's listing object, which shows the user all the dates in his or her query.
I use HTA-SuperTuesday now not only to get a quick look at the dates for upcoming Super Tuesdays but also to remind me of events and meetings that I attend on first Fridays and second Wednesdays.