PHP11 日期和时间

学习要点

  • UNIX时间戳
  • 将其他格式的日期转成UNIX时间戳格式
  • 基于UNIX时间戳的日期计算
  • 获取并格式化输出日期
  • 修改PHP的默认时间
  • 微秒的使用

  

Unix时间戳

相关概念

Unix timestamp:从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。

大部分32位操作系统使用32位二进制数字表示时间。此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制:01111111 11111111 11111111 11111111)。其后一秒,二进制数字会变为10000000 00000000 00000000 00000000,发生溢出错误,造成系统将时间误解为1901年12月13日20时45分52秒。这很可能会引起软件故障,甚至是系统瘫痪。使用64位二进制数字表示时间的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。

搭载64位处理器的iOS设备的时间bug。

 

PHP将日期和时间转变成UNIX时间戳

  • mktime()函数

    作用:取得一个日期的 Unix 时间戳

    语法格式:

int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") ]]]]]] )

  

    特点:对日期运算和验证表现卓越,可以自动校正越界输入。

    示例代码:

//获取当前时间戳

echo mktime();//不带参不推荐使用mktime(),推荐使用time()

echo time();

 

//时间戳转日期

echo date("Y-m-d",time());

 

//mktime自动校正越界

echo date("Y-m-d",mktime(0,0,0,12,36,2015)).'<br>';

echo date("Y-m-d",mktime(0,0,0,14,30,2015)).'<br>';

echo date("Y-m-d",mktime(0,0,0,1,1,2015)).'<br>';

echo date("Y-m-d",mktime(0,0,0,1,1,69)).'<br>';//<=70自动解析成1970

echo date("Y-m-d",mktime(0,0,0,1,1,1969)).'<br>';//1969

  

  • strtotime()函数

    语法格式:

int strtotime(string time,[int now])

    示例代码:

// 英文文本解析成时间戳:支持英语国家日期描述字符串

echo date ( "Y-m-d", strtotime ( "8 may 2016" ) );//2016-05-08

echo date ( "Y-m-d", strtotime ( "last monday" ) ); // 最近一个周一

echo date ( "Y-m-d", strtotime ( "now" ) );//现在

echo date ( "Y-m-d", strtotime ( "+1 day" ) );//明天

  

日期的计算

  • 上机练习:制作倒计时
  • 上机练习:给定生日日期,计算年龄
  • 上机练习:十年前
  • 上机练习:三个月前

 

在PHP中获取日期和时间

getdate()函数:获得日期/时间信息

 

 

date()函数:日期和时间格式化输出

当日期和时间需要保存或者计算时,应该使用时间戳作为标准格式。

语法规则:

String date ( string format [,int timestamp] )

 

 

 

修改PHP默认时区

  • 修改php.ini

    修改前:date.timezone = Europe/Paris

    修改后:date.timezone = Etc/GMT-8

  • 设置时区函数date_default_timezone_set()
date_default_timezone_set('PRC');

echo date("Y年m月d日  H:i:s");

  

使用微秒计算PHP脚本执行时间

语法格式:

mixed microtime ([ bool $get_as_float ] )

   

代码示例:

echo microtime();//输出微秒+时间戳

echo '<br>***********<br>';

echo microtime(true);//输出时间戳.微秒

   

上机练习:日历类的设计

日历类:

<?php

/**日历类*/
class Calendar
{
    private $year;//当前年
    private $month;//当前月
    private $days;//当前余月总天数
    private $monthStartWeekDay;//当月第一天对应的周几,用于遍历日历的开始

    /**构造方法:初始化当前日期参数*/
    function __construct()
    {
        //设置年
        $this->year = isset($_GET["year"]) ? $_GET["year"] : date("Y");
        //设置月
        $this->month = isset($_GET["month"]) ? $_GET["month"] : date("m");
        //计算该月第一天是周几
        $this->monthStartWeekDay = date("w", mktime(0, 0, 0, $this->month, 1, $this->year));
        //计算该月一共有多少天
        $this->days = date("t", mktime(0, 0, 0, $this->month, 1, $this->year));
    }

    /**
     * 输出日历信息字符串
     * @return string 日历字符串
     */
    function __toString()
    {
        $out = '<table align="center">'; //日历以表格形式打印
        $out .= $this->changeDate();       //调用内部私有方法用于用户自己设置日期
        $out .= $this->weeksList();       //调用内部私有方法打印“周”列表
        $out .= $this->daysList();        //调用内部私有方法打印“日”列表
        $out .= '</table>';               //表格结束
        return $out;                      //返回整个日历输出需要的全部字符串
    }

    /**
     * 输出周列表标题行
     */
    private function weeksList()
    {
        $week = array("日", "一", "二", "三", "四", "五", "六");
        $out = "<tr>";
        for ($i = 0; $i < count($week); $i++) {
            $out .= "<th class='fontb'>" . $week[$i] . "</th>";
        }
        $out .= "</tr>";
        return $out;
    }

    /**
     * 输出日历表
     */
    private function daysList()
    {
        $out = "<tr>";
        /**输出月日历前的空格*/
        for ($i = 0; $i < $this->monthStartWeekDay; $i++) {
            $out .= "<td> </td>";
        }

        /**输出当月日期;如果是当前日期则背景深色*/
        for ($j = 1; $j < $this->days; $j++) {
            $i++;
            if ($j == date("d")) {
                $out .= "<td class='fontb'>" . $j . "</td>";
            } else {
                $out .= "<td>" . $j . "</td>";
            }

            if ($i % 7 == 0) {
                $out .= "</tr><tr>";
            }
        }

        /**日历月份后的空格*/
        while ($i % 7 != 0) {
            $out .= "<td> </td>";
            $i++;
        }

        $out .= "</tr>";
        return $out;
    }


    /**上一年*/
    private function prevYear($year, $month)
    {
        $year = $year - 1;
        if ($year < 1970) {
            $year = 1970;
        }
        return "year={$year}&month={$month}";
    }


    /**上一个月*/
    private function prevMonth($year, $month)
    {
        if ($month == 1) {
            $year = $year - 1;
            if ($year < 1970) {
                $year = 1970;
                $month = 12;
            }
        } else {
            $month--;
        }
        return "year={$year}&month={$month}";
    }

    /**下一年*/
    private function nextYear($year, $month)
    {
        $year = $year + 1;
        if ($year > 2038) {
            $year = 2038;
        }
        return "year={$year}&month={$month}";
    }


    /**下一个月*/
    private function nextMonth($year, $month)
    {
        if ($month == 12) {
            $year = $year + 1;
            if ($year > 2038) {
                $year = 2038;
                $month = 12;
            }
        } else {
            $month++;
        }
        return "year={$year}&month={$month}";
    }

    /**
     * 调整年份和月份方法
     * @param string $url
     */
    private function changeDate($url = "index.php")
    {
        $out = '<tr>';
        $out .= '<td><a href="' . $url . '?' . $this->prevYear($this->year, $this->month) . '">' . '<<' . '</a></td>';
        $out .= '<td><a href="' . $url . '?' . $this->prevMonth($this->year, $this->month) . '">' . '<' . '</a></td>';

        $out .= '<td colspan="3">';
        $out .= '<form>';
        $out .= '<select name="year" onchange="window.location=\'' . $url . '?year=\'+this.options[selectedIndex].value+\'&month=' . $this->month . '\'">';
        for ($sy = 1970; $sy <= 2038; $sy++) {
            $selected = ($sy == $this->year) ? "selected" : "";
            $out .= '<option ' . $selected . ' value="' . $sy . '">' . $sy . '</option>';
        }
        $out .= '</select>';
        $out .= '<select name="month"  onchange="window.location=\'' . $url . '?year=' . $this->year . '&month=\'+this.options[selectedIndex].value">';
        for ($sm = 1; $sm <= 12; $sm++) {
            $selected1 = ($sm == $this->month) ? "selected" : "";
            $out .= '<option ' . $selected1 . ' value="' . $sm . '">' . $sm . '</option>';
        }
        $out .= '</select>';
        $out .= '</form>';
        $out .= '</td>';

        $out .= '<td><a href="' . $url . '?' . $this->nextYear($this->year, $this->month) . '">' . '>>' . '</a></td>';
        $out .= '<td><a href="' . $url . '?' . $this->nextMonth($this->year, $this->month) . '">' . '>' . '</a></td>';
        $out .= '</tr>';
        return $out; //返回调整日期的表单

    }
}

  

测试文件:

<html>
   <head>
      <title>日历</title>
      <style>
         table { border:1px solid #050;}            /*给表格加一个外边框*/
         .fontb { color:white; background:blue;}    /*设置周列表的背景和字体颜色*/
         th { width:30px;}                          /*设置单元格子的宽度*/
         td,th { height:30px;text-align:center;}    /*设置单元高度,和字段显示位置*/
         form { margin:0px;padding:0px; }           /*清除表单原有的样式*/
      </style>
   </head>
   <body>
      <?php
         require "Calendar.class.php";    //加载日历类
         echo  new Calendar;                 //直接输出日历对象,自动调用魔术方法__toString()打印日历
      ?>
   </body>
</html>

  



posted @ 2018-05-09 20:13  rask  阅读(390)  评论(0编辑  收藏  举报