 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Thu Jul 12, 2007 9:21 am Post subject: nearest time-unit |
|
|
Hey guys,
For my Progress Timer, I wanna make the start date optional - which means that to display the relative progress (percentage), I have to calculate an appropriate start date automatically.
Here's my concept for this, and I'd love to hear some feedback - and maybe even get some help with the implementation (I hate time calculations... ):
The end date (C) is known, as is the current time (B) - and thus I also know the time that's left (x = C - B): | Code: | |_____________________|
| | =x |
A B C
start now end | Knowing x allows me to select an appropriate time unit (or scale); minutes, hours, days, weeks, months, years, decades, centuries, or millennia.
Once I know that, I can calculate the start date based on that unit: | Code: | 0 <= x < 1 min. => A = C - 1 min.
1 min. <= x < 1 hour => A = C - 1 hour
1 hour <= x < 1 day => A = C - 1 day
1 day <= x < 1 week => A = C - 1 week
1 week <= x < 1 month => A = C - 1 month
1 month <= x < 1 year => A = C - 1 year
1 year <= x < 1 decade => A = C - 1 decade
1 decade <= x < 1 century => A = C - 1 century
1 century <= x < 1 millenium => A = C - 1 millenium
x >= 1 millenium => ERROR: Get a life... |
As for the implementation, that would have to be a function that's passed a single date (two if you count A_Now) and returns the appropriate start date.
But I'm not yet sure how to implement this efficiently (i.e. without a lot of nested IF statements).
Any feedback is appreciated! _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Seabiscuit
Joined: 07 Jan 2007 Posts: 109 Location: In fund pe scaun, la o bere prin Romania :D
|
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Thu Jul 12, 2007 2:37 pm Post subject: |
|
|
To be honest, I'm not quite sure what you mean.
Also, shouldn't EnvAdd take care of the actual calculations? _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Seabiscuit
Joined: 07 Jan 2007 Posts: 109 Location: In fund pe scaun, la o bere prin Romania :D
|
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Thu Jul 12, 2007 2:41 pm Post subject: |
|
|
Oh, right; 30 days per month would be just fine. _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
engunneer
Joined: 30 Aug 2005 Posts: 6772 Location: Pacific Northwest, US
|
Posted: Thu Jul 12, 2007 3:28 pm Post subject: |
|
|
I will think about this as I drive to work - A nested If is not such a bad thing. _________________
Unless otherwise noted, all code is untested.
Common Answers: 1.(Loops, Viruses, etc.) 2. Search 3.RTFM |
|
| Back to top |
|
 |
Seabiscuit
Joined: 07 Jan 2007 Posts: 109 Location: In fund pe scaun, la o bere prin Romania :D
|
Posted: Thu Jul 12, 2007 4:16 pm Post subject: |
|
|
Try this and tell me if its not ok. | Code: | C=20171012185312
msgbox % scale(c)
scale(c){
c-=%a_now%,seconds
sc=31104000000/3110400000/311040000/31104000/2592000/604800/86400/3600/60
x=
Loop, parse, sc, /
{
if ((c-A_LoopField)>=0){
x:=A_Index
break
}
}
sc=millenium(s)/century(s)/decade(s)/year(s)/month(s)/week(s)/day(s)/hour(s)/minunte(s)
Loop, parse, sc, /
{
if (A_Index=x){
result=%A_LoopField%
break
}
}
return result
} |
_________________
Backgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet |
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Thu Jul 12, 2007 8:20 pm Post subject: |
|
|
That's a very interesting approach, Seabiscuit!
There seems to be bug though - consider this script: | Code: | results := "results:`n`n"
time := A_Now
time += 30, Seconds
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 30, Minutes
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 12, Hours
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 1, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 15, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 180, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 1800, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 18000, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 180000, days
results .= time . ": " . scale(time) . "`n"
MsgBox %results%
Return
scale(c){
c-=%a_now%,seconds
sc=31104000000/3110400000/311040000/31104000/2592000/604800/86400/3600/60
x=
Loop, parse, sc, /
{
if ((c-A_LoopField)>=0){
x:=A_Index
break
}
}
sc=millenium(s)/century(s)/decade(s)/year(s)/month(s)/week(s)/day(s)/hour(s)/minunte(s)
Loop, parse, sc, /
{
if (A_Index=x){
result=%A_LoopField%
break
}
}
return result
} |
The first run returns nothing. I haven't been able to figure out why yet (as I've said, I hate time calculations... ). _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5068 Location: imaginationland
|
Posted: Thu Jul 12, 2007 8:52 pm Post subject: |
|
|
Instead of using scales why not have everything timed in seconds, and update the progress bar at dynamic intervals such that it equates to a percent increase every time. _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Thu Jul 12, 2007 9:27 pm Post subject: |
|
|
Well, Titan, I'll give you an example:
Say I'm going on vacation in a few weeks.
So I add the Progress Timer to the Windows startup folder to get an update every morning (which I'd close right after having taken a look at it).
Setting a start date there doesn't make much sense, obviously - and neither does what you propose (if I understand it correctly, that is).
With the method outlined above, we could gradually "zoom in" on the timescale as the event draws closer:
First I'd get a percentage based on a months-scale, then on a weeks-scale, etc. (never reaching 100% though, as changing the scale resets the progress bar) - until eventually I can pretty much watch the progress bar advance towards the yearned-for 100%...
(I hope this makes sense!?) _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Seabiscuit
Joined: 07 Jan 2007 Posts: 109 Location: In fund pe scaun, la o bere prin Romania :D
|
Posted: Fri Jul 13, 2007 1:54 am Post subject: |
|
|
Put 0 instead of 60.
| Code: | results := "results:`n`n"
time := A_Now
time += 30, Seconds
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 30, Minutes
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 12, Hours
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 1, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 15, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 180, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 1800, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 18000, days
results .= time . ": " . scale(time) . "`n"
time := A_Now
time += 180000, days
results .= time . ": " . scale(time) . "`n"
MsgBox %results%
Return
scale(c){
c-=%a_now%,seconds
sc=31104000000/3110400000/311040000/31104000/2592000/604800/86400/3600/0
x=
Loop, parse, sc, /
{
if ((c-A_LoopField)>=0){
x:=A_Index
break
}
}
sc=millenium(s)/century(s)/decade(s)/year(s)/month(s)/week(s)/day(s)/hour(s)/minunte(s)
Loop, parse, sc, /
{
if (A_Index=x){
result=%A_LoopField%
break
}
}
return result
} |
 _________________
Backgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet |
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Sat Jul 14, 2007 3:12 pm Post subject: |
|
|
After quite a few test runs, I'm still not sure whether that really fixed the problem.
I've modified the function to return the respective start date (the date passed to the function minus the nearest unit/interval), and I've also done some refactoring (code includes a short test script): | Code: | results := "results:`n`n"
time := A_Now
time += 30, Seconds
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 30, Minutes
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 12, Hours
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 1, days
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 15, days
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 180, days
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 1800, days
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 18000, days
results .= time . ": " . timescale(time) . "`n"
time := A_Now
time += 180000, days
results .= time . ": " . timescale(time) . "`n"
MsgBox %results%
Return
; timescale() by Seabiscuit, modified by FND
timescale(date) {
; initialize
time := date
timeIntervals = 31104000000|3110400000|311040000|31104000|2592000|604800|86400|3600|0
timeUnits = millenium(s)|century(s)|decade(s)|year(s)|month(s)|week(s)|day(s)|hour(s)|minunte(s)
index = ; DEBUG: obsolete!?
match = ; DEBUG: obsolete!?
result = ; DEBUG: obsolete!?
; calculate time left
time -= %A_Now%, Seconds
; find nearest unit
Loop, Parse, timeIntervals, |
{
if((time - A_LoopField) >= 0) {
index := A_Index ; DEBUG: obsolete!?
match := A_LoopField
Break
}
}
; assign unit -- DEBUG: obsolete!?
Loop, Parse, timeUnits, |
{
If(A_Index = index) {
result .= A_LoopField
Break
}
}
; calculate start date
startDate := date
startDate += -match, Seconds
result .= "`n" . startDate . "`n" ; DEBUG: obsolete!?
; return start date
Return result ; DEBUG: only return startDate!?
} | Seems buggy though...  _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5068 Location: imaginationland
|
Posted: Sun Jul 15, 2007 7:12 pm Post subject: |
|
|
| Code: | TimeScale(c) {
static y1, y2, d = "-", f
, s1 = "Millenia", s2 = "Centuries", s3 = "Years", s4 = "Months"
, s5 = "Days", s6 = "Hours", s7 = "Minutes", s8 = "Seconds"
, s9 = "Now", s10 = "Decades", s11 = "Weeks"
If y1 =
{
f = yy%d%MM%d%dd%d%HH%d%mm%d%ss
FormatTime, y, , yyyy
StringLeft, y, y, 2
StringSplit, y, y
}
FormatTime, n, , %f%
n = %y1%%d%%y2%%d%%n%
StringSplit, n, n, %d%
FormatTime, cy, %c%, yyyy
FormatTime, c, %c%, %f%
StringLeft, cy, cy, 2
StringSplit, cy, cy
c = %cy1%%d%%cy2%%d%%c%
Loop, Parse, c, %d%
If (A_LoopField > n%A_Index%) {
If A_Index = 5
{
If (A_LoopField - n%A_Index%) > 7
Return, s11
}
Else If A_Index = 3
{
If (A_LoopField - n%A_Index%) > 10
Return, s10
}
Return, s%A_Index%
}
Return, s9
} |
Hope this helps. _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
Ace_NoOne
Joined: 10 Oct 2005 Posts: 333 Location: Germany
|
Posted: Mon Jul 16, 2007 9:11 am Post subject: |
|
|
I'm afraid your script is buggy, Titan; it returns different values at different times.
Take my (updated) test script: | Code: | results := FormatTime(A_Now) . ": now`n"
time := A_Now
time += 30, Seconds
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 30, Minutes
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 12, Hours
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 1, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 15, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 180, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 1800, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 18000, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
time := A_Now
time += 180000, days
results .= FormatTime(time) . ": " . TimeScale(time) . "`n"
MsgBox %results%
Return
FormatTime(str) {
FormatTime, str, %str%, yyyy-MM-dd hh:mm:ss
Return str
}
; TimeScale() by Titan
TimeScale(c) {
static y1, y2, d = "-", f
, s1 = "Millenia", s2 = "Centuries", s3 = "Years", s4 = "Months"
, s5 = "Days", s6 = "Hours", s7 = "Minutes", s8 = "Seconds"
, s9 = "Now", s10 = "Decades", s11 = "Weeks"
If y1 =
{
f = yy%d%MM%d%dd%d%HH%d%mm%d%ss
FormatTime, y, , yyyy
StringLeft, y, y, 2
StringSplit, y, y
}
FormatTime, n, , %f%
n = %y1%%d%%y2%%d%%n%
StringSplit, n, n, %d%
FormatTime, cy, %c%, yyyy
FormatTime, c, %c%, %f%
StringLeft, cy, cy, 2
StringSplit, cy, cy
c = %cy1%%d%%cy2%%d%%c%
Loop, Parse, c, %d%
If (A_LoopField > n%A_Index%) {
If A_Index = 5
{
If (A_LoopField - n%A_Index%) > 7
Return, s11
}
Else If A_Index = 3
{
If (A_LoopField - n%A_Index%) > 10
Return, s10
}
Return, s%A_Index%
}
Return, s9
} | The first two values returned by your function (i.e. rows 2 and 3) are sometimes Seconds/Minutes, at other times it's Minutes/Minutes, and at around 10:00 o'clock just now I even had Hours/Hours (if I recall correctly, that is).
As you know, I usually have a hard time understanding your code, so I can't quite figure out how to make that function return the actual start date (see above)...
Anyway, I appreciate all your efforts! _________________ Improving my world, one script at a time.
Join the AutoHotkey IRC channel: irc.freenode.net #autohotkey |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5068 Location: imaginationland
|
Posted: Mon Jul 16, 2007 9:56 am Post subject: |
|
|
Yes I know, 60+ seconds adds a minute which could increase the hour interval and so on. I thought the method would be more accurate in terms of months and leap years but unfortunately it has this problem. Building on SeaBiscuit's method:
| Code: | TimeScale(c) {
static i = "31104000000,3110400000,311040000,31104000,2592000,604800,86400,3600,60,1"
, u = "Millenia,Centuries,Decades,Years,Months,Weeks,Days,Hours,Minutes,Seconds,Now"
c -= A_Now, s
StringSplit, u, u, `,
Loop, Parse, i, `,
If c >= %A_LoopField%
Return, u%A_Index%
Return, u11
} |
_________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| 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
|