PROGRAM WorldClock; { A program to display the current time in all the time zones of the world based on the internal clock and calendar in the ST. Author : Merlin L. Hanson Genie adr : M.L.HANSON Version : 1.0 Released to public domain : 5-27-88. Warranty : none whatsoever.} CONST {$I GEMCONST.PAS} TYPE {$I GEMTYPE.PAS} {$I GEMSUBS.PAS} {$I CURSOR.PAS} {$I DayOWeek.Pas} PROCEDURE DoIt; CONST NoBorder = 0; Black = 384; VAR CityArray : ARRAY [1..24]OF string[20]; {Pacific zone..Yukon zone} TimeArray : ARRAY [1..24]OF 0..23; {hours} DayArray : ARRAY [1..24]OF 0..6; {Sun..Sat} i,j : integer; Month,Hour,Minute : integer; DST : boolean; PROCEDURE DisplayCoverSheet; CONST w = 39; h = 16; VAR s : ARRAY [1..12] OF string[35]; Box : dialog_ptr; OK : integer; PROCEDURE MakeText (Box : dialog_ptr; X : integer; Y : integer; NChar : integer; S : string); VAR junk : integer; BEGIN {maketext} junk := Add_DItem(Box,G_String,None, X,Y,NChar,1, NoBorder,Black); Set_DText(Box,junk,S,System_Font,TE_Left); END {maketext}; PROCEDURE DrawBox; VAR i, x, y : integer; BEGIN s[1] := ' WORLD CLOCK'; s[2] := ' Version 1.0'; s[3] := ' by'; s[4] := ' Merlin L. Hanson'; s[5] := ' Genie : M.L.HANSON'; s[6] := ' 1832 Noble Road'; s[7] := ' Arden Hills, Mn 55112'; s[8] := ' '; s[9] := ' Portions of the product are'; s[10] := 'Copyright 1986, OSS and CCD.'; INSERT (CHR(189),s[10],11 ); s[11] := ' Used by Permission of OSS.'; s[12] := ' OK '; Box := New_Dialog(12, 0,0,w,h); x := 3; y := 1; FOR i := 1 TO 11 DO MakeText(Box,x,y + i, 34, s[i]); x := 17; y := 14; OK := Add_DItem(Box,G_Button, Selectable | Exit_Btn | Default, x,y,4,1, NoBorder,Black); Set_DText(Box,OK,s[12],System_Font,TE_Left); END {drawbox}; BEGIN {displaycoversheet} DrawBox; Center_Dialog(Box); OK := Do_Dialog(Box,0); End_Dialog(Box); ClrScr; END {displaycoversheet}; PROCEDURE FillCityArray; BEGIN CityArray[1] := 'San Francisco '; CityArray[2] := 'Denver '; CityArray[3] := 'Chicago '; CityArray[4] := 'New York '; CityArray[5] := 'Caracas '; CityArray[6] := 'Rio DeJaneiro '; CityArray[7] := 'Falkland Isl. '; CityArray[8] := 'Azores Isl. '; CityArray[9] := 'London '; CityArray[10] := 'Paris '; CityArray[11] := 'Athens '; CityArray[12] := 'Moscow '; CityArray[13] := 'Dubai '; CityArray[14] := 'Karachi '; CityArray[15] := 'Dacca '; CityArray[16] := 'Bangkok '; CityArray[17] := 'Singapore '; CityArray[18] := 'Tokyo '; CityArray[19] := 'Sydney '; CityArray[20] := 'Noumea '; CityArray[21] := 'Auckland '; {International date line} CityArray[22] := 'Pago Pago,Nome'; CityArray[23] := 'Honolulu '; CityArray[24] := 'Tuamotu Isl. '; END {fillcityarray}; PROCEDURE GetTime; VAR temp : integer; FUNCTION TGetTime : integer; GEMDOS($2C); BEGIN {gettime} Temp := TGetTime; Minute := SHR(Temp,5) & $3F; Hour := SHR(Temp,11) & $1F; END {hourfunc}; PROCEDURE ChangeHourToPacificZone; VAR TimeZoneBox : dialog_ptr; Pushed : tree_index; S : string[20]; Index,BoxText : integer; Item : ARRAY[1..4]OF integer; Find : boolean; PROCEDURE IdentifyTheButton; {returns with pushed in the range 1..4} VAR i : integer; BEGIN i := 1; Find := FALSE; REPEAT IF Item[i] = Pushed THEN Find := TRUE ELSE i := i + 1; UNTIL Find; Pushed := i; END {identifythebutton}; PROCEDURE FillPDT_Entry(Offset : integer); {offset is 1..4 for the 4 continental time zones. Set the time and date for the Pacific time zone.} VAR Day : 0..6; FUNCTION DayCodeF : integer; VAR Temp : integer; Date,Year : integer; FUNCTION TGetDate : integer; GEMDOS ($2A); BEGIN {daycodef} Temp := TGetDate; Date := Temp & $1F; Month := SHR(Temp,5) & $F; Year := SHR(Temp,9) & $7F + 1980; DayCodeF := DayOfWeek(Month,Date,Year); {external function} END {daycode}; PROCEDURE SubtractAnHour; BEGIN IF Hour = 0 THEN BEGIN Hour := 23; {subtract a day} IF Day = 0 THEN Day := 6 ELSE Day := Day - 1; END ELSE Hour := Hour - 1; END {subtractanhour}; PROCEDURE CheckForDaylightSavingTime; VAR Choice : integer; BEGIN DST := FALSE; IF ((Month = 4) OR (Month = 10)) THEN BEGIN Choice := Do_Alert( '[0][Is daylight saving time in effect?][ Yes | No ]',0); IF Choice = 1 THEN DST := TRUE; END; IF (Month > 4) AND (Month < 10) THEN DST := TRUE; IF DST THEN SubtractAnHour; {Base output on monitor on standard time} END {checkfordaylightsavingtime}; BEGIN {fillpdt_entry} Day := DayCodeF; {Hour is global and has been set for local civil time.} WHILE Offset > 1 DO BEGIN SubtractAnHour; Offset := Offset - 1; END; CheckForDaylightSavingTime; {Set the arrays to reflect Pacific _standard_ Time hour and day of the week.} TimeArray[1] := Hour; DayArray[1] := Day; END{fillpdt_entry}; BEGIN {changehourtopacificzone} TimeZoneBox := New_Dialog(5,0,0,34,14); BoxText := Add_DItem(TimeZoneBox,G_String,None, 5,3,30,1, NoBorder,Black); Set_DText(TimeZoneBox,BoxText, 'What Time Zone Are you in?', System_Font,TE_Center); FOR Index := 1 TO 4 DO BEGIN Item[Index] := Add_DItem(TimeZoneBox,G_Button, Radio_Btn|Selectable|Exit_Btn, 11, (3 +(2* Index)) ,12,1, NoBorder,Black); CASE Index OF 1 : S := 'Pacific'; 2 : S := 'Mountain'; 3 : S := 'Central'; 4 : S := 'Eastern'; END {case}; Set_DText(TimeZoneBox,Item[Index],S,System_Font,TE_Center); END; Center_Dialog(TimeZoneBox); Pushed := Do_Dialog(TimeZoneBox,0); IdentifyTheButton; End_Dialog(TimeZoneBox); ClrScr; {Get rid of dithered residue.} FillPDT_Entry(pushed); END {changehourtopacificzone}; PROCEDURE FillTimeAndDayArray; VAR i,Time : integer; DayCode : 0..6; BEGIN {element 1 has the proper hour and day} DayCode := DayArray[1]; Time := TimeArray[1]; FOR i := 2 TO 24 DO BEGIN Time := Time + 1; IF Time = 24 THEN BEGIN Time := 0; IF DayCode = 6 THEN DayCode := 0 ELSE DayCode := DayCode + 1; END; TimeArray[i] := Time; IF i = 22 THEN {just crossed the date line going East, loose a day.} IF DayCode = 0 THEN DayCode := 6 ELSE DayCode := DayCode - 1; DayArray[i] := DayCode; END; END{filltimeanddayarray}; PROCEDURE Display_DST_Notice; VAR Line,Pushed,OK,BoxText : integer; S : string; Box : dialog_ptr; BEGIN Box := New_Dialog(9,0,0,52,14); FOR Line := 1 TO 8 DO BEGIN BoxText := Add_DItem(Box,G_Text,None, 0,Line + 1, 52,1, NoBorder,Black); CASE Line OF 1 : S := 'Time zones with Daylight Savings in effect'; 2 : S := 'are shown in inverse video.'; 3 : S := 'This is only shown for areas which '; 4 : S := 'may be under US control.'; 5 : S := ''; 6 : S := 'You must mentally provide correction for'; 7 : S := 'other areas which you know to have'; 8 : S := 'a similar plan.'; END {case}; Set_DText(Box,BoxText,S,System_Font,TE_Center); END {do}; OK := Add_DItem(Box,G_Button,Selectable|Default|Exit_btn, 24,11,4,1, NoBorder,Black); Set_DText(Box,Ok,' OK ',System_Font,TE_Center); Center_Dialog(Box); Pushed := Do_Dialog(Box,0); End_Dialog(Box); ClrScr; END {display_dst_notice}; PROCEDURE DisplayExitBox; VAR Box : dialog_ptr; OK : integer; BEGIN Box := New_Dialog(2, 70,21,8,3); OK := Add_DItem(Box,G_Button, Selectable | Exit_Btn | Default, 2,1,4,1, NoBorder,Black); Set_DText(Box,OK,' OK ',System_Font,TE_Left); OK := Do_Dialog(Box,0); End_Dialog(Box); ClrScr; END{displayexitbox}; PROCEDURE DisplayMajorZones; VAR i : integer; s : ARRAY[0..6]OF string[9]; PROCEDURE WriteALine(TimeZone : integer); VAR j : integer; BEGIN FOR j := 1 TO LENGTH(CityArray[TimeZone]) DO Write(CityArray[TimeZone,j]); Write(' ',TimeArray[TimeZone]:2,':'); IF Minute < 10 THEN Write('0'); Write(Minute,' '); Write(S[DayArray[TimeZone]]); CASE TimeZone OF 9 : WriteLn(' Greenwich Mean Time'); 21 : WriteLn(' The International date line is'); 22 : WriteLn(' between Auckland and Pago Pago.'); 23 : WriteLn(' (also Anchorage)'); OTHERWISE : WriteLn; END {case}; END {writealine}; PROCEDURE WriteA_DST_Line(TimeZone:integer); VAR j,Time,Day : integer; BEGIN FOR j := 1 TO LENGTH(CityArray[TimeZone]) DO Write(CityArray[TimeZone,j]); InverseVideo; Time := TimeArray[TimeZone]; Day := DayArray[TimeZone]; IF Time = 23 THEN BEGIN Time := 0; IF Day = 6 THEN Day := 0 ELSE Day := Day + 1; END ELSE Time := Time + 1; Write(' ',Time:2,':'); IF Minute < 10 THEN Write('0'); Write(Minute,' '); Write(S[Day]); NormVideo; CASE TimeZone OF 23 : WriteLn(' (also Anchorage)'); OTHERWISE : WriteLn; END {case}; END {write_a_dst_line}; BEGIN {displaymajorzones}; Hide_Mouse; ClrScr; s[0] := 'Sunday '; s[1] := 'Monday '; s[2] := 'Tuesday '; s[3] := 'Wednesday'; s[4] := 'Thursday '; s[5] := 'Friday '; s[6] := 'Saturday '; FOR i := 1 TO 24 DO BEGIN Write(' '); IF DST AND (((i > 0) AND (i < 5)) OR (i > 22)) THEN WriteA_DST_Line(i) ELSE WriteALine(i); END; Show_Mouse; DisplayExitBox; ClrScr; END {displayrmazorzones}; PROCEDURE DisplayOffsetTimeZones; VAR Day,Zone,Min : integer; S : ARRAY[0..6] OF string[9]; PROCEDURE WriteAnEntry; BEGIN Write(' '); Min := Minute; {local := global, will change local} Hour := TimeArray[Zone]; Day := DayArray[Zone]; CASE Zone OF 5 : Write('Gander '); 12 : Write('Tehran '); 13 : Write('Kabul '); 14 : Write('Bombay '); 15 : Write('Rangoon '); 17 : Write('Adelaide '); 24 : Write('Pitcairn Isl. '); END {case}; Min := Min + 30; IF Min > 59 THEN BEGIN {advance the hour} Min := Min - 60; Hour := Hour + 1; IF Hour > 23 {advance the day} THEN BEGIN Hour := 0; IF Day = 6 THEN Day := 0 ELSE Day := Day + 1; END; END {min > 59}; Write(Hour:2,':'); IF Min < 10 THEN Write('0'); Write(Min); WriteLn(' ',S[Day]); END {writeanentry}; BEGIN {displayoffsettimezones} WriteLn; Write(' '); WriteLn('Time zones with a 30 minute offset'); WriteLn; WriteLn; s[0] := 'Sunday '; s[1] := 'Monday '; s[2] := 'Tuesday '; s[3] := 'Wednesday'; s[4] := 'Thursday '; s[5] := 'Friday '; s[6] := 'Saturday '; FOR Zone := 1 TO 24 DO CASE Zone OF 5,12,13,14,15,17,24 : WriteAnEntry; {otherwise do nothing} END {case}; DisplayExitBox; END {displayoffsettimezones}; BEGIN {doit} DisplayCoverSheet; {OSS copyright} FillCityArray; {24 major cities serve as samples} GetTime; ChangeHourToPacificZone; {Gets the date and determines whether DST is in effect.} FillTimeAndDayArray; {Fill for 24 major zones} IF DST THEN Display_DST_Notice; DisplayMajorZones; DisplayOffsetTimeZones; END {doit}; BEGIN {main} IF Init_GEM >= 0 THEN BEGIN ClrScr; Init_Mouse; {else show busy bee when .PRG run from the desktop} DoIt; Exit_GEM; END; END. {program}