当碰到unix纪元问题时strtotime怎么转时间戳(DateTime类的使用方法)
UNIX纪元时间又称POSIX时间/新纪元时间(Epoch Time):从协调世界时1970年1月1日0时0分0秒起到现在的总秒数,不包括闰秒。正值表示1970以後,负值则表示1970年以前。
Unix 2038 bug(Y2K38漏洞)
又称 Unix Millennium Bug,此漏洞将会影响到所有 32 位系统下用 UNIX 时间戳整数来记录时间的 PHP,及其它编程语言。一个整型的变量所能保存的最大时间为 2038 年01月19 日 03:14:07。超过这个时间后,整型数值将会溢出。从 1970 年 01 月 01 日开始,到世界标准时 2038 年 01 月 19 日星期二凌晨 03:14:07 超过 2^31 – 1。2^31 – 1 就是0x7FFFFFFF,相信很多编程员都看过,在 32 位系统里,这表示最大的有符号整数。如果用它来表示秒数,大概相当于 68.1 年,从 1970 年到 2038 年刚好是这个数。
strtotime()与mktime()
php中的这两个函数都受到 Unix 2038 bug的影响,当日期值大于2038年时则返回false,当小于1970年时则返回负值。
DateTime类
PHP 从 5.2 版本开始引入了一个 DateTime 的类,用以解决Y2K38漏洞问题,以下是DateTime类的方法:
DateTime implements DateTimeInterface { /* 常量 */ const string ATOM = "Y-m-d\TH:i:sP" ; const string COOKIE = "l, d-M-Y H:i:s T" ; const string ISO8601 = "Y-m-d\TH:i:sO" ; const string RFC822 = "D, d M y H:i:s O" ; const string RFC850 = "l, d-M-y H:i:s T" ; const string RFC1036 = "D, d M y H:i:s O" ; const string RFC1123 = "D, d M Y H:i:s O" ; const string RFC2822 = "D, d M Y H:i:s O" ; const string RFC3339 = "Y-m-d\TH:i:sP" ; const string RSS = "D, d M Y H:i:s O" ; const string W3C = "Y-m-d\TH:i:sP" ; /* 方法 */ public __construct ([ string $time = "now" [, DateTimeZone $timezone = NULL ]] ) public DateTime add ( DateInterval $interval ) public static DateTime createFromFormat ( string $format , string $time [, DateTimeZone $timezone = date_default_timezone_get() ] ) public static array getLastErrors ( void ) public DateTime modify ( string $modify ) public static DateTime __set_state ( array $array ) public DateTime setDate ( int $year , int $month , int $day ) public DateTime setISODate ( int $year , int $week [, int $day = 1 ] ) public DateTime setTime ( int $hour , int $minute [, int $second = 0 ] ) public DateTime setTimestamp ( int $unixtimestamp ) public DateTime setTimezone ( DateTimeZone $timezone ) public DateTime sub ( DateInterval $interval ) public DateInterval diff ( DateTimeInterface $datetime2 [, bool $absolute = false ] ) public string format ( string $format ) public int getOffset ( void ) public int getTimestamp ( void ) public DateTimeZone getTimezone ( void ) public __wakeup ( void ) }
总结DateTime类的常用方法
1、输出当前时间
$date_time = new DateTime(); echo $date_time->format('Y-m-d H:i:s');
//输出结果为:2016-09-12
2、输出给定时间
$date_time = new DateTime('2016-09-12'); print_r($date_time); //输出结果为: DateTime Object ( [date] => 2016-06-13 00:00:00.000000 [timezone_type] => 3 [timezone] => PRC )
3、根据给定的时间格式化为需要的时间
$date_time = DateTime::createFromFormat('Ymd','20160912'); echo $date_time->format('Y-m-d');
4、输出Unix时间戳
$date_time = new DateTime('2016-09-12'); echo $date_time->format('U');
5、根据给定的时间戳输出格式化日期
$date_time = new DateTime(); $date_time->setTimestamp(1473609600); echo $date_time->format('Y-m-d H:i:s');
6、两个日期进行比较,年与年、月与月、日与日。。。。
$start_time = new DateTime('2016-09-12 00:00:00'); $end_time = new DateTime('3016-09-12 00:00:00'); $inberval = $start_time->diff($end_time); print_r($inberval); //输出结果为: DateInterval Object ( [y] => 1000 [m] => 0 [d] => 0 [h] => 0 [i] => 0 [s] => 0 [weekday] => 0 [weekday_behavior] => 0 [first_last_day_of] => 0 [invert] => 0 [days] => 365242 [special_type] => 0 [special_amount] => 0 [have_weekday_relative] => 0 [have_special_relative] => 0 )
7、日期加减
DateInterval构造函数的参数是一个表示时间间隔约定的字符串,这个时间间隔约定以字母P开头,后面跟着一个整数,最后是一个周期标识符,限定前面的整数。有效周期标识符如下:Y(年)、M(月)、D(日)、W(周)、H(时)、M(分)、S(秒),间隔约定中既可以有日期也可以有时间,用字母T分割。例如:间隔两天5小时,P2DT5H2M;
$date_time = new DateTime(); $interval = new DateInterval('P2DT5H2M'); $date_time->add($interval); echo $date_time->format('Y-m-d H:i:s').'<br>'; $interval = DateInterval::createFromDateString('+1 month'); $date_time->add($interval); echo $date_time->format('Y-m-d H:i:s').'<br>'; $date_time->sub($interval); echo $date_time->format('Y-m-d H:i:s');
8、重置当前时间的日期
$date_time = new DateTime(); $date_time->setDate(2015,10,1); echo $date_time->format('Y-m-d');
9、重置当前时间的时间部分
$date_time = new DateTime(); $date_time->setTime(13,10,1); echo $date_time->format('Y-m-d H:i:s');
10、日期的迭代
通过DatePeriod类实现日期迭代,它的构造方法接受四个参数:
1、日期实例,表示迭代开始的日期和时间;
2、DateInterval实例,表示下一个日期和时间的间隔;
3、次数,表示迭代的次数;
4、可选参数,显式指定周期的结束日期和时间。如果迭代时排除开始日期和时间,可设为DatePeriod::EXCLUDE_START_DATE);
$date_time = new DateTime(); $interval = DateInterval::createFromDateString('-1 day'); $period = new DatePeriod($date_time, $interval, 3,DatePeriod::EXCLUDE_START_DATE); foreach ($period as $date) { echo $date->format('Y-m-d'), PHP_EOL; }