Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

calculate time span

352 views
Skip to first unread message

Lisa Pearlson

unread,
Feb 24, 2006, 2:36:05 PM2/24/06
to
Hi,

I have 2 dates, formatted like "yyyy-mm-dd hh:mm:ss".

I wish to know the difference between the two, in seconds, hours, days,
months and years.

I looked at clock function.. I can use [clock scan $dt] on these days and
get platform specific seconds or something. I can subtract these dates from
one another (larger from the smaller), and format this into a date. But this
will give me the time offset from epoch. And as such it doesn't take into
account the actual dates of which I am wanting to know the difference off..
This is important if I want to know the difference in these two dates in
number of months, since not all months are created equal.

There ought to be some type of timespan function:

set td1 {2006-01-01 12:00:00}
set td2 {2006-02-24 20:00:00}

set months [timespan months $t1 $t2]
set seconds [timespan seconds $t1 $t2]

Can something like this be accomplished in TCL?

Lisa


Robert Hicks

unread,
Feb 24, 2006, 3:10:37 PM2/24/06
to
There was a posting about doing a date diff not too far back on clt.
This was posted there:

proc findTimeDiff {inTime inDate outTime outDate} {
set inclock [clock scan $inTime -base [clock scan $inDate]]
set outclock [clock scan $outTime -base [clock scan $outDate]]
return [expr {$outclock-$inclock}]
}

Maybe you can do something with that?

Robert

Lisa Pearlson

unread,
Feb 24, 2006, 5:21:19 PM2/24/06
to
I don't see how.. I don't see how this is different from:

set diff [expr {[clock scan {2006-02-24 12:00:00} - [clock scan {1999-01-01
20:59:59}]}]

But this diff doesn't tell me how many months are between the two dates with
correct consideration of daylight saving time, that some months are 28/29
(leap years), 30 or 31 days.

But then, I don't understand the -base option that might be crucial for
this.. the online doc says

" If the -base flag is specified, the next argument should contain an
integer clock value. Only the date in this value is used, not the time. This
is useful for determining the time on a specific day or doing other
date-relative conversions"

But I don't understand this.. it might be curcial to what I am trying to
accomplish...
The timespan function I suggested in my previous e-mail is exactely what I
need.

Lisa

"Robert Hicks" <sig...@gmail.com> wrote in message
news:1140811837.0...@e56g2000cwe.googlegroups.com...

Lawrence Chitty

unread,
Feb 24, 2006, 5:26:34 PM2/24/06
to
Lisa Pearlson wrote:
> Hi,
>
> I have 2 dates, formatted like "yyyy-mm-dd hh:mm:ss".
>
> I wish to know the difference between the two, in seconds, hours, days,
> months and years.

Take a look at http://wiki.tcl.tk/3189 and see if that helps

Regards

Lawrence

Roy Terry

unread,
Feb 25, 2006, 10:27:48 AM2/25/06
to
"Lisa Pearlson" <n...@spam.plz> wrote in message
news:43ff5fe9$0$8260$e4fe...@dreader30.news.xs4all.nl...

> Hi,
>
> I have 2 dates, formatted like "yyyy-mm-dd hh:mm:ss".
>
> I wish to know the difference between the two, in seconds, hours, days,
> months and years.
>
> I looked at clock function.. I can use [clock scan $dt] on these days and
> get platform specific seconds or something.

Actually it will give you a universal time coordinate.

I can subtract these dates from
> one another (larger from the smaller), and format this into a date. But
this
> will give me the time offset from epoch.

I don't think so. If you subtract the two values you will get nothing
but a pure count of seconds.

And as such it doesn't take into
> account the actual dates of which I am wanting to know the difference
off..

Not correct. It is pure seconds that give you the exact difference.

> This is important if I want to know the difference in these two dates in
> number of months, since not all months are created equal.

How would you define a difference in months? Would
it only include whole months?


>
> There ought to be some type of timespan function:
>
> set td1 {2006-01-01 12:00:00}
> set td2 {2006-02-24 20:00:00}
>
> set months [timespan months $t1 $t2]
> set seconds [timespan seconds $t1 $t2]
>
> Can something like this be accomplished in TCL?

I think so depending on your
defiinition month differences.

>
> Lisa
>
>


Uwe Klein

unread,
Feb 25, 2006, 11:28:53 AM2/25/06
to

get the difference in seconds, see that it is positiv.

i found it usefull to format with
[clock format $diff -fmt "%j Days %T" -gmt 1]

be shure to use "-gmt 1", no timezones in differences.
breaks after a year/365Days.

uwe

Lisa Pearlson

unread,
Feb 26, 2006, 12:53:01 PM2/26/06
to
Getting number of months would be 'whole months', days would be 'whole
days', etc.

That means (assuming you have a function 'timespan' like I'd want):

timespan days {2006-01-01 12:00:00} {2006-02-01 12:00:00}
result: 31

timespan days {2006-02-01 12:00:00} {2006-03-01 12:00:00}
result: 28 (but on a leap year it would be 29)

set t [timespan expr { {2006-02-01 12:00:00} + {28 days} + {5 seconds} }]
clock format $t -format "%Y:%m:%d %H:%M%S"
result: 2006-03-01 12:00:05

set t [timespan expr { {2006-03-01 12:00:00} + {28 days} + {5 seconds} }]
clock format $t -format "%Y:%m:%d %H:%M%S"
result: 2006-03-28 12:00:05

Lisa

"Roy Terry" <royt...@earthlink.net> wrote in message
news:UH_Lf.734$6I....@newsread3.news.pas.earthlink.net...

Lisa Pearlson

unread,
Feb 26, 2006, 1:28:02 PM2/26/06
to
Why does it break after a year?


"Uwe Klein" <uwe_klein_...@t-online.de> wrote in message
news:67d6d3-...@robert.houseofmax.de...

Lisa Pearlson

unread,
Feb 26, 2006, 3:13:28 PM2/26/06
to
Hmm, I guess all I was looking for was this... anything wrong with this
code?

proc timespan {{option} {from} {to {}}} {
if {$to eq {}} {
set t1 [clock scan now]
set t2 [clock scan $from]
} else {
set t1 [clock scan $from]
set t2 [clock scan $to]
}

set diffseconds [expr {$t2 - $t1}]

set retval {}
switch -- $option {
years {
set retval [expr {[clock format $t2 -format {%Y}] -
[clock format %t1 -format {%Y}]}]
}
months {
set years [expr {[clock format $t2 -format {%Y}] -
[clock format %t1 -format {%Y}]}]
set months [expr {[clock format $t2 -format {%m}] - [clock format
%t1 -format {%m}]}]
set retval [expr { ($years * 12) + $months}]
}
days {
set retval [expr {$diffseconds / 86400}]
}
hours {
set retval [expr {$diffseconds / 3600}]
}
minutes {
set retval [expr {$diffseconds / 60}]
}
seconds {
set retval $diffseconds
}
}

return $retval
}


"Lawrence Chitty" <lawrenc...@ntlworld.com> wrote in message
news:uKLLf.70302$0N1....@newsfe5-win.ntli.net...

Lisa Pearlson

unread,
Feb 26, 2006, 3:39:29 PM2/26/06
to
proc timespan {{option} {from} {to {}}} {
if {$to eq {}} {
set t1 [clock scan now]
set t2 [clock scan $from]
} else {
set t1 [clock scan $from]
set t2 [clock scan $to]
}

set diffseconds [expr {$t2 - $t1}]

set retval {}
switch -- $option {
years {

return [expr {[clock format $t2 -format {%Y}] - [clock
format $t1 -format {%Y}]}]


}
months {
set years [expr {[clock format $t2 -format {%Y}] - [clock

format $t1 -format {%Y}]}]


set months [expr {[clock format $t2 -format {%m}] - [clock

format $t1 -format {%m}]}]
return [expr { ($years * 12) + $months}]
}
weeks {
return [expr {$diffseconds / 604800}]
}
days {
return [expr {$diffseconds / 86400}]
}
hours {
return [expr {$diffseconds / 3600}]
}
minutes {
return [expr {$diffseconds / 60}]
}
seconds {
return $diffseconds
}
}

return -code error -errorinfo "unknown option $option" {}
}

"Lisa Pearlson" <n...@spam.plz> wrote in message

news:4401eac5$0$22451$e4fe...@dreader16.news.xs4all.nl...

Uwe Klein

unread,
Feb 27, 2006, 4:13:51 AM2/27/06
to
Lisa Pearlson wrote:
> Why does it break after a year?

format specifier "%j" is day of year.
When you reach the next year ( 366+ Days)
counting starts at 1 again.

an alternate would be

set tdiff 12345678
set sec_in_day [ expr 60 * 60 * 24 ]

set days [ expr $tdiff / $sec_in_day ]
set sec_remain [ expr $tdiff % $sec_in_day ]

if {$days} {
set tdiffstr "$days Days "
}

append tdiffstr [ clock format $sec_remain -fmt "%T" -gmt 1 ]

uwe

Mark Smithfield

unread,
Feb 27, 2006, 2:40:03 PM2/27/06
to
Please excuse me if this question is out of place, but this task
(calculate time span) seems like the basis for an appropriate
subcommand to the clock command. I understand the tip process. Without
suggesting a particular solution, is an additional subcommand for
'clock' the sort of thing that the core team would be amenable to
adding?

It seems like one of those things that would be used a lot once it was
in place.

Mark.

Lisa Pearlson

unread,
Feb 27, 2006, 3:18:29 PM2/27/06
to
This is what I needed, this is what I implemented, .. if I missed something,
please let me know:

proc wholeunits {val} {
return [expr {[format {%.0f} [expr { ($val < 0) ? ceil($val) :
floor($val) }]]}]
}

proc timespan {{option} {from} {to {}}} {
if {$to eq {}} {
set t1 [clock scan now]
set t2 [clock scan $from]
} else {
set t1 [clock scan $from]
set t2 [clock scan $to]
}

set diffseconds [expr {$t2 - $t1}]

set retval {}
switch -- $option {
years {
return [expr {[clock format $t2 -format {%Y}] -
[clock format $t1 -format {%Y}]}]
}
months {
set years [expr {[clock format $t2 -format {%Y}] -
[clock format $t1 -format {%Y}]}]
set months [expr {[clock format $t2 -format {%m}] -
[clock format $t1 -format {%m}]}]
return [expr { ($years * 12) + $months}]
}
weeks {

return [wholeunits [expr {$diffseconds / 604800.0}]]
}
days {
return [wholeunits [expr {$diffseconds / 86400.0}]]
}
hours {
return [wholeunits [expr {$diffseconds / 3600.0}]]
}
minutes {
return [wholeunits [expr {$diffseconds / 60.0}]]
}
seconds {
return $diffseconds
}
}

return -code error -errorinfo "unknown option $option" {}
}

Lisa

"Lisa Pearlson" <n...@spam.plz> wrote in message
news:4401eac5$0$22451$e4fe...@dreader16.news.xs4all.nl...

Lisa Pearlson

unread,
Feb 27, 2006, 3:20:23 PM2/27/06
to
Uhmm, retval is an unused variable.. I forgot to remove it.
Are there any improvements to be made?

Who is the core maintainer of the clock command?

Lisa

"Lisa Pearlson" <n...@spam.plz> wrote in message

news:44035e58$0$8238$e4fe...@dreader30.news.xs4all.nl...

Donal K. Fellows

unread,
Feb 27, 2006, 3:40:04 PM2/27/06
to
Lisa Pearlson wrote:
> Who is the core maintainer of the clock command?

Kevin Kenny is the time-lord.

Donal.

Glenn Jackman

unread,
Feb 27, 2006, 4:47:43 PM2/27/06
to
At 2006-02-27 03:18PM, Lisa Pearlson <n...@spam.plz> wrote:
> proc wholeunits {val} {
> return [expr {[format {%.0f} [expr { ($val < 0) ? ceil($val) :
> floor($val) }]]}]
> }

You don't need nested [expr] statements:

proc wholeunits {val} {
return [expr {int( ($val < 0) ? ceil($val) : floor($val) )}]
}

--
Glenn Jackman
Ulterior Designer

Adrian Ho

unread,
Feb 28, 2006, 6:24:30 AM2/28/06
to

And quite a dashing time-lord at that, if his Frappr photo's anything to
go by. 8-)

QOTW? (Donal's, of course.)

- Adrian

Larry Smith

unread,
Feb 28, 2006, 3:03:01 PM2/28/06
to Donal K. Fellows

Really? I'd like to see his Tardis sometime.

--
.-. .-. .---. .---. .-..-.|Experts in Linux: www.WildOpenSource.com
| |__ / | \| |-< | |-< > / |"Making the bazaar more commonplace"
`----'`-^-'`-'`-'`-'`-' `-' |Check out my new novel: "Cloud Realm" at:
home:www.smith-house.org:8000|<-this url + /books/list.html

Lisa Pearlson

unread,
Feb 28, 2006, 7:09:07 PM2/28/06
to
Thanks,

Otherwise, anything wrong with my code?
Isn't it useful enough to be included in the clock command or seperate
package?

Lisa
P.S. How many years can be expressed in the internal datatype used to keep
track of the number of seconds?


"Glenn Jackman" <xx...@freenet.carleton.ca> wrote in message
news:slrne06ss0...@smeagol.ncf.ca...

Lisa Pearlson

unread,
Feb 28, 2006, 7:21:43 PM2/28/06
to
Another thing, in my timespan proc, I divide the number of seconds by the
number of seconds for that unit, with a decimal value.

For example, for the number of days:

set seconds [clock seconds]
set weeks [expr { $seconds / 604800.0 }]

I don't divide by intiger 604800 but by floating point 604800.0 so that the
result will be floating point value.
If I don't do this, 1.9 days would be automatically rounded to integer value
2, while my wholeunits will floor it for positive values and ceil it for
negative ones to gets whole numbers.

Is this okay? how large can floating point values be? How many digits before
the decimal and how many after?

Lisa


Arjen Markus

unread,
Mar 1, 2006, 7:01:30 AM3/1/06
to
Floating point numbers (the double precision kind used by Tcl) have
about 12
significant digits and the range is anywhere from 10^-200 to 10^+200
(slightly
bigger than that but I am too lazy to look up the exact values ;)).

Being floating-point numbers, the digits may appear before or after the
decimal
separator.

Maybe this page on the Wiki gives you some more information ...
http://wiki.tcl.tk/11969.

Regards,

Arjen

Sean Woods

unread,
Mar 1, 2006, 8:04:53 AM3/1/06
to

I'm a bit late to the party, but my favorite way to handle this is
actually to convert the dates
to Julian dates. Julian dates start at 0AD, and simply increment days
since then.

A package to convert from the Gregorian (i.e. standard) calendar and
the Julian calendar is
at: http://wiki.tcl.tk/2823

That will take care of days. Hours, Minutes, and Seconds are all
relative.

Donal K. Fellows

unread,
Mar 1, 2006, 8:30:25 AM3/1/06
to
Sean Woods wrote:
> I'm a bit late to the party, but my favorite way to handle this is
> actually to convert the dates to Julian dates. Julian dates start at
> 0AD, and simply increment days since then.
>
> A package to convert from the Gregorian (i.e. standard) calendar and
> the Julian calendar is at: http://wiki.tcl.tk/2823

FWIW, 8.5's [clock] uses Julian days when doing date arithmetic and
conversion.

Donal.

Kevin Kenny

unread,
Mar 4, 2006, 2:44:02 PM3/4/06
to
> Donal K. Fellows wrote:
>> Kevin Kenny is the time-lord.

Larry Smith wrote:
> Really? I'd like to see his Tardis sometime.

Ohh, I wish! I'd finally have somewhere to put all the books. ;)

--
73 de ke9tv/2, Kevin

Kevin Kenny

unread,
Mar 4, 2006, 2:51:02 PM3/4/06
to
Lisa Pearlson wrote:
> Hi,
>
> I have 2 dates, formatted like "yyyy-mm-dd hh:mm:ss".
>
> I wish to know the difference between the two, in seconds, hours, days,
> months and years.

The problem is actually quite badly defined, because of all the
anomalies in the clock and calendar. I suspect that minor modifications
to the code at http://wiki.tcl.tk/3189 will be adequate to your
needs. It is guaranteed to return a set of data that when used
-- in sequence! -- to adjust time A, will yield time B. The data
are sometimes surprising in the sense that they exploit anomalies
where a human would use something that appears more straightforward
to a human.

I haven't been able to come up with any set of rules that makes
enough sense that I wouldn't be deluged with bug reports if I added
it to the core, so I'm keeping it as a "little bit extra on the
side" for the moment. It's a much harder problem than it appears.

Sean Woods

unread,
Mar 5, 2006, 7:46:40 AM3/5/06
to
>FWIW, 8.5's [clock] uses Julian days when doing date arithmetic and
>conversion.

Sweet!

0 new messages