终端 打印当月的日历 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