 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 1:49 am Post subject: Clock/Timer |
|
|
Hi, I am having difficulty creating an "outline" for my program and I was wondering you guys may have any ideas.
I am trying to create a clock/timer for school. It would tell me what period I am in, how much time left in that period etc. Half of the school has lunch at one time and the other at another time so part of the school has a class while the other is eating lunch. My problem is showing 2 different times at the same time while still making the program extremely customizable. For example have it read a file with times in it and use that file.
An example file would look likes this...
| Code: | 1st Period,080000,083000
Break,083000,083500
2nd Period,083500,090500
Break,090500,091000
Bridges,091000,100500
Break,100500,101000
3rd Period,101000,104000 |
Does anybody have any good ideas for how to begin creating this?
Thanks! |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 1:59 am Post subject: |
|
|
This was my first attempt at writing a GUI for myself with all my shortcuts, times, etc... I work in a field sensitive to time so one of the first things that I tried to do was write an actual world clock based on the 'real' rules for DST in certain areas and time zones... I gave up.
Toggle with capslock, I hope this is not more confusing than it is helpful.
Disclaimer: There are probably better ways to do things than this. In fact, there are. It also doesn't always work right especially for GMT. I wrote this before I even really knew how to write my own functions.
But it does show you how to use the time globals in AHK to at least some degree.
Good luck!
| Code: | #SingleInstance FORCE
;note that the "standard" time variable names EST EDT CET etc, refer to their time ZONES and not to the the daylight offset
;daylight offset is determine by the variable STorDT for us times and EUSTorDT for CET zone (CED is 'central europe daylight')
;msgbox , Today is the %A_DD% of %A_MMMM% and it is TIME %STorDT%
;you can inject artificial dates here to test the script
;replace this line to prime
StringLeft, DLYear, A_YWeek, 4 ;DLYear := 2009
;change these global variables to 2 digit day or month numbers to prime
CurMonth := A_MM ;CurMonth := 3
CurDay := A_DD
CurHour :=
;see also CurHour (find) for day-of simulations at begining of GetDSToffset subroutine
;determine DST start and end for US time zones up front, this only needs to be done once or when the year changes
GoSub, GetDSToffset
;gui positions
;Welcome Text
;todayis
WelcomeY := 0
WelcomeX := 0
;
;clock
ClockY := 30
ClockX := 0
;
;folder buttons
foldersX := 0
foldersY := 70
;build the GUI
;folder buttons
;
Gui 1: font, s14, Arial
;
Gui, Add, Button, x%foldersx% y%foldersy% gFBscripts, SCRIPTS
;
;welcome text
If a_hour < 12
{
ohai :="Good morning, Randall."
}
If a_hour >= 12
{
ohai :="Good afternoon, Randall."
}
If a_hour > 17
{
ohai :="Good evening, Randall."
}
;today is
todayis := "Today is " . A_DDDD . ", " . A_MMMM . " " . A_DD . " " . A_YYYY "."
Gui 1: font, s14, Arial
;
Gui 1: Add, Text, x%welcomex% y%welcomey%, %ohai% %Todayis%
;clock
Gui 1: font, s14, Arial
If STorDT = DT
{
Gui 1: Add, text, x%clockx% y%clocky%, EDT:
Gui 1: Add, text, xp+190 y%clocky%, CDT:
Gui 1: Add, text, xp+190 y%clocky%, MDT:
Gui 1: Add, text, xp+190 y%clocky%, PDT:
}
If STorDT = ST
{
Gui 1: Add, text, x0 y%clocky%, EST:
Gui 1: Add, text, xp+190 y%clocky%, CST:
Gui 1: Add, text, xp+190 y%clocky%, MST:
Gui 1: Add, text, xp+190 y%clocky%, PST:
}
Gui 1: Add, text, xp+190 y%clocky%, GMT:
StampX := clockx + 50
Gui 1: Add, Edit, w135 h24 x%stampx% y%clocky% vClockEST, %TimeStampEST%
Gui 1: Add, Edit, w135 h24 xp+190 y%clocky% vClockCST, %TimeStampCST%
Gui 1: Add, Edit, w135 h24 xp+190 y%clocky% vClockMST, %TimeStampMST%
Gui 1: Add, Edit, w135 h24 xp+190 y%clocky% vClockPST, %TimeStampPST%
Gui 1: Add, Edit, w135 h24 xp+190 y%clocky% vClockGMT, %TimeStampGMT%
Gui 1: Show, AutoSize xCenter y0, RandallF
GoSub Clock ;for instant population on launch
SetTimer, Clock, 1000
Return
Clock:
;if year has changed, run daylight loop again
StringLeft, CurYear, A_YWeek, 4 ;DLYear := 2009
;
If CurYear <> DLYear
{
GoSub GetDSTOffset
}
;get real current time
GMT := A_nowUTC
CET := A_nowUTC
EST := A_nowUTC
CST := A_nowUTC
MST := A_nowUTC
PST := A_nowUTC
;if it's US daylight time
If STorDT = DT
{
EST += 1, H
CST += 1, H
MST += 1, H
PST += 1, H
}
;standard offsets
CET += 1, H
EST += -5, H
CST += -6, H
MST += -7, H
PST += -8, H
;get timestamps
FormatTime, TSGMT, %GMT%, hh:mm:ss tt
FormatTime, TSCET, %CET%, hh:mm:ss tt
FormatTime, TSEST, %EST%, hh:mm:ss tt
FormatTime, TSCST, %CST%, hh:mm:ss tt
FormatTime, TSMST, %MST%, hh:mm:ss tt
FormatTime, TSPST, %PST%, hh:mm:ss tt
;update the GUI
GuiControl, 1:,ClockGMT, %TSGMT%
GuiControl, 1:,ClockEST, %TSEST%
GuiControl, 1:,ClockCST, %TSCST%
GuiControl, 1:,ClockMST, %TSMST%
GuiControl, 1:,ClockPST, %TSPST%
Return
;Folder Buttons
FBscripts:
Run, %A_scriptdir%
Return
GetDSToffset:
GoSub, GetDST
;get current hour
CurHour := A_hour
;UNITED STATES
;http://aa.usno.navy.mil/faq/docs/daylight_time.php
;Starting in 2007, daylight time begins in the United States on the second Sunday in March and ends on the first Sunday in November. On the second Sunday in March, clocks are set ahead one hour at 2:00 a.m. local standard time, which becomes 3:00 a.m. local daylight time. On the first Sunday in November, clocks are set back one hour at 2:00 a.m. local daylight time, which becomes 1:00 a.m. local standard time.
;CENTRAL EUROPEAN TIME
;Europe European Union
;UK - (read law)
;Start: Last Sunday in March at 1 am UTC
;End: Last Sunday in October at 1 am UTC
;assumptions for US time zones
;If the month is 1, 2, or 12 it's definately not DT and nothing more is needed except to return ST
If CurMonth < 3
{
;msgbox jan feb (not DST) rule fired
STorDT := "ST"
;take no action to adjust time
}
If CurMonth = 12
{
;msgbox december (not DST) rule fired
STorDT := "ST"
;take no action to adjust time
}
;if the month is 4, 5, 6, 7, 8 or 9 it is definately DT and nothing more is needed except to return DT
If CurMonth contains 4,5,6,7,8,9
{
;msgbox 456789th month (DST) fired
STorDT := "DT"
}
;more complexity is required if it is march or november
;if it's march
If CurMonth = 3
{
;if the current day is PAST the daylight day in march we know it is daylight time
If CurDay > %dayofsunday%
{
;msgbox in march, after DT day fired
STorDT := "DT"
}
;if the current day is BEFORE the daylight day in march we know it is standard time
If CurDay < %dayofsunday%
{
;msgbox in march, before DT day fired
STorDT := "ST"
}
;if the current day IS the daylight savings day we need time calculations
;#############################################LEFT UNFINISHED#####################################################
;On the second Sunday in March, clocks are set ahead one hour at 2:00 a.m. local standard time, which becomes 3:00 a.m. local daylight time.
If CurDay = %dayofsunday%
{
If Curhour >= 2
{
STorDT := "DT"
}
ELSE ;final trap to prevent blank variable
{
STorDT := "ST"
}
;msgbox in march, daylight day fired
;time functions go here, depends on time variables from clock script
}
}
;if it's november
If CurMonth = 11
{
;if the current day is PAST the daylight day in november we know it is standard time
If CurDay > %dayofsunday%
{
;msgbox in november, after ST day fired
STorDT := "ST"
}
;if the current day is BEFORE the daylight day in november we know it is daylight time
If CurDay < %dayofsunday%
{
msgbox , %dayofsunday%
;msgbox in november, before ST day fired
STorDT := "DT"
}
;if the current day IS the daylight savings day we need time calculations
;On the first Sunday in November, clocks are set back one hour at 2:00 a.m. local daylight time, which becomes 1:00 a.m. local standard time.
If CurDay = %dayofsunday%
{
If Curhour >= 2 ;this works as RAW because CurHour is not set from the stamping routine, it uses the current local hour.
{
STorDT := "ST"
}
ELSE ;final trap to prevent blank variable
{
STorDT := "DT"
}
;msgbox in march, daylight day fired
}
}
;assumptions for CET
;###################LEFT UNFINISHED... CET IS wEeeiriiRirdidriRDirdd###############
;Start: Last Sunday in March at 1 am UTC
;End: Last Sunday in October at 1 am UTC
If CurMonth < 3
{
;msgbox jan feb (not DST) rule fired
EUSTorDT := "ST"
;take no action to adjust time
}
Return
GetDST:
;dst start
Date := DLYear . "03" ;cur year and march
Number := 2 ;second sunday
GoSub , GetSundayByNumber
;msgbox , Daylight savings begins on the %dayofsunday% of March in %DLyear%
;dst end
Date := DLYear . "11" ;cur year and november
Number := 1 ;first sunday
GoSub , GetSundayByNumber
;msgbox , Daylight savings ends on the %dayofsunday% of November in %dlyear%
Return
GetSundayByNumber:
Date := SubStr(Date, 1, 6)
Days := 0
FormatTime, WD, %Date%, WDay
If (--WD)
Days := 7 - WD
Days += --Number * 7
Date += Days, D
DSTcalcStamp := % SubStr(Date, 1, 8) ;example output 20090308
DayOfSunday := % SubStr(DSTcalcStamp, 7, 2)
;msgbox , %dayofsunday%
Return
Mbutton::
SetTitleMatchMode, 2
IfWinActive, Microsoft Excel
{
Send, !hfp
}
Return
CapsLock::
IfWinExist, RandallF
{
Gui, Hide
}
Else
{
Gui, Show
}
Return
GuiClose:
Pause::
ExitApp |
</mess> |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 2:10 am Post subject: |
|
|
| Thanks randallf. I already know how to display/format time. I just can't figure out a "good" way to start the countdown and track multiple countdowns. |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 2:35 am Post subject: |
|
|
| System Monitor wrote: | | Thanks randallf. I already know how to display/format time. I just can't figure out a "good" way to start the countdown and track multiple countdowns. |
I would go about it with functions on timers. Each function evalutes a particular break period. You write another function to refresh the GUI variables using GuiControl. The return values of the functions are the time remaining until each period is over.
Maybe like, (you will of course want to move the functions somewhere else, this is only an example)
| Code: | #Persistent ;important
;my times
1pS := 080000 ;first period start
1pE := 083000 ;first period end
1bS := 083000 ;first break start
1bE := 083500 ;first break end
;etc etc
;these also serve to prime the initial GUI
1p(now, 1pS, 1pE, byRef 1pO) ;1pO (first period over) is evaluated for true or false in the main loop
{
;string handling and other commands that compare A_now to the value of 1pS and 1pE
;if it is found that it's getting close to the end of the period
;GuiUpdate text color to red
;if it is found that it's the end of the period
;guiupdate text to grey'd out
;1pO should resolve to the amount of time remaining until the first period is over
Return
}
;main program flow
Gui, Show
SetTimer, Checktimes, 500 ;every half second should more than suffice for this application
Checktimes:
1p(A_now, 1pS, 1pE, 1pO)
;GuiControl command that updates the GUI time for 1p remaining using the 1pO value returned from the 1p() function from byref
;etc for 1b(), 2p(), 2b(), etc
Return
;your GUI would look something like this
/*
1st Period: (time remaining until end)
1st Break: (time remaining until end)
2nd Period: (time remaining until end)
ETC
*/ |
So basically you are constantly evaluating the time left for each period or break to end and updating the GUI with it every half second. |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 3:13 am Post subject: |
|
|
I want the script to be much more dynamic. For example on the fly you could create a text file and load it with program (without changing the program source) and it would work.
I think now my only difficulty is to find when to start the countdown. Also have it still functional after school is over. |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 3:29 am Post subject: |
|
|
| I just realized that my problem is how to start the countdown. To specify it is easy to display the time til x but how do I tell the script to start counting down at lets say 8:00 AM, but do that dynamically for many different times. |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 3:32 am Post subject: |
|
|
If your script can always tell the time remaining then it shouldn't matter when you start it.
You should be (probably are) using A_NOW and comparing it to your start and stop times.
If this is so, it shouldn't matter WHEN you launch the script, it should have the correct countdowns regardless...
So if your problem is getting it to run at 8am,
http://support.microsoft.com/kb/308569
If not, please elaborate? |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 3:40 am Post subject: |
|
|
| randallf wrote: | | You should be (probably are) using A_NOW and comparing it to your start and stop times. |
Yep!
Sorry for the bad explanation. Once the period changes I want a text label to change to the next period and say how much is left in that period.
If you still don't get it say so.
I think it might be useful to see what my gui is going to look like. Just ignore the listbox. After I get the time working it is supposed to contain a list of all the periods and their start and end times with the current one highlighted.
| Code: | #SingleInstance force
SetTimer, Second, 1000
Gui, Add, ListBox, x4 y92 w464 h164 , ListBox
Gui, Add, MonthCal, x123 y259 w228 h163 ,
gui, font,s20, Verdana ;add cwhite
Gui, Add, Text, x3 y4 w466 h43 vTime , Time:
Gui, Add, Text, x7 y55 w461 h30 , Time Left in xth Period:
;Start with correct time
FormatTime, timenow, , h:mm:ss tt
GuiControl,,Time, Time: %timenow%
; Generated using SmartGUI Creator 4.0
Gui, Show, x360 y162 h517 w546, Time
Return
GuiClose:
ExitApp
Second:
FormatTime, timenow, , h:mm:ss tt
GuiControl,,Time, Time: %timenow%
return
|
Edit: Removed a lot of "test" code |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 3:57 am Post subject: |
|
|
| System Monitor wrote: | | randallf wrote: | | You should be (probably are) using A_NOW and comparing it to your start and stop times. |
Yep!
Sorry for the bad explanation. Once the period changes I want a text label to change to the next period and say how much is left in that period.
If you still don't get it say so.
I think it might be useful to see what my gui is going to look like. Just ignore the listbox. After I get the time working it is supposed to contain a list of all the periods and their start and end times with the current one highlighted.
|
From your code example it seems that you want it to display the period number (or break number) and the time remaining for just that period.
Using the previous example, just create a single timer constructed in this fashion: (technically this is a bit wasteful, potentially you could use recursion where each function calls the next only when it decides that each period is over, however we are using so little memory in this particular application compared to what any modern computer is capable of that it should never ever be a concern)
Construct your functions that evaluate each period so that if the period is evaluated as ended, they do nothing. Include in each function an assignment to a single variable, perhaps %CurrentPeriod% which contains the period number (which is ByRef in the function). Do the same, again with a single common variable in each function, for the time remaining.
Then your timer looks like this:
| Code: | UpdateTimes:
1p(A_now, 1pS, 1pE, remaining)
1b(etc)
2p(etc)
2b(etc)
3p(etc)
etc
GuiControl ;updates the period number in your gui using %currentperiod%
GuiControl ;updates the time remaining in your gui using %remaining%
Return |
(sorry I edit a lot, please read again if you are viewing this live) |
|
| Back to top |
|
 |
None
Joined: 28 Nov 2009 Posts: 3086
|
Posted: Fri Feb 12, 2010 4:33 am Post subject: |
|
|
You can use ControlSetText to change text in a gui without reshowing It.
| Code: | gui, font, s20, Arial
Gui, Add, Text, x20 y20 w180 h80, 20
Gui, Show, x550 y400 h120 w220, Count Down
Num=20
Loop 20
{
Sleep 500
Num--
ControlSetText, Static1, %Num%, Count Down
}
ControlSetText, Static1, Time Up!, Count Down
Sleep 2000
ExitApp |
|
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 4:37 am Post subject: |
|
|
| None wrote: | You can use ControlSetText to change text in a gui without reshowing It.
|
| Code: | | GuiControl, 1:,ClockGMT, %TSGMT% |
| helpfile wrote: | | Text/Button/GroupBox/StatusBar: Specify for Param3 the control's new text. Since the control will not expand automatically, use GuiControl, Move, MyText, W300 if the control needs to be widened. For StatusBar, this sets the text of the first part only. (use SB_SetText() for greater flexibility). |
I didn't know that you could use ControlSetText on an AHK gui, good to know. I wonder what the differences are? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|