0

0

Perl时间处理函数使用详解

巴扎黑

巴扎黑

发布时间:2017-09-05 11:22:42

|

1969人浏览过

|

来源于php中文网

原创

本文重点讨论perl时间处理函数的概念,perl能在绝大多数操作系统运行,可以方便地向不同操作系统迁移,并且perl借取了c、sed、awk、shellscripting以及很多其他程序语言的特性

一. Perl时间的表示函数

1. 表示日期的方式多种多样:
"18Jan1973";
"18/01/1973";
"01/18/1973";
"Jan181973";
"18-01-73";
"18-01-1973";
"01/73".
其中一些格式意思不清(如"01-06-1973",是表示6月1日呢,还是表示1月6日呢?)
如果不规定日期的表示形式,是很难处理的.

想理解"18Jan1973"和"6Sep1950"之间的区别,需要把它们转换为数字表示.
Unix内部运用纪元秒表示时间。
日期和时间加起来表示:
自格林威志时间1970年1月1日午夜时分(纪元)到当前时刻之间的秒数。
如, "18 Jan 1973:(假定为午夜时分)的纪元秒为96163200。

2. 在该系统中,午夜表示一天的开始时刻。

让我们通过Perl中提供的gmtime函数生成一个日期。
给定一个用以表示自从纪元以来的秒数的整数, 通过gmtime函数可以计算出代表相应的日期和时刻,
例一:
调用gmtime()函数,你会得到一系列值的列表,包括时,分,秒,日期,月份,年份等.


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

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

输出:
Thu Jan 18 00:00:00 1973

例二:以","为分隔符输出时间
print join(",", gmtime(96163200));

0,0,0,18,0,73,4,17,0
语义:
前3个数: 0,0,0, 分别表示秒, 分, 时. 小时是从0-23,故下午是12时往后.
第4个数: 18, 表示该月中的天数(本例中为18号)。
第5个数: 0 , 表示月份,从0开始(代表1月份)。
之所以从0开始,是因为月份对应着月份数组的下标:


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

第6个数: 73, 年份, (本例中为73)的表示有点特殊。它并不是年份的最后两位数字。
它表示从1900年开始的年份。
为什么要这样表示呢?
这是因为C语言就是这样处理的。
Perl试图使得其库和系统调用尽量接近操作系统的处理方式。
所以,如果你想输出4位数的年份,表示如下:
$year=(gmtime(96163200))[5]+1900;

如果你不了解这种处理方式,就会制造出Y2K疑问,你也许会这样写:
$year="19".(gmtime(96163200))[5]; #出错!2000年将变为19100
第7个数: 4 , 表示一星期中的第几天(星期日为0).
第8个数: 17, 一年中的第几天(0表示一年中的第一天).
第9个数: 0 , 能不能采用夏时制(0表示不采用,正数表示采用,负数表示不可知).

3. Perl中的time()函数返回以纪元秒形式表示的当前日期和时间。

如果你打算把它转换为字符串,就可运用gmtime()和localtime()函数:


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

如果调用localtime()或gmtime()时不带参数,它将自己调用time()


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

二. Perl时间处理函数中(日期和时间操作)

1. 计算两个时刻之间的时间段,
只需将它们转换为相应的纪元秒,然后两数相减即可:
$difference_in_seconds=$later_datetime-$earlier_datetime;

要把秒转换为分,时,或天数,只须要分别将它们除以60,3600和86400即可:


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

2. 计算"4天后是几号?":


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

它给出的答案精确到秒。
例如,
如果4天后的纪元秒值为932836935,你可以输出日期的字符串如下;
Sat Jul 24 11:23:17 1999

ShoopD 网上商店系统
ShoopD 网上商店系统

用 php + mysql 驱动的在线商城系统,我们的目标为中国的中小企业及个人提供最简洁,最安全,最高效的在线商城解决方案,使用了自建的会员积分折扣功能,不同的会员组有不同的折扣,让您的商店吸引更多的后续客户。 系统自动加分处理功能,自动处理会员等级,免去人工处理的工作量,让您的商店运作起来更方便省事 采用了自建的直接模板技术,免去了模板解析时间,提高了代码利用效率 独立开发的购物车系统,使用最

下载

3. 输出某个日期的午夜时分
如"Sat Jul 24 00:00:00 1999",
运用如下模块:
$then=$then-$then%86400;#去掉那个日期的尾巴

类似地,你可以用四舍五入法,输出最靠近午夜时分的日期:


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

如果你的时区距离GMT为相差偶数个小时,这就管用了。
并不是所有的时区都是很容易处理的。
你所真实须要的是在你自己的时区内计算纪元秒,而不是在GMT中计算。

Perl中的名为Time::Local的模块,
可以提供两个函数timelocal()和timegm()。其返回值同localtime()和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”。

三. Perl时间处理函数中日常生活所用的日期和时间的表示

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

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模块。

相关文章

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

12

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

200

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

98

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

15

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

16

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

9

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

56

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

28

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
韩顺平 2016年 最新PHP基础视频教程
韩顺平 2016年 最新PHP基础视频教程

共47课时 | 10.2万人学习

perl中文手册
perl中文手册

共0课时 | 0人学习

极客学院Ruby基础视频教程
极客学院Ruby基础视频教程

共22课时 | 4.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号