Website hosting service by Active-Venture.com
  

 Back to Index

Data: Dates

How do I find the week-of-the-year/day-of-the-year?

The day of the year is in the array returned by localtime() (see perlfunc/"localtime"):

 
    $day_of_year = (localtime(time()))[7];  

How do I find the current century or millennium?

Use the following simple functions:

 
    sub get_century    { 
	return int((((localtime(shift || time))[5] + 1999))/100);
    } 
    sub get_millennium { 
	return 1+int((((localtime(shift || time))[5] + 1899))/1000);
    }   

On some systems, you'll find that the POSIX module's strftime() function has been extended in a non-standard way to use a %C format, which they sometimes claim is the "century". It isn't, because on most such systems, this is only the first two digits of the four-digit year, and thus cannot be used to reliably determine the current century or millennium.

How can I compare two dates and find the difference?

If you're storing your dates as epoch seconds then simply subtract one from the other. If you've got a structured date (distinct year, day, month, hour, minute, seconds values), then for reasons of accessibility, simplicity, and efficiency, merely use either timelocal or timegm (from the Time::Local module in the standard distribution) to reduce structured dates to epoch seconds. However, if you don't know the precise format of your dates, then you should probably use either of the Date::Manip and Date::Calc modules from CPAN before you go hacking up your own parsing routine to handle arbitrary date formats.

How can I take a string and turn it into epoch seconds?

If it's a regular enough string that it always has the same format, you can split it up and pass the parts to timelocal in the standard Time::Local module. Otherwise, you should look into the Date::Calc and Date::Manip modules from CPAN.

How can I find the Julian Day?

Use the Time::JulianDay module (part of the Time-modules bundle available from CPAN.)

Before you immerse yourself too deeply in this, be sure to verify that it is the Julian Day you really want. Are you interested in a way of getting serial days so that you just can tell how many days they are apart or so that you can do also other date arithmetic? If you are interested in performing date arithmetic, this can be done using modules Date::Manip or Date::Calc.

There is too many details and much confusion on this issue to cover in this FAQ, but the term is applied (correctly) to a calendar now supplanted by the Gregorian Calendar, with the Julian Calendar failing to adjust properly for leap years on centennial years (among other annoyances). The term is also used (incorrectly) to mean: [1] days in the Gregorian Calendar; and [2] days since a particular starting time or `epoch', usually 1970 in the Unix world and 1980 in the MS-DOS/Windows world. If you find that it is not the first meaning that you really want, then check out the Date::Manip and Date::Calc modules. (Thanks to David Cassell for most of this text.)

How do I find yesterday's date?

The time() function returns the current time in seconds since the epoch. Take twenty-four hours off that:

 
    $yesterday = time() - ( 24 * 60 * 60 );  

Then you can pass this to localtime() and get the individual year, month, day, hour, minute, seconds values.

Note very carefully that the code above assumes that your 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. A solution to this issue is offered by Russ Allbery.

 
    sub yesterday {
	my $now  = defined $_[0] ? $_[0] : time;
	my $then = $now - 60 * 60 * 24;
	my $ndst = (localtime $now)[8] > 0;
	my $tdst = (localtime $then)[8] > 0;
	$then - ($tdst - $ndst) * 60 * 60;
    }
    # Should give you "this time yesterday" in seconds since epoch relative to
    # the first argument or the current time if no argument is given and
    # suitable for passing to localtime or whatever else you need to do with
    # it.  $ndst is whether we're currently in daylight savings time; $tdst is
    # whether the point 24 hours ago was in daylight savings time.  If $tdst
    # and $ndst are the same, a boundary wasn't crossed, and the correction
    # will subtract 0.  If $tdst is 1 and $ndst is 0, subtract an hour more
    # from yesterday's time since we gained an extra hour while going off
    # daylight savings time.  If $tdst is 0 and $ndst is 1, subtract a
    # negative hour (add an hour) to yesterday's time since we lost an hour.
    #
    # All of this is because during those days when one switches off or onto
    # DST, a "day" isn't 24 hours long; it's either 23 or 25.
    #
    # The explicit settings of $ndst and $tdst are necessary because localtime
    # only says it returns the system tm struct, and the system tm struct at
    # least on Solaris doesn't guarantee any particular positive value (like,
    # say, 1) for isdst, just a positive value.  And that value can
    # potentially be negative, if DST information isn't available (this sub
    # just treats those cases like no DST).
    #
    # Note that between 2am and 3am on the day after the time zone switches
    # off daylight savings time, the exact hour of "yesterday" corresponding
    # to the current hour is not clearly defined.  Note also that if used
    # between 2am and 3am the day after the change to daylight savings time,
    # the result will be between 3am and 4am of the previous day; it's
    # arguable whether this is correct.
    #
    # This sub does not attempt to deal with leap seconds (most things don't).
    #
    # Copyright relinquished 1999 by Russ Allbery <rra@stanford.edu>
    # This code is in the public domain  

Does Perl have a Year 2000 problem? Is Perl Y2K compliant?

Short answer: No, Perl does not have a Year 2000 problem. Yes, Perl is Y2K compliant (whatever that means). The programmers you've hired to use it, however, probably are not.

Long answer: The question belies a true understanding of the issue. Perl is just as Y2K compliant as your pencil--no more, and no less. Can you use your pencil to write a non-Y2K-compliant memo? Of course you can. Is that the pencil's fault? Of course it isn't.

The date and time functions supplied with Perl (gmtime and localtime) supply adequate information to determine the year well beyond 2000 (2038 is when trouble strikes for 32-bit machines). The year returned by these functions when used in a list context is the year minus 1900. For years between 1910 and 1999 this happens to be a 2-digit decimal number. To avoid the year 2000 problem simply do not treat the year as a 2-digit number. It isn't.

When gmtime() and localtime() are used in scalar context they return a timestamp string that contains a fully-expanded year. For example, $timestamp = gmtime(1005613200) sets $timestamp to "Tue Nov 13 01:00:00 2001". There's no year 2000 problem here.

That doesn't mean that Perl can't be used to create non-Y2K compliant programs. It can. But so can your pencil. It's the fault of the user, not the language. At the risk of inflaming the NRA: ``Perl doesn't break Y2K, people do.'' See http://language.perl.com/news/y2k.html for a longer exposition.

 

 

 

Domain name registration service & domain search - 
Register cheap domain name from $7.95 and enjoy free domain services 
 

Cheap domain name search service -
Domain name services at just
$8.95/year only
 

Register domain name -
Buy domain name registration and cheap domain transfer at low, affordable price.

© 2002-2004 Active-Venture.com Web Site Hosting Service

 

[ First we thought the PC was a calculator. Then we found out how to turn numbers into letters with ASCII — and we thought it was a typewriter. Then we discovered graphics, and we thought it was a television. With the World Wide Web, we've realized it's a brochure.   ]

 

 
 
 

Disclaimer: This documentation is provided only for the benefits of our web hosting customers.
For authoritative source of the documentation, please refer to http://www.perldoc.com