PHP的日期检查类

2019-10-25  本文已影响0人  imjcw

前言

还是在看项目的源码,其实这个是和上篇 《PHP自带的观察者模式接口》是一起看到的。

回顾

还记得在廿一客最后的一段日子里,开发了用户中心的纪念日模块,当时为了加强参数的校验,对用户纪念日也进行了相关校验。

当时处理起来还是蛮麻烦的,大致的思路如下:

看了项目中的全局函数部分的时候,突然发现,自己还是知道的太少了。

checkdate

PHP 提供了 checkdate 方法给我们做日期检查。

bool checkdate ( int $month , int $day , int $year )

使用很简单,如下(例子来源于文档):

var_dump(checkdate(12, 31, 2000)); # bool(true)
var_dump(checkdate(2, 29, 2001));  # bool(false)

DateTime类

原以为 checkdate 已经非常强大了,可以解决我上面的纪念日的问题了。然而,我在浏览文档中的例子之后,发现了一个更加强大的类 DateTime

别的不说,可以先看一下人家是怎么实现检查日期功能的:

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

var_dump(validateDate('2012-02-28 12:12:12')); # true
var_dump(validateDate('2012-02-30 12:12:12')); # false
var_dump(validateDate('2012-02-28', 'Y-m-d')); # true
var_dump(validateDate('28/02/2012', 'd/m/Y')); # true
var_dump(validateDate('30/02/2012', 'd/m/Y')); # false
var_dump(validateDate('14:50', 'H:i')); # true
var_dump(validateDate('14:77', 'H:i')); # false
var_dump(validateDate(14, 'H')); # true
var_dump(validateDate('14', 'H')); # true

var_dump(validateDate('2012-02-28T12:12:12+02:00', 'Y-m-d\TH:i:sP')); # true
# or
var_dump(validateDate('2012-02-28T12:12:12+02:00', DateTime::ATOM)); # true

var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', 'D, d M Y H:i:s O')); # true
# or
var_dump(validateDate('Tue, 28 Feb 2012 12:12:12 +0200', DateTime::RSS)); # true
var_dump(validateDate('Tue, 27 Feb 2012 12:12:12 +0200', DateTime::RSS)); # false
# ...

很强大!!!支持多种格式的日期时间格式。

当然,不同的函数和类,使用的场景不同,比如我之前的需求,一个 checkdate 可以满足我的需求了,但如果使用 DateTime 来做的话,有点杀鸡用牛刀的感觉。

当然,DateTime 的强大之处不止在这里,先看一下它有那些属性和函数吧。

DateTime implements DateTimeInterface {
    /* Inherited constants */
    const string DateTimeInterface::ATOM = "Y-m-d\TH:i:sP" ;
    const string DateTimeInterface::COOKIE = "l, d-M-Y H:i:s T" ;
    const string DateTimeInterface::ISO8601 = "Y-m-d\TH:i:sO" ;
    const string DateTimeInterface::RFC822 = "D, d M y H:i:s O" ;
    const string DateTimeInterface::RFC850 = "l, d-M-y H:i:s T" ;
    const string DateTimeInterface::RFC1036 = "D, d M y H:i:s O" ;
    const string DateTimeInterface::RFC1123 = "D, d M Y H:i:s O" ;
    const string DateTimeInterface::RFC2822 = "D, d M Y H:i:s O" ;
    const string DateTimeInterface::RFC3339 = "Y-m-d\TH:i:sP" ;
    const string DateTimeInterface::RFC3339_EXTENDED = "Y-m-d\TH:i:s.vP" ;
    const string DateTimeInterface::RSS = "D, d M Y H:i:s O" ;
    const string DateTimeInterface::W3C = "Y-m-d\TH:i:sP" ;

    /* Methods */
    public __construct ([ string $time = "now" [, DateTimeZone $timezone = NULL ]] )
    public DateTime add ( DateInterval $interval )
    public static DateTime createFromFormat ( string $format , string $time [, DateTimeZone $timezone ] )
    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 [, int $microseconds = 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 )
}

一些小的使用,多种格式,总有一款适合你:

摘自: PHP中的DateTime类

获取当前时间

$date = new DateTime();
echo $date->format('Y-m-d H:i:s');

获取特定时间并打印

# 指定时间
$date = new DateTime('2014-05-04');
echo $date->format('Y-m-d H:i:s');

# 不一定是时间格式,语义化的也支持一部分
$date2 = new DateTime('tomorrow');
echo $date2->format('Y-m-d H:i:s');

# 获取两天后的时间
$date2 = new DateTime('+2 days');
echo $date2->format('Y-m-d H:i:s');

# 一些方法的使用
$date = new DateTime();
// add方法
$date->add(new DateInterval('P1D'));
echo $date->format('Y-m-d H:i:s');

// modify方法
$date->modify('+1 day');
echo $date->format('Y-m-d H:i:s');

// setDate方法
$date->setDate('1989','11','10');
echo $date->format('Y-m-d H:i:s');

// setTime方法
$date = new DateTime('2001-01-01');
$date->setTime(14, 55);
echo $date->format('Y-m-d H:i:s');

$date->setTime(14, 55, 24);
echo $date->format('Y-m-d H:i:s');

unix时间戳的转换

# 获取当前时间的时间戳
$date = new DateTime();
echo $date->format('U');
# 或者
$date = new DateTime();
echo $date->getTimestamp();

# 将时间戳转换为可读时间
$date = new DateTime('@1408950651');
$date->setTimezone(new DateTimeZone('Asia/Shanghai'));
echo $date->format('Y-m-d H:i:s');
# 或者
$date = new DateTime();
$date->setTimestamp(1408950651);
echo $date->format('Y-m-d H:i:s');

日期的比较

# 日期大小比较
$date1 = new DateTime();
$date2 = new DateTime('2016-12-15');

if($date1 < $date2) {
    echo $date2->format('Y-m-d H:i:s') . ' is in the future';
}

# 日期间隔
$date1 = new DateTime();
$date2 = new DateTime('2016-12-15');
$diff = $date1->diff($date2);
# 格式化输出
echo $diff->format("The future will come in %Y years %m months and %d days");

其中,日期比较是感觉非常实用的,计算日期的神器啊,省去了不少麻烦。

最后

又学到了两个方法,突然感觉以后有类似的需求,可以较快不少开发速度。

上一篇下一篇

猜你喜欢

热点阅读