PLEAC-Perl 教程 - Date and Time (Perl进阶者极力推荐)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

3. Dates and Times

Introduction

#-----------------------------
$sec
#-----------------------------
$min
#-----------------------------
$hours
#-----------------------------
$mday
#-----------------------------
$month
#-----------------------------
$year
#-----------------------------
$wday
#-----------------------------
$yday
#-----------------------------
$isdst
#-----------------------------
#Fri Apr 11 09:27:08 1997
#-----------------------------
# using arrays
print "Today is day ", (localtime)[7], " of the current year./n";
# Today is day 117 of the current year.

# using Time::tm objects
use Time::localtime;
$tm = localtime;
print "Today is day ", $tm->yday, " of the current year./n";
# Today is day 117 of the current year.
#-----------------------------

Finding Today's Date

#-----------------------------
($DAY, $MONTH, $YEAR) = (localtime)[3,4,5];
#-----------------------------
use Time::localtime;
$tm = localtime;
($DAY, $MONTH, $YEAR) = ($tm->mday, $tm->mon, $tm->year);
#-----------------------------
($day, $month, $year) = (localtime)[3,4,5];
printf("The current date is %04d %02d %02d/n", $year+1900, $month+1, $day);
# The current date is 1998 04 28
#-----------------------------
($day, $month, $year) = (localtime)[3..5];
#-----------------------------
use Time::localtime;
$tm = localtime;
printf("The current date is %04d-%02d-%02d/n", $tm->year+1900,
($tm->mon)+1, $tm->mday);
# The current date is 1998-04-28
#-----------------------------
printf("The current date is %04d-%02d-%02d/n",
sub {($_[5]+1900, $_[4]+1, $_[3])}->(localtime));
#-----------------------------
use POSIX qw(strftime);
print strftime "%Y-%m-%d/n", localtime;
#-----------------------------

Converting DMYHMS to Epoch Seconds

#-----------------------------
use Time::Local;
$TIME = timelocal($sec, $min, $hours, $mday, $mon, $year);
$TIME = timegm($sec, $min, $hours, $mday, $mon, $year);
#-----------------------------
# $hours, $minutes, and $seconds represent a time today,
# in the current time zone
use Time::Local;
$time = timelocal($seconds, $minutes, $hours, (localtime)[3,4,5]);
#-----------------------------
# $day is day in month (1-31)
# $month is month in year (1-12)
# $year is four-digit year e.g., 1967
# $hours, $minutes and $seconds represent UTC time

use Time::Local;
$time = timegm($seconds, $minutes, $hours, $day, $month-1, $year-1900);
#-----------------------------

Converting Epoch Seconds to DMYHMS

#-----------------------------
($seconds, $minutes, $hours, $day_of_month, $month, $year,
$wday, $yday, $isdst) = localtime($time);
#-----------------------------
use Time::localtime; # or Time::gmtime
$tm = localtime($TIME); # or gmtime($TIME)
$seconds = $tm->sec;
# ...
#-----------------------------
($seconds, $minutes, $hours, $day_of_month, $month, $year,
$wday, $yday, $isdst) = localtime($time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d/n",
$hours, $minutes, $seconds, $year+1900, $month+1,
$day_of_month);
#-----------------------------
use Time::localtime;
$tm = localtime($time);
printf("Dateline: %02d:%02d:%02d-%04d/%02d/%02d/n",
$tm->hour, $tm->min, $tm->sec, $tm->year+1900,
$tm->mon+1, $tm->mday);
#-----------------------------

Adding to or Subtracting from a Date

#-----------------------------
$when = $now + $difference;
$then = $now - $difference;
#-----------------------------
use Date::Calc qw(Add_Delta_Days);
($y2, $m2, $d2) = Add_Delta_Days($y, $m, $d, $offset);
#-----------------------------
use Date::Calc qw(Add_Delta_DHMS);
($year2, $month2, $day2, $h2, $m2, $s2) =
Add_Delta_DHMS( $year, $month, $day, $hour, $minute, $second,
$days_offset, $hour_offset, $minute_offset, $second_offset );
#-----------------------------
$birthtime = 96176750; # 18/Jan/1973, 3:45:50 am
$interval = 5 + # 5 seconds
17 * 60 + # 17 minutes
2 * 60 * 60 + # 2 hours
55 * 60 * 60 * 24; # and 55 days
$then = $birthtime + $interval;
print "Then is ", scalar(localtime($then)), "/n";
# Then is Wed Mar 14 06:02:55 1973
#-----------------------------
use Date::Calc qw(Add_Delta_DHMS);
($year, $month, $day, $hh, $mm, $ss) = Add_Delta_DHMS(
1973, 1, 18, 3, 45, 50, # 18/Jan/1973, 3:45:50 am
55, 2, 17, 5); # 55 days, 2 hrs, 17 min, 5 sec
print "To be precise: $hh:$mm:$ss, $month/$day/$year/n";
# To be precise: 6:2:55, 3/14/1973
#-----------------------------
use Date::Calc qw(Add_Delta_Days);
($year, $month, $day) = Add_Delta_Days(1973, 1, 18, 55);
print "Nat was 55 days old on: $month/$day/$year/n";
# Nat was 55 days old on: 3/14/1973
#-----------------------------

Difference of Two Dates

#-----------------------------
$seconds = $recent - $earlier;
#-----------------------------
use Date::Calc qw(Delta_Days);
$days = Delta_Days( $year1, $month1, $day1, $year2, $month2, $day2);
#-----------------------------
use Date::Calc qw(Delta_DHMS);
($days, $hours, $minutes, $seconds) =
Delta_DHMS( $year1, $month1, $day1, $hour1, $minute1, $seconds1, # earlier
$year2, $month2, $day2, $hour2, $minute2, $seconds2); # later
#-----------------------------
$bree = 361535725; # 16 Jun 1981, 4:35:25
$nat = 96201950; # 18 Jan 1973, 3:45:50

$difference = $bree - $nat;
print "There were $difference seconds between Nat and Bree/n";
# There were 265333775 seconds between Nat and Bree


$seconds = $difference % 60;
$difference = ($difference - $seconds) / 60;
$minutes = $difference % 60;
$difference = ($difference - $minutes) / 60;
$hours = $difference % 24;
$difference = ($difference - $hours) / 24;
$days = $difference % 7;
$weeks = ($difference - $days) / 7;

print "($weeks weeks, $days days, $hours:$minutes:$seconds)/n";
# (438 weeks, 4 days, 23:49:35)
#-----------------------------
use Date::Calc qw(Delta_Days);
@bree = (1981, 6, 16); # 16 Jun 1981
@nat = (1973, 1, 18); # 18 Jan 1973
$difference = Delta_Days(@nat, @bree);
print "There were $difference days between Nat and Bree/n";
# There were 3071 days between Nat and Bree
#-----------------------------
use Date::Calc qw(Delta_DHMS);
@bree = (1981, 6, 16, 4, 35, 25); # 16 Jun 1981, 4:35:25
@nat = (1973, 1, 18, 3, 45, 50); # 18 Jan 1973, 3:45:50
@diff = Delta_DHMS(@nat, @bree);
print "Bree came $diff[0] days, $diff[1]:$diff[2]:$diff[3] after Nat/n";
# Bree came 3071 days, 0:49:35 after Nat
#-----------------------------

Day in a Week/Month/Year or Week Number

#-----------------------------
($MONTHDAY, $WEEKDAY, $YEARDAY) = (localtime $DATE)[3,6,7];
$WEEKNUM = int($YEARDAY / 7) + 1;
#-----------------------------
use Date::Calc qw(Day_of_Week Week_Number Day_of_Year);
# you have $year, $month, and $day
# $day is day of month, by definition.
$wday = Day_of_Week($year, $month, $day);
$wnum = Week_Number($year, $month, $day);
$dnum = Day_of_Year($year, $month, $day);
#-----------------------------
use Date::Calc qw(Day_of_Week Week_Number Day_of_Week_to_Text)

$year = 1981;
$month = 6; # (June)
$day = 16;

$wday = Day_of_Week($year, $month, $day);
print "$month/$day/$year was a ", Day_of_Week_to_Text($wday), "/n";
## see comment above

$wnum = Week_Number($year, $month, $day);
print "in the $wnum week./n";
# 6/16/1981 was a Tuesday
#

# in week number 25.
#-----------------------------

Parsing Dates and Times from Strings

#-----------------------------
use Time::Local;
# $date is "1998-06-03" (YYYY-MM-DD form).
($yyyy, $mm, $dd) = $date =~ /(/d+)-(/d+)-(/d+)/;
# calculate epoch seconds at midnight on that day in this timezone
$epoch_seconds = timelocal(0, 0, 0, $dd, $mm, $yyyy);
#-----------------------------
use Date::Manip qw(ParseDate UnixDate);
$date = ParseDate($string);
if (!$date) {
# bad date
} else {
@values = UnixDate($date, @formats);
}
#-----------------------------
use Date::Manip qw(ParseDate UnixDate);

while (<>) {
$date = ParseDate($_);
if (!$date) {
warn "Bad date string: $_/n";
next;
} else {
($year, $month, $day) = UnixDate($date, "%Y", "%m", "%d");
print "Date was $month/$day/$year/n";
}
}
#-----------------------------

Printing a Date

#-----------------------------
$STRING = localtime($EPOCH_SECONDS);
#-----------------------------
use POSIX qw(strftime);
$STRING = strftime($FORMAT, $SECONDS, $MINUTES, $HOUR,
$DAY_OF_MONTH, $MONTH, $YEAR, $WEEKDAY,
$YEARDAY, $DST);
#-----------------------------
use Date::Manip qw(UnixDate);
$STRING = UnixDate($DATE, $FORMAT);
#-----------------------------
# Sun Sep 21 15:33:36 1997
#-----------------------------
use Time::Local;
$time = timelocal(50, 45, 3, 18, 0, 73);
print "Scalar localtime gives: ", scalar(localtime($time)), "/n";
# Scalar localtime gives: Thu Jan 18 03:45:50 1973
#-----------------------------
use POSIX qw(strftime);
use Time::Local;
$time = timelocal(50, 45, 3, 18, 0, 73);
print "strftime gives: ", strftime("%A %D", localtime($time)), "/n";
# strftime gives: Thursday 01/18/73
#-----------------------------
use Date::Manip qw(ParseDate UnixDate);
$date = ParseDate("18 Jan 1973, 3:45:50");
$datestr = UnixDate($date, "%a %b %e %H:%M:%S %z %Y"); # as scalar
print "Date::Manip gives: $datestr/n";
# Date::Manip gives: Thu Jan 18 03:45:50 GMT 1973
#-----------------------------

High-Resolution Timers

#-----------------------------
use Time::HiRes qw(gettimeofday);
$t0 = gettimeofday;
## do your operation here
$t1 = gettimeofday;
$elapsed = $t1 - $t0;
# $elapsed is a floating point value, representing number
# of seconds between $t0 and $t1
#-----------------------------
use Time::HiRes qw(gettimeofday);
print "Press return when ready: ";
$before = gettimeofday;
$line = <>;
$elapsed = gettimeofday-$before;
print "You took $elapsed seconds./n";
# Press return when ready:
#

# You took 0.228149 seconds.
#-----------------------------
require 'sys/syscall.ph';

# initialize the structures returned by gettimeofday
$TIMEVAL_T = "LL";
$done = $start = pack($TIMEVAL_T, ());

# prompt
print "Press return when ready: ";

# read the time into $start
syscall(&SYS_gettimeofday, $start, 0) != -1
|| die "gettimeofday: $!";

# read a line
$line = <>;

# read the time into $done
syscall(&SYS_gettimeofday, $done, 0) != -1
|| die "gettimeofday: $!";

# expand the structure
@start = unpack($TIMEVAL_T, $start);
@done = unpack($TIMEVAL_T, $done);

# fix microseconds
for ($done[1], $start[1]) { $_ /= 1_000_000 }

# calculate time difference
$delta_time = sprintf "%.4f", ($done[0] + $done[1] )
-
($start[0] + $start[1] );

print "That took $delta_time seconds/n";
# Press return when ready:
#

# That took 0.3037 seconds
#-----------------------------
use Time::HiRes qw(gettimeofday);
# take mean sorting time
$size = 500;
$number_of_times = 100;
$total_time = 0;

for ($i = 0; $i < $number_of_times; $i++) {
my (@array, $j, $begin, $time);
# populate array
@array = ();
for ($j=0; $j<$size; $j++) { push(@array, rand) }

# sort it
$begin = gettimeofday;
@array = sort { $a <=> $b } @array;
$time = gettimeofday-$begin;
$total_time += $time;
}

printf "On average, sorting %d random numbers takes %.5f seconds/n",
$size, ($total_time/$number_of_times);
# On average, sorting 500 random numbers takes 0.02821 seconds
#-----------------------------

Short Sleeps

#-----------------------------
select(undef, undef, undef, $time_to_sleep);
#-----------------------------
use Time::HiRes qw(sleep);
sleep($time_to_sleep);
#-----------------------------
while (<>) {
select(undef, undef, undef, 0.25);
print;
}
#-----------------------------
use Time::HiRes qw(sleep);
while (<>) {
sleep(0.25);
print;
}
#-----------------------------

Program: hopdelta

#-----------------------------
use Date::Manip qw(ParseDate DateCalc);
$d1 = ParseDate("Tue, 26 May 1998 23:57:38 -0400");
$d2 = ParseDate("Wed, 27 May 1998 05:04:03 +0100");
print DateCalc($d1, $d2);
# +0:0:0:0:0:6:25
#-----------------------------
# download the following standalone program
#!/usr/bin/perl
# hopdelta - feed mail header, produce lines
# showing delay at each hop.
use strict;
use Date::Manip qw (ParseDate UnixDate);

# print header; this should really use format/write due to
# printf complexities
printf "%-20.20s %-20.20s %-20.20s %s/n",
"Sender", "Recipient", "Time", "Delta";
$/ = ''; # paragraph mode
$_ = <>; # read header
s//n/s+/ /g; # join continuation lines

# calculate when and where this started
my($start_from) = /^From.*/@([^/s>]*)/m;
my($start_date) = /^Date:/s+(.*)/m;
my $then = getdate($start_date);
printf "%-20.20s %-20.20s %s/n", 'Start', $start_from, fmtdate($then);

my $prevfrom = $start_from;

# now process the headers lines from the bottom up
for (reverse split(//n/)) {
my ($delta, $now, $from, $by, $when);
next unless /^Received:/;
s//bon (.*?) (id.*)/; $1/s; # qmail header, I think
unless (($when) = /;/s+(.*)$/) { # where the date falls
warn "bad received line: $_";
next;
}
($from) = /from/s+(/S+)/;
($from) = //((.*?)/)/ unless $from; # some put it here
$from =~ s//)$//; # someone was too greedy
($by) = /by/s+(/S+/./S+)/; # who sent it on this hop

# now random mungings to get their string parsable
for ($when) {
s/ (for|via) .*$//;
s/([+-]/d/d/d/d) /(/S+/)/$1/;
s/id /S+;/s*//;
}
next unless $now = getdate($when); # convert to Epoch
$delta = $now - $then;

printf "%-20.20s %-20.20s %s ", $from, $by, fmtdate($now);
$prevfrom = $by;
puttime($delta);
$then = $now;
}

exit;

# convert random date strings into Epoch seconds
sub getdate {
my $string = shift;
$string =~ s//s+/(.*/)/s*$//; # remove nonstd tz
my $date = ParseDate($string);
my $epoch_secs = UnixDate($date,"%s");
return $epoch_secs;
}

# convert Epoch seconds into a particular date string
sub fmtdate {
my $epoch = shift;
my($sec,$min,$hour,$mday,$mon,$year) = localtime($epoch);
return sprintf "%02d:%02d:%02d %04d/%02d/%02d",
$hour, $min, $sec,
$year + 1900, $mon + 1, $mday,
}

# take seconds and print in pleasant-to-read format
sub puttime {
my($seconds) = shift;
my($days, $hours, $minutes);
$days = pull_count($seconds, 24 * 60 * 60);
$hours = pull_count($seconds, 60 * 60);
$minutes = pull_count($seconds, 60);
put_field('s', $seconds);
put_field('m', $minutes);
put_field('h', $hours);
put_field('d', $days);
print "/n";
}

# usage: $count = pull_count(seconds, amount)
# remove from seconds the amount quantity, altering caller's version.
# return the integral number of those amounts so removed.
sub pull_count {
my($answer) = int($_[0] / $_[1]);
$_[0] -= $answer * $_[1];
return $answer;
}

# usage: put_field(char, number)
# output number field in 3-place decimal format, with trailing char
# suppress output unless char is 's' for seconds
sub put_field {
my ($char, $number) = @_;
printf " %3d%s", $number, $char if $number || $char eq 's';
}

#-----------------------------
# Sender Recipient Time Delta
#

# Start wall.org 09:17:12 1998/05/23
#

# wall.org mail.brainstorm.net 09:20:56 1998/05/23 44s 3m
#

# mail.brainstorm.net jhereg.perl.com 09:20:58 1998/05/23 2s
#

#-----------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值