Hey, Scripting Guy! How Can I Retrieve Time Zone Information for a Computer?

Hey, Scripting Guy! How Can I Retrieve Time Zone Information for a Computer?

  • Comments 3
  • Likes

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I retrieve time zone information for a computer?

-- AL

SpacerHey, Scripting Guy! AnswerScript Center

Hey, AL. You know, over the Thanksgiving Day weekend the Scripting Guy who writes this column took some time to think about his job, and to think of ways in which he could do that job even better. (Note to the Scripting Editor: Believe it or not, the Scripting Guy who writes this column isn’t perfect. He does have some room for improvement.) One of the conclusions the Scripting Guy who writes this column came to is this: a daily scripting column should be about scripting. A daily scripting column shouldn’t be about a Scripting Guy riding an exercise bike or ranting about people who abuse the express lane at the grocery store. No, a daily scripting column should be about scripting, period. Therefore, no more personal anecdotes; from now on, we’re all business all the time.

You say you have a question first? You’d like to know who won the 2007 Turducken Bowl? Let’s put it this way: it was the 2007 Turducken Bowl that caused the Scripting Guy who writes this column to swear off personal anecdotes forever.

Note. Although we might point out that the Scripting Guy who writes this column did score all seven of his team’s touchdowns. That includes the touchdown he scored when he took the opening kickoff, faked a lateral to the Scripting Significant Other, and then ran right between the two flabbergasted defenders, giving his team an early 7-0 lead.

And no, that’s not a personal anecdote. That’s just a statement of historical fact.

Besides, you know what they say: it’s not whether you win or lose, it’s how you play the game. And, unfortunately, the Scripting Guy who writes this column and his teammate didn’t play the game very well this year.

But that’s OK; after all, this is a daily scripting column, it’s not a column where we point out that the Scripting Guy who writes the column scored all seven of his team’s touchdowns. (Meaning that that his teammate must have scored – well, we’ll let you do the math on that one.) Likewise, this isn’t a column where we point out that the Scripting Son and Scripting Nephew were guilty of offensive pass interference on pretty much every single play; heaven forbid that we should even suggest such a thing. Instead, this is a daily scripting column, a column where we show you how to do scripting type things. You know, things like retrieve time zone information for a computer:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * From Win32_TimeZone")

For Each objItem in colItems
    Set colItems2 = objWMIService.ExecQuery("Select * From Win32_ComputerSystem")

    For Each objItem2 in colItems2
        blnDaylightInEffect = objItem2.DaylightInEffect
    Next

    If blnDaylightInEffect Then
        Wscript.Echo objItem.DaylightName
    Else
        Wscript.Echo objItem.StandardName
    End If
Next

As you can see, there really isn’t much to this script. We start out by conencting to the WMI service on the local computer, then use the following line of code to return a collection of all the time zones that this computer belongs to:

Set colItems = objWMIService.ExecQuery("Select * From Win32_TimeZone")

And before you ask, the answer to both of your questions is this: yes. Yes, you can run this script against a remote computer; all you have to do is assign the name of that computer to the variable strComputer, like so:

strComputer = "atl-fs-01"

And yes, our collection will consist of just one item; that’s because, barring any new discoveries in physics, a computer can only be in any one place – and any one time zone – at a time.

Note. Wouldn’t it have been nice if the Scripting Guy who writes this column could have been in more than one place at a time, enabling him to, say, both play quarterback and wide receiver at the same time? Well, now that you mention it ….

Speaking of time zones, as you probably know, much of the world has a tendency to change times twice a year; in locations like that, part of the year takes place under Daylight Saving Time, and part of the year takes place under Standard Time. (Judging from the view outside the window right now, those of us in Redmond should have done a better job of actually saving some daylight during Daylight Saving Time.) Maybe that doesn’t matter to you; maybe all you care about is the name of the time zone itself. If that’s the case, then the For Each loop we’re about to set up (the one that loops through our collection of time zones) can be as simple as this:

For Each objItem in colItems
    Wscript.Echo objItem.Caption
Next

What does that give us? That gives us output that looks like this:

(GMT-08:00) Pacific Time (US & Canada)

That’s good: it tells us the time zone (Pacific Time) that the computer is running under. What it doesn’t tell us, however, is whether the computer is currently running under Standard Time or Daylight Saving Time. So what the heck; let’s see if we can figure that out as well.

After all, that’s the sort of thing you do in a daily scripting column, right?

With that in mind, the first thing we do within the For Each loop is execute this line of code:

Set colItems2 = objWMIService.ExecQuery("Select * From Win32_ComputerSystem")

If you’re looking at that and thinking, “Wow, that looks like we’re running another WMI query,” well, there’s a good reason for that: we are running another WMI query. Although the Win32_TimeZone class tells us a considerable amount about a computer and its time zone (more on that in a minute) what it doesn’t tell us is whether that computer is running under Daylight Saving Time or Standard Time. To get that information we need to query the Win32_ComputerSystem class. Which, needless to say, is exactly what we did.

After executing our second query we next need to set up a second For Each loop, this one designed to loop through the collection of data returned by the Win32_ComputerSystem class. (Again, this will be a collection containing just one item.) Inside this second loop, we use the following line of code to assign the value of the DaylightInEffect property to a variable named blnDaylightInEffect:

blnDaylightInEffect = objItem2.DaylightInEffect

What’s the purpose of that? Well, DaylightInEffect is a Boolean value that tells us whether or not the computer is running under Daylight Saving Time. If DaylightInEffect is True that means that the computer is running under Daylight Saving Time; if DaylightInEffect is False then that means the computer is running under Standard Time. That also means that all we have to do is examine the value of blnDaylightInEffect and echo back the appropriate message:

If blnDaylightInEffect Then
    Wscript.Echo objItem.DaylightName
Else
    Wscript.Echo objItem.StandardName
End If

As you probably figured out for yourself, DaylightName not only gives us the name of the time zone but also tells us that the computer us running under Daylight Saving Time; StandardName – well, you can definitely figure out for yourself what StandardName does. When we ran this script in Remdond, WA on November 26, 2007 we got back the following:

Pacific Standard Time

Why? Because our computer is running under Pacific Standard Time, that’s why. If we ran this script a month ago, back when Daylight Saving Time was still in effect, we would have gotten this message instead:

Pacific Daylight Time

Like we said, that information could be extremely useful, especially for enterprises who have computers in both Washington state (where we observe Daylight Saving Time) and in Arizona (where they don’t observe Daylight Saving Time.)

But wait: we have a bonus script for you as well. (Yet another thing you’d expect to find in a daily scripting column.) As we noted earlier, the Win32_TimeZone class gives you all sorts of information about a computer and its time zone. What kind of information? Well, for one thing, Win32_TimeZone can tell you the exact date when you need to spring ahead (switch to Daylight Saving Time) or fall back (switch to Standard Time). In fact, here’s a script that tells you that very thing:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_TimeZone")

For Each objItem in colItems
    intMonth =  objItem.DaylightMonth
    Select Case intMonth
        Case 1 strMonth = "January"
        Case 2 strMonth = "February"
        Case 3 strMonth = "March"
        Case 4 strMonth = "April"
        Case 5 strMonth = "May"
        Case 6 strMonth = "June"
        Case 7 strMonth = "July"
        Case 8 strMonth = "August"
        Case 9 strMonth = "September"
        Case 10 strMonth = "October"
        Case 11 strMonth = "November"
        Case 12 strMonth = "December"
    End Select
    intDayOfWeek = objItem.DayLightDayOfWeek
    Select Case intDayOfWeek
        Case 0 strDayOfWeek = "Sunday"
        Case 1 strDayOfWeek = "Monday"
        Case 2 strDayOfWeek = "Tuesday"
        Case 3 strDayOfWeek = "Wednesday"
        Case 4 strDayOfWeek = "Thursday"
        Case 5 strDayOfWeek = "Friday"
        Case 6 strDayOfWeek = "Saturday"
    End Select
    intDay = objItem.DaylightDay
    Select Case intDay
        Case 1 strDay = "first"
        Case 2 strDay = "second"
        Case 3 strDay = "third"
        Case 4 strDay = "fourth"
        Case 5 strDay = "last"
    End Select        
    Wscript.Echo "Daylight Saving Time begins on the " & _
        strDay & " " & strDayOfWeek & " in " & strMonth & "."
    intMonth =  objItem.StandardMonth
    Select Case intMonth
        Case 1 strMonth = "January"
        Case 2 strMonth = "February"
        Case 3 strMonth = "March"
        Case 4 strMonth = "April"
        Case 5 strMonth = "May"
        Case 6 strMonth = "June"
        Case 7 strMonth = "July"
        Case 8 strMonth = "August"
        Case 9 strMonth = "September"
        Case 10 strMonth = "October"
        Case 11 strMonth = "November"
        Case 12 strMonth = "December"
    End Select
    intDayOfWeek = objItem.StandardDayOfWeek
    Select Case intDayOfWeek
        Case 0 strDayOfWeek = "Sunday"
        Case 1 strDayOfWeek = "Monday"
        Case 2 strDayOfWeek = "Tuesday"
        Case 3 strDayOfWeek = "Wednesday"
        Case 4 strDayOfWeek = "Thursday"
        Case 5 strDayOfWeek = "Friday"
        Case 6 strDayOfWeek = "Saturday"
    End Select
    intDay = objItem.StandardDay
    Select Case intDay
        Case 1 strDay = "first"
        Case 2 strDay = "second"
        Case 3 strDay = "third"
        Case 4 strDay = "fourth"
        Case 5 strDay = "last"
    End Select        
    Wscript.Echo "Standard Time begins on the " & _
        strDay & " " & strDayOfWeek & " in " & strMonth & "."
Next

This is all a little complicated thanks to the way this information is stored. The DaylightMonth property is an integer value representing the month (1 for January, 2 for February, etc.). The DaylightDayOfWeek property is an integer value representing the day of the week when Daylight Saving Time begins (e.g., 0 equals Sunday, 1 equals Monday, and so on.) In other words, that property tells us that Daylight Saving Time begins on a Sunday. As to which Sunday, well, that’s the job of the DaylightDay property. This is yet another integer value, with 1 representing the first (in our case) Sunday of the month, 2 representing the second Sunday of the month, etc.

Like we said, it’s a bit complicated, but the end result is simple enough:

Daylight Saving Time begins on the second Sunday in March.

And then we repeat this process with the corresponding Standard Time properties, resulting in output similar to this:

Standard Time begins on the first Sunday in November.

And the great circle of life goes on.

That should do it, AL. And you know, after giving it a little more thought, we decided to go back to the good old days of Hey, Scripting Guy!, the days when we did talk about things other than system administration scripting. Let’s see, what else went on this past weekend …. What’s that? The Apple Cup football game between the University of Washington Huskies and the Washington State Cougars? Right … Listen, have we mentioned lately that this is a daily scripting column? The truth is, there are some things that should never be discussed in a daily scripting column.

And there are also some things, like this year’s Apple Cup, that should never be discussed at all.

Ever.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hey guys...  I know this is very old, but, something that is applicable for me is finding the number of seconds since epoch to match that produced by the time() function in PERL for various reasons (often doing date math and to be able to implement a mix of solutions that may involve both PERL and VBS)....

    Here is a little code that I use to do that.

    Dim gmtOffset, objWMIServices

    now_epoch = DateDiff("s", "01/01/1970 00:00:00", now()) - gmtOffset

    Wscript.Echo now_epoch

    Wscript.Quit

    Public Function iniVars

    Dim colItems, objItem, colItems2, objItem2

    Set objSWMIServices = GetObject ("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

    Set colItems = objSWMIServices.ExecQuery("Select * From Win32_TimeZone")

    For Each objItem in colItems

    Set colItems2 = objSWMIServices.ExecQuery("Select * From Win32_ComputerSystem")

    For Each objItem2 in colItems2

    gmtOffset = ((objItem.Bias)*60) + ((objItem.DaylightBias)*(objItem2.DaylightInEffect)*60)

    Next

    Next

    End Function

  • Let's try it with a little formatting... :)

    Dim gmtOffset, objWMIServices

    now_epoch = DateDiff("s", "01/01/1970 00:00:00", now()) - gmtOffset

    Wscript.Echo now_epoch

    Wscript.Quit

    Public Function iniVars

       Dim colItems, objItem, colItems2, objItem2

       Set objSWMIServices = GetObject ("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

       Set colItems = objSWMIServices.ExecQuery("Select * From Win32_TimeZone")

       For Each objItem in colItems

           Set colItems2 = objSWMIServices.ExecQuery("Select * From Win32_ComputerSystem")

           For Each objItem2 in colItems2

               gmtOffset = ((objItem.Bias)*60) + ((objItem.DaylightBias)*(objItem2.DaylightInEffect)*60)

               Next

           Next

       End Function

  • My apologies....  Posted the wrong copy...  following is the correct code for using VBS to get the UTC and DST adjusted seconds since EPOCH....

    Dim gmtOffset, objWMIServices, wShell, wExec

    initVars()

    now_epoch = DateDiff("s", "01/01/1970 00:00:00", now()) - gmtOffset

    Wscript.Echo now_epoch

    Wscript.Quit

    Public Function initVars

       Dim colItems, objItem, colItems2, objItem2

       Set wShell = CreateObject( "WScript.Shell" )

       Set objSWMIServices = GetObject ("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

       Set colItems = objSWMIServices.ExecQuery("Select * From Win32_TimeZone")

       For Each objItem in colItems

           Set colItems2 = objSWMIServices.ExecQuery("Select * From Win32_ComputerSystem")

           For Each objItem2 in colItems2

               gmtOffset = ((objItem.Bias)*60) + ((objItem.DaylightBias)*(objItem2.DaylightInEffect)*60)

               Next

           Next

       End Function