Skip to content

Instantly share code, notes, and snippets.

@mikemix
Created January 9, 2014 22:00
Show Gist options
  • Save mikemix/8342861 to your computer and use it in GitHub Desktop.
Save mikemix/8342861 to your computer and use it in GitHub Desktop.
Job interview task solved: day of week calculation
<?php
interface ImaginaryCalendarFinderInterface
{
/**
* @param int $year
* @param int $month
* @param int $day
* @return int
*/
public function dayOfTheWeek($year, $month, $day);
}
<?php
interface ImaginaryCalendarInterface
{
/**
* Get the name of the $day.
*
* @return string
*/
public function getDayName($day);
/**
* Get days of the week array.
*
* @return array
*/
public function getDaysOfTheWeek();
/**
* Return is $year a leap year.
*
* @param int $year
* @return bool
*/
public function isLeapYear($year);
/**
* Return number of days in the given $month.
*
* @param int $month
* @param int $days
* @return int Days in given $month due to leap year
*/
public function getDaysInMonthOfLeapYear($month, $days);
/**
* Return months and number of days for each month as an array.
* Example output:
* [1] => 30, [2] => 27, [3] => 31, ...
*
* @return array
*/
public function getMonthsAndDaysCount();
}
<?php
function __autoload($name)
{
require __DIR__ . DIRECTORY_SEPARATOR . $name . '.php';
}
$calendar=new MyImaginaryCalendar();
$finder=new MyCalendarFinder($calendar);
$dayNumber=$finder->dayOfTheWeek(2013, 11, 17);
printf('Hooray, got %s', $calendar->getDayName($dayNumber));
<?php
class MyCalendarFinder implements ImaginaryCalendarFinderInterface
{
/** @var ImaginaryCalendarInterface */
protected $calendar;
/** @param ImaginaryCalendarInterface $calendar */
public function __construct(ImaginaryCalendarInterface $calendar)
{
$this->calendar=$calendar;
}
/**
* @param int $year
* @param int $month
* @param int $day
* @return int
*/
public function dayOfTheWeek($year, $month, $day)
{
// get the blueprints
$daysInWeek = $this->calendar->getDaysOfTheWeek();
$months = $this->calendar->getMonthsAndDaysCount();
// first current day is the first day of the week
$currentDayOfTheWeek = array_keys($daysInWeek)[0];
$firstDayOfTheWeek = $currentDayOfTheWeek;
$lastDayOfTheWeek = array_keys($daysInWeek)[count($daysInWeek)-1];
// go each year
for ($iYear=0; $iYear <= $year; $iYear++) {
// each month
foreach ($months as $iMonth => $iMonthDays) {
// if leap year modify day count
if ($this->calendar->isLeapYear($iYear)) {
$iMonthDays=$this->calendar->getDaysInMonthOfLeapYear($iMonth, $iMonthDays);
}
// each day of the month
for ($iDay=1; $iDay <= $iMonthDays; $iDay++) {
// if method is satisfied
if ($year == $iYear && $month == $iMonth && $day == $iDay) {
return $currentDayOfTheWeek;
}
// move to the next day of the week
if ($currentDayOfTheWeek === $lastDayOfTheWeek) {
$currentDayOfTheWeek = $firstDayOfTheWeek;
} else {
++$currentDayOfTheWeek;
}
}
}
}
throw new Exception('Loop seems invalid');
}
}
<?php
class MyImaginaryCalendar implements ImaginaryCalendarInterface
{
/**
* @return string
*/
public function getDayName($day)
{
return $this->getDaysOfTheWeek()[$day];
}
/**
* @return array
*/
public function getDaysOfTheWeek()
{
$dayIndexes=[1,2,3,4,5,6,7];
$dayNames=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'];
return array_combine($dayIndexes, $dayNames);
}
/**
* @return bool
*/
public function isLeapYear($year)
{
return $year % 5 == 0;
}
/**
* @return int
*/
public function getDaysInMonthOfLeapYear($month, $days)
{
if ($month == 13) {
return $days - 1;
}
return $days;
}
/*
* @return array
*/
public function getMonthsAndDaysCount()
{
$months=[1,2,3,4,5,6,7,8,9,10,11,12,13];
$days=[22,21,22,21,22,21,22,21,22,21,22,21,22];
return array_combine($months, $days);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment