一道面试题引发的思考 
                                                    
                        
                    
                    
  
                    
                    最近出了一个面试题,
给一个时间,获取这个月的结束的日期。比如 输入'2018-08-04' 输出'2018-08-31'
这个题目,相应如果熟悉php date 的应该很快能写出来。但是遇到一些求职者,可能没思考清楚,于是就开始编写了。
一个月的结束时间,只要知道这个月有多少天,就能知道最后一天是多少号了?但是这里你要思考的问题就有很多,因为月份有大小月份(1 3 5  7 8 10 12 则是大月有31天,其余的月份除了2月,都是小月,每个月有30天),你可能会忽略掉2月这个特殊的月份,因为2月又有29天和28天。假设你已经考虑到2月了,但是你又得需要考虑闰年了,闰年的规则你需要知道吧!
不考虑超大年的情况下的规则(按照历法 比如 3200 就不是闰年。有兴趣的可以查下资料)
普通年:能被4整除但不能被100整除的年份为普通闰年。(如2004年就是闰年,1999年不是闰年);
世纪年:能被400整除的为世纪闰年。(如2000年是闰年,1900年不是闰年);
于是有的求职者上来就写了一个这种代码
方法一
function monthDay($date) {
     $month31 = [1, 3, 5, 7, 8, 10, 12];
    list($year, $month) = explode('-',$date);
    if ($month != 2) {
        if (in_array($month, $month31)) {
            return "{$year}-{$month}-31";
        } else {
            return "{$year}-{$month}-30";
        }
    }
      if (  $year%4==0  && ($year%100!=0 ||  $year%400==0 ) ){
        return "{$year}-{$month}-29";
    }else{
        return "{$year}-{$month}-28";
    }
}方法二
方法一的代码看着没啥问题,但是可能是一种特别复杂的实现方式,它考虑的因素比较多。
我们可以换种思考的方式,这个月有多少天,我们知道一个月的开始时间和一个月的结束时间 两者相减,也是等于当月的天数。一月末正好是一个月的开始。而且每个月的开始时间是固定的,都是1号,不会变的。下一个月的月数等于当月+1。
但是有个特殊的情况,如果是年底,那么12月的下一月就是新的一年的1月。
function endDayOfMonth($date) {
    list($year, $month) = explode('-',$date);
    $nextYear = $year;
    $nexMonth = $month+1;
    //如果是年底12月 下个月就是1月
    if($month == 12) {
        $nexMonth = "01";
        $nextYear = $year+1;
    }
    $begin = "{$year}-{$month}-01 00:00:00";
    $end = "{$nextYear}-{$nexMonth}-01 00:00:00";
    $day = (strtotime($end) - strtotime($begin) )/ (24*60*60);
    return "{$year}-{$month}-{$day}";
}方法三
方法二的方法其实已经差不多接近了,但是还是可能不够特别好的。因为我们不需要算天数。我们知道新的一个月的第一天,减去一个1,就是当月的最后一秒。
function endDayOfMonth($date) {
    list($year, $month) = explode('-',$date);
    $nextYear = $year;
    $nexMonth = $month+1;
    //如果是年底12月 下个月就是1月
    if($month == 12) {
        $nexMonth = "01";
        $nextYear = $year+1;
    }
    $end = "{$nextYear}-{$nexMonth}-01 00:00:00";
    $endTimeStamp = strtotime($end) - 1 ;
    return date('Y-m-d',$endTimeStamp);
}PHP自带函数实现
其实php自带的有多种实现的方式,比如date、DateTime、strtotime等
- php date 函数格式化t指定月份的天数; 如: "28" 至 "31"$date = '2018-08-08'; echo date('Y-m-t',strtotime($date));
- strtotime 字符串时间修饰词last day of this month时间字符 类似我们常说的 -1 dayecho date('Y-m-d',strtotime("last day of this month",strtotime('2018-02-01'))); echo date('Y-m-d',strtotime("last day of 2018-02"));
- 
php DateTime类 面向对象方式 $date = new \DateTime('2000-02-01'); $date->modify('last day of this month'); echo $date->format('Y-m-d');
其实这题主要是我们常见的面试题演变的。主要是想看怎么考虑问题,很多的时候,我们陷入了一个误区里,考虑了复杂的实现,其实就是两个函数的使用,一个是 date 和 strtotime
求昨天的日期,strtotime('-1 day')
能使用date("Y-m-t") 的这种是最简单的,题目中没有提到不用内置函数,所以也考虑思考的方式,是否读了题目,就跟我们以前考试一样。做选择题,从下面选项选出不是的答案,我们看了第一个正确就选了。
想法很重要!
本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           xianyunyehe 的个人博客
 xianyunyehe 的个人博客
         
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
                     
                     
             
             
             
             
             
             
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: