It works!
I have again modified the code to return the actual date I'm looking for:
Code:
; TimeScale() v0.9 -- by Seabiscuit, Titan and FND
TimeScale(date) {
; initialize
time := date
startDate := date
static intervals = "31557600000,3155760000,315576000,31557600,2629800,604800,86400,3600,60,1" ; units = "Millenia,Centuries,Decades,Years,Months,Weeks,Days,Hours,Minutes,Seconds"
; calculate time left
time -= A_Now, Seconds
; find nearest unit
StringSplit, interval, intervals, `,
match := 0
Loop, Parse, intervals, `,
{
If time >= %A_LoopField%
{
match := interval%A_Index%
Break
}
}
; calculate start date
startDate += -match, Seconds
; return start date
Return startDate
}
Here is the test script, in which the function (for debugging purposes) returns both the unit and the desired date:
Code:
results := " now: " . FormatTime(A_Now) . "`n`n"
time := A_Now
time += 30, Seconds
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 30, Minutes
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 12, Hours
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 1, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 15, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 180, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 1800, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 18000, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 180000, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
time := A_Now
time += 1800000, days
results .= " end: " FormatTime(time) . " -- " . TimeScale(time) . "`n"
MsgBox %results%
Return
FormatTime(str) {
FormatTime, str, %str%, yyyy-MM-dd hh:mm:ss
Return str
}
; TimeScale() by Seabiscuit, Titan and FND
TimeScale(date) {
; initialize
time := date
startDate := date
static intervals = "31557600000,3155760000,315576000,31557600,2629800,604800,86400,3600,60,1"
, units = "Millenia,Centuries,Decades,Years,Months,Weeks,Days,Hours,Minutes,Seconds,Now"
; calculate time left
time -= A_Now, Seconds
; find nearest unit
StringSplit, interval, intervals, `,
match := interval11
Loop, Parse, intervals, `,
{
If time >= %A_LoopField%
{
match := interval%A_Index%
Break
}
}
; assign unit - DEBUG: obsolete?
StringSplit, unit, units, `,
unitMatch := unit11
Loop, Parse, intervals, `,
{
If time >= %A_LoopField%
{
unitMatch := unit%A_Index%
Break
}
}
; calculate start date
startDate += -match, Seconds
result .= unitMatch . "`nstart: " . FormatTime(startDate) . "`n" ; DEBUG: obsolete!?
; return start date
Return result ; DEBUG: only return startDate!?
}
This is the output:
Code:
now: 2007-07-18 05:27:22
end: 2007-07-18 05:27:52 -- Seconds
start: 2007-07-18 05:27:51
end: 2007-07-18 05:57:22 -- Minutes
start: 2007-07-18 05:56:22
end: 2007-07-19 05:27:22 -- Hours
start: 2007-07-19 04:27:22
end: 2007-07-19 05:27:22 -- Days
start: 2007-07-18 05:27:22
end: 2007-08-02 05:27:22 -- Weeks
start: 2007-07-26 05:27:22
end: 2008-01-14 05:27:22 -- Months
start: 2007-12-15 05:27:22
end: 2012-06-21 05:27:22 -- Years
start: 2011-06-27 05:27:22
end: 2056-10-28 05:27:22 -- Decades
start: 2046-12-20 05:27:22
end: 2500-05-14 05:27:22 -- Centuries
start: 2401-10-20 05:27:22
end: 6935-10-11 05:27:22 -- Millenia
start: 5950-02-17 05:27:22
As you can see, it's not always entirely correct (e.g. millenia are a few years off) - but I'm not sure why, and I'm not sure whether I should care...
UPDATE:
Duh - Titan just pointed out the reason for this: We rely on the fact that a day is
exactly 86400 seconds and a year is exactly 365 days, which leads to these deviations...
He has also supplied a much-improved set of intervals, using the
Julian scale (code updated accordingly).
Again, thanks very much for you help!!
PS: After the peer review, we should post this in the Scripts & Functions section.
PPS: This function only works for finding the start date when given the end date, not vice versa - that's good enough for me, but maybe not universal enough to justify the name "TimeScale"... !?