System Times
Time
There are two ways of measuring time: ages from today, and counting from an arbitrary date in the past. So, for example, you can get that a file is 28.5 days old, or you can find out that the file was created at 3:53 PM on January 21, 1985. In Perl, you measure the latter in seconds from “the start of the epoch”. The epoch is simply the earliest date your computer can use. For most Unix computers, this is the midnight before January 1, 1970, universal standard time. On the Macintosh, this is the midnight before January 1, 1904. You don’t really need to worry about that, since you’ll generally be feeding the number of seconds into special built-in functions that take the seconds and return information about that date that number represents.
The “time” function returns the current time, that is, the number of seconds since the epoch.
Time Information
The “localtime” and “gmtime” functions take a “seconds since the epoch” number and return information about the date that number represents. The “localtime” function returns information about what that time represents in whatever the local time is, and the “gmtime” returns the same information but relative to universal standard time.
They return a nine-element array:
0 - Seconds
1 - Minutes
2 - Hour
3 - Day of the month
4 - Month (0 for January, 11 for December)
5 - Year (0 for 1900, 100 for 2000: just add 1900)
6 - Weekday (0 for Sunday, 6 for Saturday)
7 - Day of the year, from 1 to 365
8 - 1 if the result represents daylight savings, 0 if not.
Here’s a simple program that returns the current date and time in a ‘human-readable’ format:
@Weekdays = 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
@Months = 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
@Now = localtime(time());
$Month = $Months[$Now[4]];
$Weekday = $Weekdays[$Now[6]];
$Hour = $Now[2];
if ($Hour > 12) {
$Hour = $Hour - 12;
$AMPM = "PM";
} else {
$Hour = 12 if $Hour == 0;
$AMPM ="AM";
}
Minute = $Now[1];
$Minute = "0$Minute" if $Minute < 10;
$Year = $Now[5]+1900;
print "$Weekday, $Month $Now[3], $Year $Hour:$Minute $AMPM\n";
This should produce something like the following:
Sunday, May 24, 1998 12:10 AM
File Times
You can get file times either with the -M or -C file check, or the eighth and ninth elements of the ‘stat’ function. The file checks return the age in days (including fractions) and the stat function returns the time in seconds since the ‘epoch’, or the earliest possible time on the computer. This is usually sometime early in the twentieth century.
Age in Days
The -M file check returns the age in days since the file was last changed. It includes fractional amounts, so if you want to compare days, you need to take the ‘int’ of the returned value. The -A file check returns the age in days since someone last looked at the file.
foreach $FileName (@ARGV) {
$FileAge = -M $FileName;
if ($FileAge < .5) {
print "\”$FileName\" is less than half a day old.\n";
} elsif ($FileAge < 1.5) {
print "\"$FileName\" is only a day old.\n";
} else {
$FileAge = int($FileAge+.5);
print "\"$FileName\" is $FileAge days old.\n";
}
}
Date Statistics
If you need more detailed information about the date of file modification, use the ‘stat’ function and ask for the ninth element. Then, use ‘localtime’ or ‘gmtime’ to get the day, month, year, and time that the file was changed.
@Weekdays = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
@Months = ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
foreach $FileName (@ARGV) {
@Stats = stat($FileName);
$ModTime = $Stats[9];
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($ModTime);
$Weekday = $Weekdays[$wday];
$Month = $Months[$mon];
$year += 1900;
print "\"$FileName\" was last modified on $Weekday, $Month $mday, $year.\n";
}
Year 2,000
There are a number of year 2,000 problems. These have to do with not treating years correctly. As far as Perl is concerned, make sure that:
- You add 1900 to your Perl-derived years. Don’t put the string “19” in front of your number! You will end up getting “19100” in the year 2,000. You treat leap years correctly.
- There are three rules to follow to check for a leap year.
- The actual year 2,000 problem is more complex. If you are interested, there are entire web sites devoted to the topic. But as long as you store your years as numbers in Perl, and look out for leap years, you should be fine within your Perl programs.
Leap Years
If you work with dates, you will occasionally want to know what a leap year is.
- If it is divisible by 4, it is a leap year, except
- If it is divisible by 100, it is not be a leap year, except
- If it is divisible by 400, it is a leap year.
- When figuring out what it is divisible, make sure you are using the real year! Add 1900 to it if you are using a Perl year. The year 1900 (divisible by 4 and 100) is not a leap year. The year 2000 (divisible by 4, 100, and 400) is a leap year.
About this Tutorial
This tutorial is written by Jerry Stratton and is published under the GNU Free Documentation License.