终端 打印当月的日历 cal

Cal.php

index.php

仿照系统命令

* Cal.php

<?php
class Cal {
    /** @var DateTime */
    private $datetime;

    /** @var array */
    private static $monthDay = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    /** @var \SplFixedArray|null */
    private $model = null;

    const SPACE = " ";
    const EOL = "\n";

    public function __construct() {
        $this->datetime = new \DateTime();
        $this->model();
    }

    private function model() {
        $s = $this->datetime->format('Y-m-d N');
        list($year, $month, $date, $day) = sscanf($s, "%d-%d-%d %d");
        $firstDay = self::getFirstDayOfDate($date, $day);
        $model = new \SplFixedArray($firstDay + self::countMonthDay($year, $month));
        $i = 0;
        while ($i < $firstDay) {
            $model->offsetSet($i, 0);
            $i++;
        }
        for ($j = 1; $i < $model->count(); $i++, $j++) {
            $model->offsetSet($i, $j);
        }
        $this->model = $model;
    }

    public function getModel() {
        return $this->model;
    }

    public function render() {
        $this->renderTitle();
        printf(self::EOL);
        $this->renderDayOfWeeks();
        printf(self::EOL);
        $this->renderDate();
        printf(self::EOL);
    }

    private function renderTitle() {
        list($year, $month) = sscanf($this->datetime->format('Y-m'), "%d-%d");
        $monthOfYear = [ '', 'January', 'February', 'March', 'April', 'May', 'June',
            'July', 'August', 'September', 'October', 'November', 'December'];
        $sMonth = $monthOfYear[ $month ];
        $s = sprintf("%s%s%d", $sMonth, self::SPACE, $year);
        $padding = floor((20 - \strlen($s)) / 2);

        while ($padding-->0) {
            printf(self::SPACE);
        }
        printf($s);
    }

    private function renderDate() {
        $today = intval($this->datetime->format('d'));
        for ($i = 0; $i < $this->model->count(); $i++) {
            $cur = $this->model->offsetGet($i);
            if (0 === $cur) {
                printf("%2s%s", self::SPACE, self::SPACE);
                continue;
            }
            if ($today === $cur) {
                printf("\033[40m\033[37m%2d\033[0m", $cur);
            } else {
                printf("%2d", $cur);
            }
            if ($i % 7 < 6) {
                printf(" ");
            } else {
                printf(self::EOL);
            }
        }
    }

    private function renderDayOfWeeks() {
        $dow = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
        $sp = self::SPACE;
        array_walk($dow, function($el) use ($sp) {
            printf("%s%s", $el, $sp);
        });
    }

    /**
     * 这个月的第1天是星期几
     * @param $date int 1-31
     * @param $day int   0-7
     * @return int
     */
    public static function getFirstDayOfDate(int $date, int $day) {
        while (--$date > 0) {
            if (--$day < 0) {
                $day =  7 + $day;
            }
        }
        return $day;
    }

    public static function isLeapYear($year) {
        return ($year % 4 === 0 && $year % 100 !== 0) || ($year % 400===0);
    }

    public static function countMonthDay(int $year, int $month) {
        if ($month===2 && self::isLeapYear($year)) {
            return 29;
        }
        return self::$monthDay[$month];
    }
}

* index.php

<?php
/**
 * Created by PhpStorm.
 * User: Mch
 * Date: 10/13/18
 * Time: 2:02 PM
 */
function __autoload($className) {
    include $className.'.php';
}

$cal = new Cal();
$cal->render();

* test

php index.php

ansi终端颜色

https://www.linuxidc.com/Linux/2014-02/97148.htm

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/83038112