AutoHotkey Community

It is currently May 25th, 2012, 11:11 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: nearest time-unit
PostPosted: July 12th, 2007, 9:21 am 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 2:34 pm 
Offline

Joined: January 7th, 2007, 6:40 pm
Posts: 109
Location: In fund pe scaun, la o bere prin Romania :D
Do you need a very precise function in calculating months between two dates or a rough one? Cause those days can be real pain in the ass.

_________________
ImageBackgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet


Last edited by Seabiscuit on July 12th, 2007, 2:40 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 2:37 pm 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 2:40 pm 
Offline

Joined: January 7th, 2007, 6:40 pm
Posts: 109
Location: In fund pe scaun, la o bere prin Romania :D
I've corected myself, I was talking about months.

_________________
ImageBackgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 2:41 pm 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 3:28 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8647
Location: Salem, MA
I will think about this as I drive to work - A nested If is not such a bad thing.

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 4:16 pm 
Offline

Joined: January 7th, 2007, 6:40 pm
Posts: 109
Location: In fund pe scaun, la o bere prin Romania :D
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
}

_________________
ImageBackgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 8:20 pm 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 8:52 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
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.

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2007, 9:27 pm 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 13th, 2007, 1:54 am 
Offline

Joined: January 7th, 2007, 6:40 pm
Posts: 109
Location: In fund pe scaun, la o bere prin Romania :D
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
}

:wink:

_________________
ImageBackgammon addicted!
GamesGrid was one of the first online web sites to bring Backgammon to the Internet


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 14th, 2007, 3:12 pm 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 15th, 2007, 7:12 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
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.

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 16th, 2007, 9:11 am 
Offline

Joined: October 10th, 2005, 10:44 am
Posts: 299
Location: Germany
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 16th, 2007, 9:56 am 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
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
}

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: mrhobbeys, snyder and 65 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group