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

FAQ 4.17 How do I find yesterday's date?

2 views
Skip to first unread message

PerlFAQ Server

unread,
May 4, 2008, 9:03:03 AM5/4/08
to
This is an excerpt from the latest version perlfaq4.pod, which
comes with the standard Perl distribution. These postings aim to
reduce the number of repeated questions as well as allow the community
to review and update the answers. The latest version of the complete
perlfaq is at http://faq.perl.org .

--------------------------------------------------------------------

4.17: How do I find yesterday's date?

(contributed by brian d foy)

Use one of the Date modules. The "DateTime" module makes it simple, and
give you the same time of day, only the day before.

use DateTime;

my $yesterday = DateTime->now->subtract( days => 1 );

print "Yesterday was $yesterday\n";

You can also use the "Date::Calc" module using its "Today_and_Now"
function.

use Date::Calc qw( Today_and_Now Add_Delta_DHMS );

my @date_time = Add_Delta_DHMS( Today_and_Now(), -1, 0, 0, 0 );

print "@date_time\n";

Most people try to use the time rather than the calendar to figure out
dates, but that assumes that days are twenty-four hours each. For most
people, there are two days a year when they aren't: the switch to and
from summer time throws this off. Let the modules do the work.

--------------------------------------------------------------------

The perlfaq-workers, a group of volunteers, maintain the perlfaq. They
are not necessarily experts in every domain where Perl might show up,
so please include as much information as possible and relevant in any
corrections. The perlfaq-workers also don't have access to every
operating system or platform, so please include relevant details for
corrections to examples that do not work on particular platforms.
Working code is greatly appreciated.

If you'd like to help maintain the perlfaq, see the details in
perlfaq.pod.

szr

unread,
May 4, 2008, 12:15:52 PM5/4/08
to

So according to the last part, that makes
time - 86400
unreliable?

E.G.,
$ perl -e 'print scalar localtime(time - 86400), "\n";'

Or is it safe to use that?

--
szr


Peter J. Holzer

unread,
May 4, 2008, 2:24:29 PM5/4/08
to
On 2008-05-04 16:15, szr <sz...@szromanMO.comVE> wrote:

> PerlFAQ Server wrote:
>> 4.17: How do I find yesterday's date?
[...]

>> Most people try to use the time rather than the calendar to figure
>> out dates, but that assumes that days are twenty-four hours each.
>> For most people, there are two days a year when they aren't: the
>> switch to and from summer time throws this off. Let the modules do
>> the work.
>
> So according to the last part, that makes
> time - 86400
> unreliable?

Yes.

> E.G.,
> $ perl -e 'print scalar localtime(time - 86400), "\n";'

Consider:

% perl -le 'print scalar localtime(1206914460)'
Mon Mar 31 00:01:00 2008
% perl -le 'print scalar localtime(1206914460-86400)'
Sat Mar 29 23:01:00 2008

% perl -le 'print scalar localtime(1225061940)'
Sun Oct 26 23:59:00 2008
% perl -le 'print scalar localtime(1225061940-86400)'
Sun Oct 26 00:59:00 2008


> Or is it safe to use that?

Only after 01:00 and before 23:00.

hp

brian d foy

unread,
May 4, 2008, 4:39:16 PM5/4/08
to
In article <fvknf...@news4.newsguy.com>, szr <sz...@szromanMO.comVE>
wrote:


> > Most people try to use the time rather than the calendar to figure
> > out dates, but that assumes that days are twenty-four hours each.
> > For most people, there are two days a year when they aren't: the
> > switch to and from summer time throws this off. Let the modules do
> > the work.
>
> So according to the last part, that makes
> time - 86400
> unreliable?
>
> E.G.,
> $ perl -e 'print scalar localtime(time - 86400), "\n";'
>
> Or is it safe to use that?

Well, that last paragraph explains why that won't work. There are two
days where it breaks. On one you'll get the date from two days ago, and
the other the same day. So, no, it's not safe.

Andrew DeFaria

unread,
May 4, 2008, 8:28:51 PM5/4/08
to
Actually no, you won't get a day 2 days ago or the same date unless you're within a certain time of day. For example, if you are trying to find out what day was before the DST changing day at say 5 Pm you'll come up with the previous day @ 4 Pm, wouldn't you?

Besides - 86400 is reliable here! Here in Arizona that is! Wish you guys would wise up and stop changing your clocks all the time. It's damn annoying! ;-)
--
Andrew DeFaria
Please, God, deliver us from your followers!

David Combs

unread,
May 28, 2008, 8:54:59 PM5/28/08
to
In article <481e54c4$0$33218$815e...@news.qwest.net>,
Andrew DeFaria <And...@DeFaria.com> wrote:
>-=-=-=-=-=-
>Andrew DeFaria <http://defaria.com>

>Please, God, deliver us from your followers!
>
>-=-=-=-=-=-
>[Alternative: text/html]
>-=-=-=-=-=-


I'm still not sure, from what you guys have discovered,
what the faq *should* say?

Eg suggested explanations for a boss who complains
about how it works on those two days or not within a certain
part of the day?

I wonder how the finance and legal worlds handle this
stuff, eg in a contract?

David

Peter J. Holzer

unread,
May 30, 2008, 1:54:41 PM5/30/08
to
On 2008-05-29 00:54, David Combs <dkc...@panix.com> wrote:
> In article <481e54c4$0$33218$815e...@news.qwest.net>,
> Andrew DeFaria <And...@DeFaria.com> wrote:
>>>>> Most people try to use the time rather than the calendar to figure
>>>>> out dates, but that assumes that days are twenty-four hours each.
>>>>> For most people, there are two days a year when they aren't: the
>>>>> switch to and from summer time throws this off. Let the modules do
>>>>> the work.
[...]

>>Besides - 86400 is reliable here! Here in Arizona that is! Wish you guys
>>would wise up and stop changing your clocks all the time. It's damn
>>annoying! ;-)
>
>
> I'm still not sure, from what you guys have discovered,
> what the faq *should* say?

The FAQ should say what it actually says (well, it could also mention
localtime/mktime - I'm not sure if the two modules it mentions are part
of the core).


> Eg suggested explanations for a boss who complains
> about how it works on those two days or not within a certain
> part of the day?

It works correctly if you follow the advice in the FAQ. If you do what
the FAQ says you shouldn't do, it may work in Arizona (Andrew is lucky
not having to put up with that DST insanity) but not in many other
parts of the world.


> I wonder how the finance and legal worlds handle this
> stuff, eg in a contract?

Mostly by ignoring it, I guess. The time shift occurs in the wee hours
of sunday morning. The finance and legal worlds don't do much at that
time.

hp

Gunnar Hjalmarsson

unread,
May 30, 2008, 2:39:03 PM5/30/08
to
Peter J. Holzer wrote:
> On 2008-05-29 00:54, David Combs <dkc...@panix.com> wrote:
>> I'm still not sure, from what you guys have discovered,
>> what the faq *should* say?
>
> The FAQ should say what it actually says (well, it could also mention
> localtime/mktime - I'm not sure if the two modules it mentions are part
> of the core).

They are not part of the core.

The core module Time::Local + localtime() are sufficient to answer the
FAQ question safely.

use Time::Local;
my $today = timelocal 0, 0, 12, ( localtime )[3..5];
my ($d, $m, $y) = ( localtime $today-86400 )[3..5];
printf "Yesterday: %d-%02d-%02d\n", $y+1900, $m+1, $d;

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

nolo contendere

unread,
May 30, 2008, 2:45:37 PM5/30/08
to
On May 30, 2:39 pm, Gunnar Hjalmarsson <nore...@gunnar.cc> wrote:
> Peter J. Holzer wrote:
> > On 2008-05-29 00:54, David Combs <dkco...@panix.com> wrote:
> >> I'm still not sure, from what you guys have discovered,
> >> what the faq *should* say?  
>
> > The FAQ should say what it actually says (well, it could also mention
> > localtime/mktime - I'm not sure if the two modules it mentions are part
> > of the core).
>
> They are not part of the core.
>
> The core module Time::Local + localtime() are sufficient to answer the
> FAQ question safely.
>
>      use Time::Local;
>      my $today = timelocal 0, 0, 12, ( localtime )[3..5];
>      my ($d, $m, $y) = ( localtime $today-86400 )[3..5];
>      printf "Yesterday: %d-%02d-%02d\n", $y+1900, $m+1, $d;
>

Doesn't Peter's post contradict this, since his example demonstrated
that the -86400 can lead to a result that is 2 days older?

Gunnar Hjalmarsson

unread,
May 30, 2008, 2:51:53 PM5/30/08
to

No. Can't you spot a difference between the above code and

print scalar localtime(time-86400);

??

nolo contendere

unread,
May 30, 2008, 6:10:38 PM5/30/08
to

oh, that was your whole point. sorry :-).

Peter J. Holzer

unread,
May 31, 2008, 5:28:36 AM5/31/08
to


or - as I wrote - localtime and mktime (in POSIX). mktime lets you do
arithmetic on the day field, so you can directly write "the day before"
instead of "the day that was 86400 seconds before noon of the current
day" as you did above.


#!/usr/bin/perl
use warnings;
use strict;
use POSIX qw(mktime strftime);

before_and_after(time);
before_and_after(1206914460);
before_and_after(1225061940);

sub before_and_after {
my ($now) = @_;
print strftime("%Y-%m-%d %H:%M:%S%z\n", localtime($now));

my @today = localtime($now);

my @yesterday = @today; $yesterday[3]--; $yesterday[8] = -1;
my $yesterday = mktime(@yesterday);

print strftime("%Y-%m-%d %H:%M:%S%z\n", localtime($yesterday));

my @tomorrow = @today; $tomorrow[3]++; $tomorrow[8] = -1;
my $tomorrow = mktime(@tomorrow);

print strftime("%Y-%m-%d %H:%M:%S%z\n", localtime($tomorrow));
print "\n";
}
__END__


2008-05-31 11:24:30+0200
2008-05-30 11:24:30+0200
2008-06-01 11:24:30+0200

2008-03-31 00:01:00+0200
2008-03-30 00:01:00+0100
2008-04-01 00:01:00+0200

2008-10-26 23:59:00+0100
2008-10-25 23:59:00+0200
2008-10-27 23:59:00+0100


brian d foy

unread,
Jun 1, 2008, 5:24:43 AM6/1/08
to
In article <6ab01bF...@mid.individual.net>, Gunnar Hjalmarsson
<nor...@gunnar.cc> wrote:

> The core module Time::Local + localtime() are sufficient to answer the
> FAQ question safely.
>
> use Time::Local;
> my $today = timelocal 0, 0, 12, ( localtime )[3..5];
> my ($d, $m, $y) = ( localtime $today-86400 )[3..5];
> printf "Yesterday: %d-%02d-%02d\n", $y+1900, $m+1, $d;

Added to the FAQ. Thanks,

0 new messages