A calendar written with IntlCalendar class

Code
<?php

// Berlin - Germany
$c IntlCalendar::createInstance('Europe/Berlin''de_DE');
$renderer = new CalendarMonthRenderer(new IntlDateFormatter('de_DE'nullnull));
echo 
$renderer->render(new CalendarMonth($c));

// USA - New York
$c IntlCalendar::createInstance('America/New_York''en_US');
$renderer = new CalendarMonthRenderer(new IntlDateFormatter('en_US'nullnull));
echo 
$renderer->render(new CalendarMonth($c));


/**
 * This code snippet is no copy and paste example. It has no error
 * handling and isn't generic or clean written enough to be used in 
 * production.
 */
class CalendarMonth
{
    private 
$calendar;
    private 
$now;
    
    const 
DAY IntlCalendar::FIELD_DATE;
    const 
MONTH IntlCalendar::FIELD_MONTH;
    const 
DOW_LOCAL IntlCalendar::FIELD_DOW_LOCAL;
    
    public function 
__construct(IntlCalendar $calendar)
    {
        
$this->calendar $calendar;
        
$this->now $calendar->getTime();
    }
    
    public function 
getNow()
    {
        return 
$this->now;
    }
    
    public function 
createStructure()
    {
        
$calendar $this->calendar;
        
        
// beginning of the week
        
$calendar->set(self::DAY$calendar->getMinimum(self::DAY));
        
$dayOfWeek $calendar->get(self::DOW_LOCAL);
        
$month $calendar->get(self::MONTH);
        
$calendar->add(self::DAY, -($dayOfWeek 1));

        
$structure = [];
        
$week = [];
        while (
$calendar->get(self::MONTH) <= $month || 
            !
$this->isNewWeek($calendar)
        ) {
            if (
$this->isNewWeek($calendar)) {
                
$week = [];
            }
            
            
$week[] = $calendar->getTime();
            
            if (
$this->isEndOfWeek($calendar)) {
                
$structure[] = $week;
                if (
$calendar->get(self::MONTH) != $month) {
                    break;
                }
            }
            
            
$calendar->add(self::DAY1);
        }
        
        return 
$structure;
    }
    
    private function 
isNewWeek(IntlCalendar $c)
    {
        return 
=== $c->get(self::DOW_LOCAL);
    }
    
    private function 
isEndOfWeek(IntlCalendar $c)
    {
        return 
=== $c->get(self::DOW_LOCAL);
    }
}

class 
CalendarMonthRenderer
{
    private 
$formatter;
    
    public function 
__construct(IntlDateFormatter $formatter)
    {
        
$this->formatter $formatter;
    }
    
    public function 
render(CalendarMonth $calendar)
    {
        
$days $weekdays '';
        foreach (
$calendar->createStructure() as $pos => $week) {
            
$days .= '<tr>';
            foreach(
$week as $day) {
                if (
=== $pos) {
                    
$weekdays .= '<td>' $this->format($day 1000'E') . '</td>';
                }
            
                
$days .= '<td align="right">' $this->format($day 1000'd') . '</td>';
            }
            
$days .= '</tr>';
        }
        
        
$caption '<caption>' $this->format($calendar->getNow() / 1000'LLLL') . '</caption>';
        
        return 
'<table border="1">' $caption '<tr>' $weekdays '</tr>' $days '</table>';
    }
    
    private function 
format($c$format)
    {
        
$this->formatter->setPattern($format);
        return 
$this->formatter->format($c);
    }
}
Result
Dezember
Mo.Di.Mi.Do.Fr.Sa.So.
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
December
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
Used Versions
PHP 7.1, Zend 3.0, Symfony 3.2, Laravel 5.2, PHPUnit 5.6, Doctrine 2.6