Subscribe to Windows IT Pro
September 11, 2006 12:00 AM

Creating Date and Time Stamps

Scripts generate ISO 8601–format dates and times that you can use in filenames
Windows IT Pro
InstantDoc ID #92941
Rating: (8)
Downloads
92941.zip

Using Pure VBScript
As you may have noticed at callout A in Listing 1, VBScript is comfortable with dates and times expressed as numbers. VBScript contains native functions that can extract any component of a date/time value as a number—these are the appropriately named Year, Month, Day, Hour, Minute, and Second functions. Because these functions are present in all versions of VBScript no matter what the OS version, you can use them to help create a date- or timestamp in any version of Windows.

The VBScript date and time functions are not a solution by themselves, but if we look at the ISO 8601 standard, it becomes clear that we just need to do some formatting to get a stamp. Each element of the stamp must be a specific number of characters long: The year is four characters, and every other date and time element must be two characters long. If an element is fewer than the necessary number of characters, we add 0s to the left of it until it’s the correct length.

Listing 2 shows the entire process. Although several lines of code are required, the lines are simple and repetitive.

The code assumes that the year portion of the string is four characters long. VBScript always returns a complete year, not an abbreviated, two-digit year, so the only VBScript-generated date range the code won’t produce an accurate date/time stamp for is the interval from A.D. 100 through A.D. 999. Arguably, the code could be “fixed” to handle this range, but you likely won’t encounter dates in this range in your day-to-day work.

Callout A in Listing 2 shows how we get the other two date elements in proper form. Each element will always be a number represented with one or two characters. If it’s only one character, we preface it with a 0.

Once we have the elements padded, we just join them together, as shown at callout B in Listing 2. The WScript.Echo statements will then display the following output:

datestamp: 20050815
timestamp: 155658 

Although this code works, rewriting it every time you need a date- or timestamp isn’t so much fun. The best way to simplify generating date- and timestamps is to wrap the code up in functions that you can drop into your own scripts. Listing 3 shows the code in Listing 2 reworked as two drop-in functions, ToDateStamp and ToTimeStamp. Both functions generate strings from a VBScript date because this is the most flexible way to handle stamps. Most code that needs to generate a stamp bases it on the current date and/or time, and you can use VBScript’s Now function to get a complete date and time usable in both functions.

Dating Advice
Generally, you should avoid the VBScript functions Date and Time. Although they generate a valid current date and time respectively, the Date function doesn’t retain time information, so if you pass a date generated from Date to the ToTimeStamp function, it will always return the string “000000”. VBScript’s Time function returns only the current time of day with the actual date chopped out, so although it technically still contains date data, using it with ToDateString will always return the string “18991230”. This peculiar result is because VBScript’s dates are actually a count of days from December 30, 1899.

Related Content:

ARTICLE TOOLS

Comments
  • Alex
    4 years ago
    Jun 11, 2008

    OlliK -
    The approach you show is definitely more compact, but there actually is a case where it could be a problem due to the discrete amount of time it takes for each evaluation of Now().
    If you're generating a date/time stamp right around the time when the year, month, day, hour, or minute is about to increment, you can get a bad value generated. It's going to be very rare of course, but it could be bizarre in the worst possible cases. As an example, suppose the code is running at approximately midnight on 2008 December 31. By evaluating Now() once, you get a specific value that may turn out to be
    20081231 235959
    or, if run milliseconds later,
    20090101 000000
    The first one is just before the beginning of the year, the second is just after the beginning of the year.
    However, with multiple evaluations of Now(), wDate might be evaluated before midnight as 20081231 and wTime right after midnight, giving you
    20081231 000000
    which is 24 hours earlier! It could even happen within a line of code; VBScript evaluates right to left, so if the date changes immediately after the day is evaluated, then you would get
    20091231 000000
    which is almost a year off.
    The code runs _very_ fast on modern machines so I would be very surprised to see this happen, but the mere possibility would qualify as a bug. That's why I use the longer way that evaluates Now() once.

  • Alex
    4 years ago
    Jun 11, 2008

    Jim -
    These look like they work on Vista with default US date/time settings as well. Unfortunately, I found the cmd approach doesn't work very well if the settings are already in an ISO8601 form (although it _should_ be possible to make a batch file that uses reg.exe to check the registry for the current date settings format and base parsing on that).

  • Niels
    4 years ago
    Jun 06, 2008

    The standard gives several formats, and I find the format

    T:: more readable. Unfortunately one has to define the format in the given language.
    But it is defently worth the effort.

  • Oliver
    4 years ago
    Jun 06, 2008

    what about an even easier approach?

    wDate = CStr(Year(Now) * 10000 + Month(Now) * 100 + Day(Now))
    wTime = Right(CStr(1000000 + Hour(Now) * 10000 + Minute(Now) * 100 + Second(Now)), 6)

    to get an ISO date in a batch file just put the mathematical part of the aforementioned expressions (ie without the string functions) in a vbscript file and return the result with WScript.Quit, like

    WScript.Quit(Year(Now) * 10000 + Month(dtNow) * 100 + Day(Now))

    and retrieve the value by using %ErrorLevel%

  • Jim
    4 years ago
    Jun 06, 2008

    Without knowing it had a definition, I've been using ISO 8601 format for some time for just the advantages you listed, in particular that this format is easy to understand and read, and that it sorts very nicely.

    From a CMD file, you can create an ISO 8601 compatible string for the date by using this:

    FOR /F "tokens=2-4 delims=/ " %%f in ("%date%") do set ISO9601Date=%%h%%f%%g

    Note that I'm using two delimiters here, a forward slash AND a space, the space is necessary to lop off the day of the week from the front of the date variable.

    and for time, use

    FOR /F "tokens=1-3 delims=:." %%f in ("%time: =0%") do set ISO9601Time=%%f%%g%%h


    The %time: =0% (after the colon it is 'space equals 0' changes all the blanks in the time variable to 0, taking care of the single digit hour issue

    (These were prepared on Windows XP Pro using English-US regional settings. Your configuration may require this code to be tweaked)

    Jim

You must log on before posting a comment.

Are you a new visitor? Register Here

advertisement

advertisement

Windows is a trademark of the Microsoft group of companies. Windows IT Pro is used by Penton Media Inc. under license from owner.