Older Version Newer Version

harmonv harmonv Sep 30, 2008

[[code format="vbnet"]]
' Time Zone: Extreme Coding Challenge
' entry of Harmon V. -- GUI version
' released as public domain
' LB\timezone2.bas

' The 27 megacities with populations of 10 million or more.
' daylight savings/summer start and stop times from www.dateandtime.com

Rem  #    City, Country            Pop.          ST       DT start & End
Data  1, "Tokyo, Japan",          "33,600,000", "UTC+9", "NONE"  ' 35*41'N x 139*46'E
Data  2, "Seoul, South Korea",    "23,400,000", "UTC+9", "NONE"
Data  3, "Mexico City, Mexico",   "22,400,000", "UTC-6", "Sun 06-APR-08 02:00", "Sun 26-OCT-08 02:00"
Data  4, "New York City, USA",    "21,962,000", "UTC-5", "Sun 09-MAR-08 02:00", "Sun 02-NOV-08 02:00"
Data  5, "Mumbai, India",         "21,600,000", "UTC+5.5", "NONE"
Data  6, "Delhi, India",          "21,500,000", "UTC+5.5", "NONE"
Data  7, "São Paulo, Brazil",     "20,600,000", "UTC-3", "Sun 19-OCT-08 00:00", "Sun 17-FEB-09 00:00"
Data  8, "Los Angeles, USA",      "18,000,000", "UTC-8", "Sun 09-MAR-08 02:00", "Sun 02-NOV-08 02:00"
Data  9, "Shanghai, China",       "17,500,000", "UTC+8", "NONE"
Data 10, "Osaka, Japan",          "16,700,000", "UTC+9", "NONE"
Data 11, "Cairo, Egypt",          "16,100,100", "UTC+2", "Fri 25-APR-08 00:00", "Fri 29-AUG-08 00:00"
Data 12, "Buenos Aires,Argentina","16,000,000", "UTC-3", "Sun 19-OCT-08 00:00", "Sun 16-MAR-09 00:00"
Data 13, "Kolkata, India",        "15,700,000", "UTC+5.5", "NONE"
Data 14, "Manila, Philippines",   "15,600,000", "UTC+8", "NONE"
Data 15, "Jakarta, Indonesia",    "15,100,000", "UTC+7", "NONE"
Data 16, "Karachi, Pakistan",     "15,100,000", "UTC+5", "Sun 01-Jun-08 00:00", "Sat 01-NOV-08 00:00"
Data 17, "Tehran, Iran",          "13,500,000", "UTC+3.5", "Fri 21-MAR-08 00:00", "Sun 21-SEP-08 00:00"
Data 18, "Beijing, China",        "12,800,000", "UTC+8", "NONE"
Data 19, "Dhaka, Bangladesh",     "12,750,000", "UTC+6", "NONE"
Data 20, "Lahore, Pakistan",      "12,700,000", "UTC+5", "Sun 01-JUN-08 00:00", "Sat 01-NOV-08 00:00"
Data 21, "London, England",       "12,500,000", "UTC+0", "Sun 30-MAR-08 01:00", "Sun 26-OCT-08 02:00"
Data 22, "Paris, France",         "12,000,000", "UTC+1", "Sun 30-MAR-08 02:00", "Sun 26-OCT-08 03:00"
Data 23, "Istanbul, Turkey",      "11,800,000", "UTC+2", "Sun 30-MAR-08 03:00", "Sun 26-OCT-08 04:00"
Data 24, "Rio de Janeiro, Brazil","11,500,000", "UTC-3", "Sun 19-OCT-08 00:00", "Sun 17-FEB-09 00:00"
Data 25, "Lagos, Nigeria",        "10,200,000", "UTC+1", "NONE"
Data 26, "Moscow, Russia",        "10,100,000", "UTC+3", "Sun 30-MAR-08 02:00", "Sun 26-OCT-08 03:00"
Data 27, "Bangkok, Thailand",     "10,100,000", "UTC+7", "NONE"

Struct timeZoneData, _
  Bias As Long, _
  StandardName As Char[64], _
  StandardDateYear As Short, _
  StandardDateMonth As Short, _
  StandardDateDayOfWeek As Short, _
  StandardDateDay As Short, _
  StandardDateHour As Short, _
  StandardDateMinute As Short, _
  StandardDateSecond As Short, _
  StandardDateMilliseconds As Short, _
  StandardBias As Long, _
  DaylightName As Char[64], _
  DaylightDateYear As Short, _
  DaylightDateMonth As Short, _
  DaylightDateDayOfWeek As Short, _
  DaylightDateDay As Short, _
  DaylightDateHour As Short, _
  DaylightDateMinute As Short, _
  DaylightDateSecond As Short, _
  DaylightDateMilliseconds As Short, _
  DaylightBias As Long

  Calldll #kernel32, "GetTimeZoneInformation", timeZoneData As Struct, ret As Long

  Global myUTCoffset
  myUTCoffset = timeZoneData.Bias.struct + timeZoneData.DaylightBias.struct

  ncities = 27
  Dim city$(ncities) ' City, Country
  Dim pop$(ncities)  ' population of megacity (aka: metropolitan area)
  Dim st$(ncities)   ' standard time (in terms of UTC)  ie:UTC-3
' Next two arrays deal with daylight savings time (DST)
' format of these two strings is "Aaa dd-MMM-yy HH:MM"
  Dim dtstart$(ncities) ' When DST starts or NONE if area does not observe DST
  Dim dtstop$(ncities)  ' When DST stops

' load arrays
  For a = 1 To ncities
    Read n, a$, b$, c$, d$
    If d$<>"NONE" Then Read e$ Else e$ = ""
    city$(a) = a$
    pop$(a) = b$
    st$(a) = c$
    dtstart$(a) = d$
    dtstop$(a) = e$
    Print n;" "; a$; Tab(28);" "; b$;" "; c$;"  "; d$;" "; e$
  Next a

' GUI code begins here
  WindowWidth = 500
  WindowHeight = 400
  Statictext #win.banner1, "Time Zone -- Extreme Coding Challenge", 80, 25, 350, 25
  Statictext #win.now1, "Local Date and Time :", 10, 75, 400, 25
  Statictext #win.now2, "", 120, 100, 150, 25
  Statictext #win.now3, "", 280, 100, 100, 25

  Statictext #win.UTC,  "UTC/GMT Date and Time :", 10, 125, 400, 25
  Statictext #win.UTC2, "",  120, 150, 400, 25

  Statictext #win.txt, "<< Select megacities >>", 120, 190, 300, 25
  Combobox #win.cb1, city$(), citypick,  10, 220, 220, 100
  Statictext #win.citya, "",  20, 250, 200, 50 ' print city date & time

  Combobox #win.cb2, city$(), citypick, 250, 220, 220, 100
  Statictext #win.cityb, "", 260, 250, 200, 50 ' print city date & time

  Open "UTC/GMT Time Zone Utility" For window_nf As #win
  #win, "trapclose [xitprog]"
  winOpen = 1
  #win, "font Verdana 12"

[again]
  Timer 0
' * Program must first show the current date and time based upon
'   Liberty BASIC's native Date$() and Time$() functions.
  dateNow$ = Date$()
  timeNow$ = Time$()

  #win.now2, dateNow$
  #win.now3, timeNow$

' * Program must calculate GMT
' convert local time to UTC/GMT time
  dateTimeUTC = Date$("days") + Time$("seconds")/86400 + myUTCoffset/1440

' * Program must then allow user to select at least 2 other time zones.
  #win.cb1, "selectionindex? a"
  If a>0 Then Call citypick "#win.cb1"
  #win.cb2, "selectionindex? a"
  If a>0 Then Call citypick "#win.cb2"

' * Program must display the GMT as well as the selected date(s) and time(s).
  #win.UTC2, days2DT$(dateTimeUTC)

  Timer 1000, [again]
Wait

[xitprog]
  Print "Done."
  Timer 0
  If winOpen=1 Then Close #win
End

Sub citypick handle$
  Timer 0
  #handle$, "selectionindex? a"
  dateTimeUTC = Date$("days") + Time$("seconds")/86400 + myUTCoffset/1440
  UTCoffset = Val(Mid$(st$(a),4))/24  ' convert hours to decimal days
  cityDateTime = dateTimeUTC + UTCoffset

  t1$ = dtstart$(a)
  t2$ = dtstop$(a)
  If onDST(cityDateTime, t1$, t2$) Then cityDateTime = cityDateTime + 1/24

  If handle$="#win.cb1" Then
    #win.citya, days2DT$(cityDateTime) ' print city date & time
  Else
    #win.cityb, days2DT$(cityDateTime) ' print city date & time
  End If
  Timer 1000, [again]
End Sub  ' citypick

' returns 1 if we're on daylight savings/summer time, else returns 0
' t1$ & t2$ format = "Fri 21-MAR-08 00:00"
Function onDST(nday, t1$, t2$)
  If t1$="NONE" Then
    onDST = 0
  Else
    startime$ = Right$(t1$, 5)
    sec1 = 3600*Val(Left$(startime$,2)) + 60*Val(Right$(startime$,2))
    dt1 = Date$(Mid$(t1$, 5, 9)) + sec1/86400

    stoptime$ = Right$(t2$, 5)
    sec2 = 3600*Val(Left$(stoptime$,2)) + 60*Val(Right$(stoptime$,2))
    dt2 = Date$(Mid$(t2$, 5, 9)) + sec2/86400

    ' is our local time "nday" between our start & stop dates?
    If dt1<nday And nday<dt2 Then onDST = 1 Else onDST = 0
  End If
End Function  ' onDST

' Convert decimal days format to standard "MM/DD/YYYY  HH:MM:SS" format
Function days2DT$(DyTm)
  xdate$ = Date$(Int(DyTm))
  xtime  = (DyTm Mod 1)*86400  ' in seconds since midnight
  xtime$ = sec2hms$(xtime)
  days2DT$ = xdate$; "     "; xtime$
End Function   ' days2DT$

' Convert n seconds into standard HH:MM:SS time string
Function sec2hms$(n)
  hh = Int(n/3600)
  mm = Int((n Mod 3600) / 60)
  ss = Int((n Mod 60) + 0.5)
  sec2hms$ = Right$(Str$(hh+100),2);":"; _
             Right$(Str$(mm+100),2);":"; _
             Right$(Str$(ss+100),2)
End Function  ' sec2hms$ 
[[code]]