WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Time - Timer and Date Functions
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Setting Time Zone


Question:

Is there a way to set the time zone (besides using up/down arrows in the control panel, either by name (Pacific, Mountain etc) or by + or - (value) relative to GMT .

The setup I am doing is not just for time zone. What I need is a time zone function I can call with an argument that is a digit n, in the range -12 to +12, that indicates the time zone i want for that laptop, relative to GMT. Not worried about standard/vs/DST

Answer:

;===========================================================================
;
; This gets info from the registry based on a predefined list of
; time zones. It then updates the Time Zone Information in the
; registry based on a selection in an itembox in a dialog.
;
; Takes Daylight Savings Time into account
;
; Due to the IntControl(59,-1,"",0,0) there is a noticeable pause of
; six or seven seconds after you select the timezone.
;
; If you don't run this compiled you will get prompted with messages
; about reloading the program. Click "No". The best thing would be to
; run compiled.
;
; Written and tested on WinXP.
;
;===========================================================================


;===========================================================================
;
; Timezone program
;
;===========================================================================

:init

  IntControl(12,5,0,0,0)                           ; Allow quite termination

;  Timedelay(2)
  exepath = FilePath(IntControl(1004,0,0,0,0))

  ; Turn on debugging?
  If IsKeyDown(@CTRL) || FileExist("%exepath%debugon.chk")
    Debug(@ON)
  EndIf

  ; Turn on debug tracing?
  If IsKeyDown(@SHIFT) || FileExist("%exepath%debugtraceon.chk")
    DebugTrace(@ON,"%exepath%trace2.txt")
  EndIf

  spaces = StrFill(" ",50)
  tzsel = "NONE"

  tzinfo = StrCat("(GMT-05:00) Eastern Time (PR/VI)",spaces,"^eastern")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-05:00) Eastern Time (US & Canada)",spaces,"^Eastern Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-06:00) Central Time (US & Canada)",spaces,"^Central Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-07:00) Mountain Time (US & Canada)",spaces,"^Mountain Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-08:00) Pacific Time (US & Canada); Tijuana",spaces,"^Pacific Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-09:00) Alaska",spaces,"^Alaskan Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT-10:00) Hawaii",spaces,"^Hawaiian Standard Time")
  tzinfo = StrCat(tzinfo,@TAB,"(GMT+10:00) Guam, Port Moresby",spaces,"^West Pacific Standard Time")

  GoSub definefuncs

  date = TimeYmdHms()


;===========================================================================
:main

TZFormat=`WWWDLGED,6.1`

TZCaption=`Set Time Zone`
TZX=171
TZY=117
TZWidth=142
TZHeight=098
TZNumControls=004
TZProcedure=`TZCBP`
TZFont=`DEFAULT`
TZTextColor=`DEFAULT`
TZBackground=`DEFAULT,DEFAULT`
TZConfig=0

TZ001=`009,077,036,012,PUSHBUTTON,DEFAULT,"Set",1,2,32,DEFAULT,DEFAULT,DEFAULT`
TZ002=`057,077,036,012,PUSHBUTTON,DEFAULT,"Cancel",99,3,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
TZ003=`009,003,074,008,STATICTEXT,DEFAULT,"Pick Desired Timezone",DEFAULT,4,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
TZ004=`007,015,124,056,ITEMBOX,tzinfo,DEFAULT,DEFAULT,1,256,DEFAULT,DEFAULT,DEFAULT`

ButtonPushed=Dialog("TZ")

If tzsel == "NOT CHANGED"
  displaymsg = tzsel
Else
  newzone = StrTrim(ItemExtract(1,tzsel,"^"))
  displaymsg = "Time Zone set to %newzone%"
EndIf

Display(2,"Time Zone Set",displaymsg)


;===========================================================================
:finish

  Exit


;===========================================================================
:definefuncs

  #DefineSubRoutine TZCBP(TZ_Handle,TZ_Message,TZ_ID,rsvd1,rsvd2)

    ;DialogprocOptions Constants
    MSG_INIT=0                ; The one-time initilization
    MSG_BUTTONPUSHED=2        ; Pushbutton or Picturebutton
    MSG_ITEMBOXDOUBLECLICK=13  ; Get double-click message on an ItemBox

    ;DialogControlSet / DialogControlGet Constants
    DC_ITEMBOXCONTENTS=5      ; ITEMBOX FILELISTBOX DROPLISTBOX
    DC_ITEMBOXSELECT=6        ; ITEMBOX FILELISTBOX DROPLISTBOX

    Switch TZ_Message

      Case MSG_INIT
        DialogProcOptions(TZ_Handle,MSG_BUTTONPUSHED,@TRUE)
        DialogProcOptions(TZ_Handle,MSG_ITEMBOXDOUBLECLICK,@TRUE)
        Return(-1)

      Case MSG_ITEMBOXDOUBLECLICK
        tzsel = DialogControlGet(TZ_Handle,004,DC_ITEMBOXSELECT)
        keyname = ItemExtract(2,tzsel,"^")
        updatetimezone(keyname)
        IntControl(59,-1,"",0,0)
        Return(1)

      Case MSG_BUTTONPUSHED
        Switch TZ_ID
          Case 001
            tzsel = DialogControlGet(TZ_Handle,004,DC_ITEMBOXSELECT)
            keyname = ItemExtract(2,tzsel,"^")
            updatetimezone(keyname)
            IntControl(59,-1,"",0,0)
            Return(-1)

          Case 002
            tzsel = "NOT CHANGED"
            Return(-1)

        EndSwitch           ;TZ_ID
        Return(-1)          ;  Do default processing

    EndSwitch       ; TZ_Message
    Return(-1)      ;  Do default processing

  #EndSubRoutine       ;End of Dialog Callback TZCBP


  #DefineFunction updatetimezone(keyname)

    date = TimeYmdHms()

    keytoget = StrCat("SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\",keyname)
    hnd = RegOpenKey(@REGMACHINE,keytoget)
    dltname = RegQueryValue(hnd,"[dlt]")
    stdname = RegQueryValue(hnd,"[std]")

    tzi = RegQueryBin(hnd,"[tzi]")

    bias = reverse(StrSub(tzi,1,11))
    bias = udfHexToDec(bias)

    stdbias = reverse(StrSub(tzi,13,11))
    stdbias = udfHexToDec(stdbias)

    dltbias = reverse(StrSub(tzi,25,11))
    dltbias = udfHexToDec(dltbias)

;    stdstart = strclean(strsub(tzi,37,47)," ",",",@false,1)
;    dltstart = strclean(strsub(tzi,85,47)," ",",",@false,1)

    stdstart = StrSub(tzi,37,47)
    std1 = StrSub(stdstart,1,11)
    std2 = StrSub(stdstart,12,6)
    std3 = StrSub(stdstart,18,30)
    stdstmm = udfHexToDec(StrSub(stdstart,7,2))
    stdstdow = udfHexToDec(StrSub(stdstart,13,2))
    stdstwk = udfHexToDec(StrSub(stdstart,19,2))
    stdsthr = udfHexToDec(StrSub(stdstart,25,2))
    yyyy = StrSub(date,1,4)

    stdstart = StrCat(std1,std3,std2)  ; reorder

    dltstart = StrSub(tzi,85,47)
    dlt1 = StrSub(dltstart,1,11)
    dlt2 = StrSub(dltstart,12,6)
    dlt3 = StrSub(dltstart,18,30)
    dltstmm = udfHexToDec(StrSub(dltstart,7,2))
    dltstdow = udfHexToDec(StrSub(dltstart,13,2))
    dltstwk = udfHexToDec(StrSub(dltstart,19,2))
    dltsthr = udfHexToDec(StrSub(dltstart,25,2))
    yyyy = StrSub(date,1,4)

    dltstart = StrCat(dlt1,dlt3,dlt2)  ; reorder

    RegCloseKey(hnd)

    ; Ok, now we have all the info. Update the Time Zone Info

    keytoupdate = StrCat("System\CurrentControlSet\Control\TimeZoneInformation")
    hnd = RegOpenKey(@REGMACHINE,keytoupdate)

    If dltstart == "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
      dltflag = "00 00 00 00"
      activebias = bias
    Else
      dltflag = "01 00 00 00"
      startdatex = StrCat(yyyy,":",stdstmm,":15:",stdsthr,":00:00")
      stdstartdt = udfGetNthDOWInMonth(startdatex,stdstwk,stdstdow)
      startdatex = StrCat(yyyy,":",dltstmm,":15:",dltsthr,":00:00")
      dltstartdt = udfGetNthDOWInMonth(startdatex,dltstwk,dltstdow)

      If date >= dltstartdt && date <= stdstartdt
        activebias = bias + dltbias
      Else
        activebias = bias
      EndIf
    EndIf

    stat = RegSetBin(hnd,"[daylightflag]",dltflag)
    oldbias = RegQueryDword(hnd,"[bias]")
    biasdiff = (oldbias - bias)/60
    stat = RegSetDword(hnd,"[bias]",bias)
    stat = RegSetValue(hnd,"[standardname]",stdname)
    stat = RegSetDword(hnd,"[standardbias]",stdbias)
    stat = RegSetBin(hnd,"[standardstart]",stdstart)
    stat = RegSetValue(hnd,"[daylightname]",dltname)
    stat = RegSetDword(hnd,"[daylightbias]",dltbias)
    stat = RegSetBin(hnd,"[daylightstart]",dltstart)
    stat = RegSetDword(hnd,"[activetimebias]",activebias)


    RegCloseKey(hnd)

    If biasdiff < 0
      biasdiff = Abs(biasdiff)
      biasdiff = StrFixLeft(biasdiff,"0",2)
      newtime = TimeSubtract(date,StrCat("0000:00:00:",biasdiff,":00:00"))
    Else
      biasdiff = StrFixLeft(biasdiff,"0",2)
      newtime = TimeAdd(date,StrCat("0000:00:00:",biasdiff,":00:00"))
    EndIf

   IntControl(58,newtime,0,0,0)



    Return(@TRUE)

  #EndFunction

  #DefineFunction udfHexToDec(sHex)
  sHexChars = "0123456789ABCDEF"
  sHex = StrUpper(StrTrim(sHex))
  iHexLen = StrLen(sHex)
  iDec = 0
  For iHex=1 To iHexLen
     iDec = (iDec<<4)+StrIndex(sHexChars,StrSub(sHex,iHex,1),0,@FWDSCAN)-1
  Next
  Return (iDec)
  ; Note: Returned negative numbers are ok for use in WinBatch.
  #EndFunction

  #DefineFunction udfDecToHex_3 (iDecimal, iPadLength, iCaseMode)
  iPadLength = Min(8,Max(1,iPadLength))
  If Max(0,Min(1,iCaseMode)) Then sHexChars = "0123456789ABCDEF"
     Else sHexChars = "0123456789abcdef"
  sHex = ""
  iZ = 1
  For i=7 To 0 By -1
     In = (iDecimal>>(i*4))&15
     If !In Then If iZ Then Continue
     iZ = 0
     sHex = StrCat(sHex,StrSub(sHexChars,In+1,1))
  Next
  sHex = StrFixLeft(sHex,"0",iPadLength)
  Return (sHex)
  #EndFunction

  #DefineFunction reverse (str)

  cnt = ItemCount(str," ")
  newstr = ""

  For I = 1 To cnt
    item = ItemExtract(i,str," ")
    newstr = StrCat(item,newstr)
  Next

  Return (newstr)

  #EndFunction

  #DefineFunction reverse2 (str)

  cnt = ItemCount(str," ")
  newstr = ""

  For I = 1 To cnt
    item = ItemExtract(i,str," ")
    newstr = ItemInsert(item,i,newstr," ")
  Next

  Return (newstr)

  #EndFunction

  #DefineFunction udfGetNthDOWInMonth (sYmdHms, iOccurrence, iDayOfWeek)
  ; With iDayOfWeek = 0..6 ; Sunday..Saturday.
  @YM0 = "0:0:0"
  @YM7 = "0:0:7"
  @YMD = "0:0:D"
  @D   = "D"
  @58  = ":"
  iOccurrence = Min(5,Max(1,iOccurrence))                                             ; Limit to 1..5 weeks.
  iDayOfWeek  = Min(6,Max(0,iDayOfWeek))                                              ; Limit to 0..6 days.
  iMonth  = ItemExtract(2,sYmdHms,@58)                                                ; Save for later check.
  sYmdHms = ItemReplace(1,3,sYmdHms,@58)                                              ; Set the 01.mm.yyyy of month.
  iFirstDay = ((TimeJulianDay(sYmdHms)+5) mod 7)                                      ; Sunday=0
  If ((iOccurrence==1)&&(iDayOfWeek==iFirstDay)) Then Return (TimeAdd(sYmdHms,@YM0))  ; Return if first day of month hits the rule.
  sYmdHms = TimeAdd(sYmdHms,StrReplace(@YMD,@D,(7+iDayOfWeek-iFirstDay) mod 7))       ; Add diff. days to the first occurrence.
  If (iOccurrence==1) Then Return (sYmdHms)                                           ; Return if this day hits the rule.
  sYmdHms = TimeAdd(sYmdHms,StrReplace(@YMD,@D,(7*(iOccurrence-1))))                  ; Add diff. weeks to hit the rule.
  If (iMonth!=ItemExtract(2,sYmdHms,@58)) Then sYmdHms = TimeSubtract(sYmdHms,@YM7)   ; Fallback if necessary and subtract 7 days.
  Return (sYmdHms)
  ;..........................................................................................................................................
  ; This Function "udfGetNthDowInMonth" returns the Nth occurence of the day of the week
  ; (for example, the second Tuesday) in the specified month.
  ; If the Nth day cannot be resolved in this month, then the last occurence of day will be returned.
  ; (for example : the fifth Thursday in July 2002 does not exist (actually it will be calculated to the 01.08.2002),
  ; so this function returns the last 'good' Thursday 25.07.2002.
  ;..........................................................................................................................................
  #EndFunction



  Return

  Exit


Article ID:   W16221
File Created: 2012:08:07:09:08:00
Last Updated: 2012:08:07:09:08:00