Home >Backend Development >Python Tutorial >Detailed explanation of the use of Perl time processing functions

Detailed explanation of the use of Perl time processing functions

巴扎黑
巴扎黑Original
2017-09-05 11:22:421757browse

This article focuses on the concept of Perl time processing functions. Perl can run on most operating systems and can be easily migrated to different operating systems. Perl has borrowed ideas from C, sed, awk, shellscripting and many other programming languages. Features

1. Perl time representation function

1. There are many ways to represent dates:
"18Jan1973";
"18/01 /1973";
"01/18/1973";
"Jan181973";
"18-01-73";
"18-01-1973";
"01/ 73".
Some of the formats are unclear (for example, "01-06-1973", does it mean June 1st or January 6th?)
If the date representation form is not specified, It is difficult to deal with.

If you want to understand the difference between "18Jan1973" and "6Sep1950", you need to convert them into numerical representations.
Unix uses epoch seconds internally to represent time.
The sum of the date and time represents:
The number of seconds between midnight (epoch) on January 1, 1970 GMT and the current time.
For example, "18 Jan 1973: The epoch second (assumed to be midnight) is 96163200.

2. In this system, midnight represents the beginning of the day.

Let us generate a date through the gmtime function provided in Perl.
Given an integer representing the number of seconds since the epoch, the corresponding date and time can be calculated through the gmtime function,
Example 1:
Call the gmtime() function, and you will get a list of a series of values, including hours, minutes, seconds, dates, months, years, etc.


#!/usr/bin/perl
use Time::localtime;

$t_num = 96163200;
$tm = scalar(gmtime($t_num));
print $tm,"\n";

Output:
Thu Jan 18 00:00:00 1973

Example 2: Use "," as the separator to output the time
print join(",", gmtime(96163200 ));

0,0,0,18,0,73,4,17,0
Semantics:
The first 3 numbers: 0,0,0, respectively Seconds, minutes, hours. Hours are from 0 to 23, so afternoon is after 12 o'clock.
The fourth number: 18, represents the number of days in the month (in this case, the 18th). 5 numbers: 0, indicating the month, starting from 0 (representing January).
Starts from 0 because the month corresponds to the subscript of the month array:

##

@months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
$month = @months[(gmtime($t_num))[4]];
print "MONTH: ",$month,"\n";

The sixth number: 73, the year, (73 in this case) is a bit special. It is not the last two digits of the year.

It represents the year starting from 1900.

Why is it expressed like this?
This is because the C language handles it this way.
Perl tries to make its libraries and system calls as close as possible to the way the operating system handles them.
So, if you want to output. The 4-digit year is expressed as follows:

$year=(gmtime(96163200))[5]+1900;
If you don’t understand this processing method, you will To create a Y2K question, you might write:

$year="19".(gmtime(96163200))[5]; #Error! The year 2000 will become 19100

The 7th number: 4, Indicates the day of the week (Sunday is 0).
The 8th number: 17, the day of the year (0 indicates the first day of the year).
The 9th number : 0, whether daylight saving time can be adopted (0 means not adopted, positive number means adopted, negative number means unknown).

3. The time() function in Perl returns the form of epoch seconds

If you plan to convert it to a string, you can use the gmtime() and localtime() functions:


##
$now=localtime(time());
($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=localtime(time());

If you call localtime() or gmtime() without parameters, it will call time() itself


$now=localtime();
($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=localtime();


二. In Perl time processing functions (date and time operations)

1. Calculate the time period between two moments,

Just convert them to the corresponding Epoch seconds, and then subtract the two numbers: $difference_in_seconds=$later_datetime-$earlier_datetime;
To convert seconds to minutes, hours, or days, just divide them by 60, respectively. 3600 and 86400 are enough:


$difference_in_minutes=$difference_in_seconds/60;
$difference_in_hours=$difference_in_seconds/3600;
$difference_in_day=$difference_in_seconds/86400;

2. Calculate "What is the date in 4 days?":


$then=time()+86400*4;
print scalar(localtime($then));

The answer it gives is accurate to the second.
For example,

If the epoch second value 4 days later is 932836935, you can output the date string as follows;

Sat Jul 24 11:23:17 1999


3. Output the midnight hour of a certain date

For example, "Sat Jul 24 00:00:00 1999",Use the following module:$then=$then-$then%86400;#Remove that The tail of the date

Similarly, you can use rounding to output the date closest to midnight:


$then += 43200; #add on half a day
$then = $then - $then%86400; #truncate to the day

If your time zone is far away GMT is an even number of hours apart, so that works.
Not all time zones are easy to deal with.

What you really need is to calculate epoch seconds in your own time zone, not in GMT.


The module named Time::Local in Perl,
can provide two functions timelocal() and timegm(). Its return value is the same as localtime() and gmtime().


use Time::Local;
$then = time() + 4*86400;
$then = timegm(localtime($then)); #local epoch seconds
$then -= $then%86400; #truncate to the day
$then = timelocal(gmtime($then)); #back to gmt epoch seconds
print scalar(localtime$then,“\n”。


3. Representation of date and time used in daily life in Perl time processing function

前面介绍了时,分,年等值的意思,也了解了纪元秒的意思。
而日常生活中的日期和时间是用字符串来表示的,
怎样才能把日常所用的日期和时间串格式转换成纪元秒呢?

1. 要领之一是写出语法分析小程序,该要领灵活而高速:


#!/usr/bin/perl

use Time::Local;
@months{qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)}=(0..11);
$_ = "19 Dec 1997 15:30:02";
/(\d\d)\s+(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)/ or die "Notadate";


$mday=$1;
$mon=exists($months{$2})?$months{$2}:die"Badmonth";
$year=$3-1900;
($h,$m,$s)=($4,$5,$6);
$epoch_seconds = timelocal($s,$m,$h,$mday,$mon,$year);


print "day: ",$mday,"\n";
print "mon: ",$mon,"\n";
print "year: ",$year,"\n";
print "seconds: ",$epoch_seconds,"\n";

2. 一个更通用些的要领,是从CPAN安装Date::Manip模块。


useDate::Manip;
$epoch_seconds=UnixDate("19 Dec 1997 15:30:02","s");

留心,由于Date::Manip是个大模块,运用该模块时,将会添加你的程序的启动时间。
其中一个原由是Date::Manip将对多种不同的格式执行识别,
如:
"today"
"now"
"first sunday in april 2000"
"3:15,today"
"3:15 pm,first sunday in april 2000"
"2000/01/18 09:15" Date Manipulation
2036,2037,2038,…,1901?!

四. 大多数C程序把纪元秒存为有符号整数,可表示正的和负的日期;
但计算机存储器所表示的整数大小是有限的, 用有限的位数来表示秒.
这就是说,我们在计算纪元秒时, 所表示的日期是有限定的。
确切的限度取决于你的机器所能表示的整数的位数。

Perl最多以32位的长度存储整数。
粗略地讲,有一位用来表示正负号,其余31位来表示数。
如果8位,你可以存储的最大数是255,即2的8次方减1。
故Perl中所存储的32位符号数中的最大数为:


print 2**31-1,"\n";
2147483647

这个数字对应了哪个日期呢?


print scalar(gmtime(2**31-1)),"\n";
Tue Jan 19 03:14:07 2038

在那个时刻的1秒之后会发生什么呢?


print scalar(gmtime(2**31)),"\n";
Fri Dec 13 20:45:52 1901

对于32位有符号整数来说,2**31太大了。
它"翻卷过去了",其符号位被置为负号,因而成为了所能表示的最大负数。
这对应于1970年开始时刻之前的秒的最大值。
其结果说明了什么呢?你不能存储gmtime(2**31)之前或gmtime(2**31-1)之后的以纪元秒表示的日期。
你可千万不要想不开,这可不是什么大疑问。
如果你要用到32位有符号整数表示的纪元秒以外的时间,你只须要改动你的表示方式,
你可从CPAN中找到不少日期模块,其中的Date::Calc和Date::Manip很可能是功能最强的两个模块。
这两个模块运用自己的日期表示方式,以防止Y1901-Y2038的限定。
Date::Manip运用罗马历法,从公元0000到公元9999。
Date::Calc也运用罗马历法,可表示的年份从1到32767。

总结

Perl时间处理函数中对于在1902-2037范围内的日期和时期表示,把它们转换为纪元秒,
要存取这些数,你只需运用整数算术运算,gmtime()和localtime()函数,以及标准的Time::Local模块。
如果要对该范围以外的日期执行计算或者要分析某特殊的日期格式,
你可以运用CPAN中的Date::Manip和Date::Calc模块。

The above is the detailed content of Detailed explanation of the use of Perl time processing functions. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn