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

Date question ?

16 views
Skip to first unread message

Mel

unread,
Jun 16, 2008, 3:24:37 PM6/16/08
to
how can I get all the days between give two dates ?

say 05/28/2008 and 06/02/2008

I need a function to return dates (days) that fall between those two
dates. as a list
{05/28/2008 05/29/2008 05/30/2008 05/31/2008 06/1/2008 06/2/2008}

thanks in advance

Alexandre Ferrieux

unread,
Jun 16, 2008, 3:56:55 PM6/16/08
to

Convert both dates to seconds-since-epoch with [clock scan], then do a
[for] loop with step 86400 (number of seconds in a day). In the loop,
convert back the value to the form you like with [clock format].
Since you'll be jumping from midnight to midnight you're even safe
from daylight saving time effects (since those typically occur at
2AM).

-Alex

Alexandre Ferrieux

unread,
Jun 16, 2008, 4:05:49 PM6/16/08
to
On Jun 16, 9:56 pm, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
wrote:

>
> Since you'll be jumping from midnight to midnight you're even safe
> from daylight saving time effects (since those typically occur at
> 2AM).

Oops sorry, wrong. Jumping by 24 hours when you're at midnight sharp
and the day is 25 leaves you at 23:00 on the same date.
To be on the safe side start at noon on the first day, by appending "
12:00:00" to it before calling [clock scan]:

set start [clock scan "$d1 12:00:00"]
set end [clock scan "$d2 13:00:00"] ;# just in case a DST occurred
in between
set l {}
for {set d $d1} {$d<=$d2} {incr d 86400} {
lappend l [clock format $d -format %m/%d/%Y]
}

-Alex

Gerald W. Lester

unread,
Jun 16, 2008, 4:21:58 PM6/16/08
to


Wrong answer due to leap seconds and daylight savings.

Use a while loop, but use [clock add $lastTime 1 day]. Then to the rest as
he says.


--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Alexandre Ferrieux

unread,
Jun 16, 2008, 4:42:12 PM6/16/08
to
On Jun 16, 10:21 pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
> Alexandre Ferrieux wrote:
> > On Jun 16, 9:24 pm, Mel <MelHer...@gmail.com> wrote:
> >> how can I get all the days between give two dates ?
>
> >> say 05/28/2008 and 06/02/2008
>
> >> I need a function to return dates (days) that fall between those two
> >> dates. as a list
> >> {05/28/2008 05/29/2008 05/30/2008 05/31/2008 06/1/2008 06/2/2008}
>
> > Convert both dates to seconds-since-epoch with [clock scan], then do a
> > [for] loop with step 86400 (number of seconds in a day). In the loop,
> > convert back the value to the form you like with [clock format].
> > Since you'll be jumping from midnight to midnight you're even safe
> > from daylight saving time effects (since those typically occur at
> > 2AM).
>
> Wrong answer due to leap seconds and daylight savings.

Yup, see my other post ;-)

> Use a while loop, but use [clock add $lastTime 1 day].

Cleaner, though slower I think than the 86400 since here we don't care
about being at noon, 11:00 or 13:00...
(but I can imagine speed is not really an issue for that sort of loop
-- you win)

-Alex

Neil Madden

unread,
Jun 16, 2008, 4:47:07 PM6/16/08
to

Using Tcl 8.5 you can do:

proc dates {start end} {
set s [clock scan $start -format "%m/%d/%Y"]
set e [clock scan $end -format "%m/%d/%Y"]
set ret [list]
for {} {$s <= $e} {set s [clock add $s 1 day]} {
lappend ret [clock format $s -format "%m/%d/%Y"]
}
return $ret
}

% dates 05/28/2008 06/02/2008
05/28/2008 05/29/2008 05/30/2008 05/31/2008 06/01/2008 06/02/2008

-- Neil

mark anthony

unread,
Jun 17, 2008, 3:54:04 AM6/17/08
to


If you go with the -gmt flag you would not need to worry about
daylight
saving time effects and could use the 24 hours in seconds aproach.

Yet I would use a clock reduced version since the only month that
changes
the #days is february...

cheers,
mark

Andreas Leitgeb

unread,
Jun 17, 2008, 6:09:33 AM6/17/08
to
mark anthony <koya...@gmail.com> wrote:
>> proc dates {start end} {
>> set s [clock scan $start -format "%m/%d/%Y"]
>> set e [clock scan $end -format "%m/%d/%Y"]
>> set ret [list]
>> for {} {$s <= $e} {set s [clock add $s 1 day]} {
>> lappend ret [clock format $s -format "%m/%d/%Y"]
>> }
>> return $ret
>> }

with older tcl's you can get this, too:
set s [clock scan $start] ;# parses 05/28/2008 correctly
and for the loop-increment:
set s [clock scan "1 day" -base $s]

Tested with 8.3.3

> If you go with the -gmt flag you would not need to worry about
> daylight saving time effects and could use the 24 hours in seconds
> aproach.

I would *generally* discourage that approach!

Maybe in this specific situation you may even get away with it,
because there is no dependency on "current" time or date.

Beyond the scope of this thread:
Calculating days by adding 86400 seconds puts you
right into DST-hell, at the point where you
[clock format] the (so far gmt) seconds.

Just recently, I had to change a script from subtracting 86400 seconds
to "clock scan "-1 days" -base $s", because after stepping over the
DST-border, I was suddenly one hour off, and depending on starting
timeofday, this hour off might even have set the day off by one.


Jonathan Bromley

unread,
Jun 17, 2008, 6:25:43 AM6/17/08
to
On 17 Jun 2008 10:09:33 GMT, Andreas Leitgeb
<a...@gamma.logic.tuwien.ac.at> wrote:


>> If you go with the -gmt flag you would not need to worry about
>> daylight saving time effects and could use the 24 hours in seconds
>> aproach.
>
>I would *generally* discourage that approach!
>

>Calculating days by adding 86400 seconds puts you
>right into DST-hell, at the point where you
>[clock format] the (so far gmt) seconds.
>
>Just recently, I had to change a script from subtracting 86400 seconds
>to "clock scan "-1 days" -base $s", because after stepping over the
>DST-border, I was suddenly one hour off, and depending on starting
>timeofday, this hour off might even have set the day off by one.

This is certainly true. I believe it's even worse because some
countries have (had?) double daylight-saving.

However... Can't you finesse that by starting at noon rather than
midnight? Then no matter how many times you add 86400 seconds,
you're sure to be on the right date.

Starting from midnight sounds suspiciously like those badly
designed mouse-wheel devices that have the mechanical detents
lined up with the transitions of the encoder, rather than
halfway between transitions as they should be...
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan...@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Alexandre Ferrieux

unread,
Jun 17, 2008, 7:40:12 AM6/17/08
to
On Jun 17, 12:25 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:

>
> However... Can't you finesse that by starting at noon rather than
> midnight?  Then no matter how many times you add 86400 seconds,
> you're sure to be on the right date.

Yup, that's my proposal 6 messages up this thread :-)
(I'm not proud of it -- it's just that I like simple things)

-Alex

Glenn Jackman

unread,
Jun 17, 2008, 7:54:43 AM6/17/08
to

Really, if you want simplicity do the calculation in days not seconds.
Then you don't have to even consider that hoop let alone jump through it.

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous

Andreas Leitgeb

unread,
Jun 17, 2008, 7:56:08 AM6/17/08
to
Jonathan Bromley <jonathan...@MYCOMPANY.com> wrote:
> However... Can't you finesse that by starting at noon rather than
> midnight? Then no matter how many times you add 86400 seconds,
> you're sure to be on the right date.

If current time is a non-issue, then starting at noon is
one of those workarounds, that actually appear to work.

It's really unlikely, that a timezone would have a "tide"
of 12 hours or more :-)

Nevertheless, I find the clock scan (or new: clock add)
command to be much clearer than [incr secs 86400], anyway,
and I once had to trackdown a problem (but in C), where
by a typo I added 84600 seconds, and the calculated dates
were just plain wrong. It was even worse, because
the calculated future day wasn't itself made visible, but
only used to check if some user-date was within valid range.
(at most <n> days in future)

Jonathan Bromley

unread,
Jun 17, 2008, 8:00:44 AM6/17/08
to
On Tue, 17 Jun 2008 04:40:12 -0700 (PDT), Alexandre Ferrieux wrote:

[re: date arithmetic starting at noon]

>Yup, that's my proposal 6 messages up this thread :-)

Apologies - must remember to RTFT in future...

>(I'm not proud of it -- it's just that I like simple things)

Like all simple things it's OK in the hands of those who
understand its limitations...

Alexandre Ferrieux

unread,
Jun 17, 2008, 8:15:50 AM6/17/08
to
On Jun 17, 1:54 pm, Glenn Jackman <gle...@ncf.ca> wrote:
>
> Really, if you want simplicity do the calculation in days not seconds.

And what kind of magic would you use to compute in days without [clock
add] ? Do you mean taking for granted the 11-element table of days per
month, plus the Feb29 algorithm ? Yeah, if that one in under the hood,
everything looks simple...

-Alex

Kaitzschu

unread,
Jun 17, 2008, 8:15:44 AM6/17/08
to
On Tue, 17 Jun 2008, Glenn Jackman wrote:

> Really, if you want simplicity do the calculation in days not seconds.
> Then you don't have to even consider that hoop let alone jump through
> it.

And one far from simplest solution for that is to use Julian calendar
(which, I think, is not really affected by DST or stuff like that, but
feel free to correct me on this issue).

[code]

set d1 {05/28/2008}
set d2 {06/02/2008}

set s1 [clock scan $d1]
set s2 [clock scan $d2]

set j1 [clock format $s1 -format %J]
set j2 [clock format $s2 -format %J]

set list [list]
for {} {$j1 <= $j2} {incr j1} {
lappend list [clock format [clock scan $j1 -format %J]]
}
puts $list

[/code]

Setting -format for [clock scan]s is up to own personal belief system.

--
-Kaitzschu
set s TCL\ ;wh 1 {pu [set s [st ra $s 1 3][st in $s 0]]\033\[1A;af 99}

"Good thing programmers don't build bridges
[the same way as Kaitzschu writes code]."
--John Kelly in comp.lang.tcl

Andreas Leitgeb

unread,
Jun 17, 2008, 8:57:25 AM6/17/08
to

I don't know if your dislike of "add" is based on it's "new"ness,
or if you generally dislike using clock for calendar arithmetics,
but if it's the former, then [clock scan "$n days" -base $basesecs]
is mostly the same as [clock add $basesecs $n days]

sp...@controlq.com

unread,
Jun 17, 2008, 10:23:41 AM6/17/08
to

On Tue, 17 Jun 2008, Alexandre Ferrieux wrote:

> Date: Tue, 17 Jun 2008 05:15:50 -0700 (PDT)
> From: Alexandre Ferrieux <alexandre...@gmail.com>
> Newsgroups: comp.lang.tcl
> Subject: Re: Date question ?

Um, I wrote a true Julian date/time extension some time ago, and released
to the community with a resounding flop (noone was interested in viewing
dates and times as seperate entities, with dates in Days and time in
seconds) ... but it is still available in source form and with an open
license ... man pages included ...

I believe that the tar file includes a binary for FreeBSD and Windows, but
Linux and other platforms should not be difficult to compile/link ...

http://www.controlq.com/OpenSource/Tcl_Julian.tgz

HTH ...
Rob Sciuk
---- Posted via Pronews.com - Premium Corporate Usenet News Provider ----
http://www.pronews.com offers corporate packages that have access to 100,000+ newsgroups

Darren New

unread,
Jun 17, 2008, 11:52:38 AM6/17/08
to
Jonathan Bromley wrote:
> However... Can't you finesse that by starting at noon rather than
> midnight?

The way I've done it when I just wanted something quick and dirty was to
start at the start date, add 8 hours, check to see if the date changed,
add 8 hours, check to see if the date changed, etc. Count how many
times the date changes before it turns into the date you're looking for.

Kludgey, but easy to prove you're getting it right. Unless it's in an
inner loop somewhere, it might be easier to do it this way and move on
to a more challenging problem.

--
Darren New / San Diego, CA, USA (PST)
Helpful housekeeping hints:
Check your feather pillows for holes
before putting them in the washing machine.

sp...@controlq.com

unread,
Jun 18, 2008, 10:54:18 AM6/18/08
to

<J_Date>(n) <J_Date>(n)

NAME
<J_Date> - Create a new J Date object to manipulate true Julian Dates.

SYNOPSIS
load [Julian.so|Julian.dll]
set dt [J_Date create my dt]
J_Date destroy $dt

DESCRIPTION
J_Date creates or destroys a new Tcl command which implements a true
Julian date. Julian dates extend from October 15, 1583 - whenever.
Julian dates are expressed as the number of days since the epoch (Oct
15, 1583). It is simple to perform date arithmetic, convert them to and
from timestamps, and format them for human consumption.

DATE OPERATIONS
$dt set [YYYYMMDD|YYYY-MM-DD|today|tomorrow|yesterday|last
[year|month|day]|next [year|month|day]]
Sets the date value to either a specified date, or a date
exactly one day, month, or year into either the past or future.

$dt +set N
Sets the current date N days into the future.

$dt -set N
Sets the current date N days into the past.

$dt is J
Sets the current date to the specified true Julian date <J>.

$dt Returns the current Julian date as a number.

$dt year
Returns the year component of the date.

$dt month
Returns the month component of the date.

$dt day
Returns the day component of the date.

$dt dow
Returns the day of the week as a number.

$dt daystr
Returns the day of the week as a string
(eg: Monday, Tuesday ...).

$dt monstr
Returns the month of the year as a string
(eg January, February ...).

$dt format
Returns the date as a string in the form YYYY-MM-DD.

$dt stamp [$tm]
Returns a datestamp (see clock(n) seconds) made from the current
value of the date ($dt), and optionally includes a Julian time
$tm (see J Time(n)).
-

$dt extract [$ts]
Extracts the Julian date component from a timestamp (clock(n)
seconds). This will simply return the julian date as a simple
numeric return value, and this value must be converted to a
Julian date by creating and assigning it using the $dt is J syn-
tax.

SEE ALSO
J_Time

BUGS
There may be some.

ORIGIN
Rob Sciuk, Control-Q Research (http://www.controlq.com)

<J Date>(n)

0 new messages