Home
PHP
Tech Tube
MySQL
Linux
CSS&HTML
JavaScript

PHP date and time class

This class contains some useful functions to help me deal with some common date and time calculations.
<?php

/**
 * This class will handle the work with date formats, time periods, intervals and other time related stuff.
 * @package Sami's date/time class
 * @version $Id: samis_date_time.class.php v.2.0 2017-03-15 18:30:00 $
 * @author Samuil Banti
 * @copyright (C) 2015 - Samuil Banti
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
class samis_date_handler {

    // Settings:
    private $display_notes = true; // Take a look at the constructor

    /**
    * @param boolean $display_notes - Set to false if you don't want the class to generate E_USER_NOTICE in case of incorrect data.
    */
    public function __construct($display_notes = true)
    {
	$this->display_notes = $display_notes;
    }

    /**
    * This function sets notes if the settings allows to and its false return value is used by other methods.
    * @param string $notice_message - The text of the notice message.
    */
    private function set_notice($notice_message)
    {
	if($this->display_notes) {
	    trigger_error($notice_message, E_USER_NOTICE);
	}
	return false;
    }

    /**
    * Split period to approximately equal periods for given number of dates.
    * Requires PHP v.4.0.1 or newer.
    * @param string $start_time - The start date and time of the period in format Y-m-d H:i:s (for example 2011-03-15).
    * @param string $end_time - The end date and time of the period in format Y-m-d H:i:s (for example 2011-03-15).
    * @param int $num_dates - Number of dates to split in the period.
    * @return array $dates - Array with dates on approximately same intervals of time in format Y-m-d H:i:s.
    */
    public function split_in_period($start_time, $end_time, $num_dates) 
    {
	$period_seconds = $this->get_period_seconds($start_time, $end_time);
	if(!$period_seconds) {
	    return false;
	} elseif($period_seconds < $num_dates) {
	    return $this->set_notice('The period is shorter than the number of dates!');
	}
	$interval = floor($period_seconds / $num_dates);
	$dates = array();
	$last_date = strtotime($start_time);
	for($i=0; $i<$num_dates; $i++) {
	    $dates[] = date('Y-m-d H:i:s', $last_date);
	    $last_date += $interval;
	}
	return $dates;
    }

    /**
    * Returns the number of seconds in a given period.
    * Requires PHP v.4.0.1 or newer.
    * @param string $start_time - The start date and time of the period in format Y-m-d H:i:s (for example 2011-03-15 00:00:00).
    * @param string $end_time - The end date and time of the period in format Y-m-d H:i:s (for example 2011-03-15 00:00:00).
    * @return int $period_seconds - The number of seconds in the given period.
    */
    public function get_period_seconds($start_time, $end_time)
    {
	$start_timestamp = strtotime($start_time);
	$end_timestamp = strtotime($end_time);
        if(!$start_timestamp || !$end_timestamp) {
            return $this->set_notice('One of the given dates is incorrect!');
        }
	$period_seconds = $end_timestamp - $start_timestamp;
	if($period_seconds <= 0) {
	    return $this->set_notice('The start date is before or equal to the end date!');
	}
	return $period_seconds;
    }
    
    /**
    * Gets the number of days between two dates.
    * Requires PHP v.4.0.1 or newer.
    * WARNING: This function is set to consider ranges like "2011-01-01 00:00:00" to "2011-01-02 00:00:00" as two days.
    * @param string $start_time - The start date and time of the period in format Y-m-d (for example 2011-03-15).
    * @param string $end_time - The end date and time of the period in format Y-m-d (for example 2011-03-15).
    * @return integer number of days on success OR false incase of incorrect data
    */
    public function get_range_in_days($start_time, $end_time) 
    {
	$period_seconds = $this->get_period_seconds($start_time, $end_time);
	if(!$period_seconds) {
	    return false;
	}
        $period_seconds += 1; // Add 1 to make sure that the first date of the period is includeded
        $days = $period_seconds / (60*60*24);
        return ceil($days);
    }
    
    /**
     * Takes two dates formatted as YYYY-MM-DD and creates an array of the dates between the from and to dates.
     * @param string $start_date - The start date of the period
     * @param string $end_date - The end date of the period
     * @return array $days - List of all dates in the period
     */
    public function create_date_range_array($start_date, $end_date)
    {
        $start_timestamp = strtotime($start_date);
        $end_timestamp = strtotime($end_date);
        if(!$start_timestamp || !$end_timestamp) {
            return $this->set_notice('One of the given dates is incorrect!');
        }
	$days = array();
	for ($i = $start_timestamp; $i <= $end_timestamp; $i = $i + 86400) {
	    $days[] = date('Y-m-d', $i);
	}
	return $days;
    }
    
    /**
     * Returns the time of a day in seconds for example 01:01:30 => 60*60+30
     * Useful for timers and countdowns
     * @param string $time - the hour of the day in format H:i:s
     * @return int - The numer of seconds until the given hour 
     */
    public function get_time_in_seconds($time) {
        $time = explode(':', $time);
        if(count($time)!=3) {
             return $this->set_notice('The time format should be described in format H:i:s (for example 01:01:30)!');
        }
        return ($time[0]*60*60)+($time[1]*60)+$time[2];
    }
    
    /**
     * Converts seconds to hours, minutes, seconds, miliseconds
     * NOTE to have conversion to miliseconds the format should be 14.34
     * @param int $interval - Number of seconds
     * @return array - Array with the numer of hours, minutes, seconds, miliseconds
     */
    public function convert_time_by_seconds($interval) { 
        if($interval < 0) {
            return array('h' => 0, 'm' => 0, 's' => 0);
        }
        $seconds_n_miliseconds = explode('.', $interval);
        $interval = $seconds_n_miliseconds[0];
        
        $hours = floor($interval / (60*60));
        $minutes = floor(($interval - ($hours*60*60)) / 60);
        $seconds = floor(($interval - ($hours*60*60)) - ($minutes*60));
        $ms = empty($seconds_n_miliseconds[1]) ? 0 : $seconds_n_miliseconds[1];
        return array('h' => $hours, 'm' => $minutes, 's' => $seconds, 'ms' => $ms);
    }
    
    /**
     * Calculates how much time is left to a given date
     * @param string $datetime - date and time of the countdown end in format "Y-m-d H:i:s"
     * @return array - The time left in hours, minutes and seconds
     */
    public function time_left($datetime) {
        $stime = strtotime($datetime);
        if(empty($stime)) {
            return array('h' => 0, 'm' => 0, 's' => 0);
        }
        $interval = $stime - time();
        return $this->convert_time_by_seconds($interval);
    }
    
    /**
     * Checks if the given date is existing
     * @param sting $date - the date in format "Y-m-d"
     * @return boolean true if the date exists, false otherwise
     */
    public function is_existing_date($date)
    {
        $date = substr($date, 0, 10);
        $date = explode('-', $date);
        if(count($date)!=3) {
            return false;
        }
        if(checkdate($date[1], $date[2], $date[0])) {
            return true;
        }
        return false;
    }
    
    /**
     * Converts time from one timezone to another
     * NOTE: Requires PHP version 5.1.0 or later
     * NOTE: the time is expected in format "Y-m-d H:i:s"
     * @param string $date_time - the date and time in format "Y-m-d H:i:s"
     * @param string $timezone_from - the timezone to convert from in format "Europe/Sofia"
     * @param string $timezone_to - the timezone to convert to in format "Europe/Amsterdam"
     * @return string The time in the given destination in format "Y-m-d H:i:s"
     */
    public function convert_to_timezone($date_time, $timezone_from, $timezone_to)
    {
        $current_timezone = date_default_timezone_get();
        date_default_timezone_set($timezone_from);
        $date_time = strtotime($date_time);
        date_default_timezone_set($timezone_to);
        $date_time = date('Y-m-d H:i:s', $date_time);
        date_default_timezone_set($current_timezone);
        return $date_time;
    }
    
    /**
    * Calculates the age by a given birthdate.
    * NOTE: Requires PHP version 5.3.0 or later.
    * @param string $birth_date - the birthdate in fomrat Y-m-d.
    * @return array $age an array with the reached age in years, months and days.
    */
    public function calculate_age($birth_date)
    {
	$date_diff = date_diff(date_create($birth_date), date_create('now'));
	$age = array();
	$age['years'] = $date_diff->y;
	$age['months'] = $date_diff->m;
	$age['days'] = $date_diff->d;
	return $age;
    }

    /**
    * Generate callendar like table.
    * @param int $month - The number of the month.
    * @param int $year - The year.
    * @param array $days_order - The order of the days in the week.
    * @param array $holydays - Aditional days of.
    * @param string $holidays_class - The CSS class for the holidays.
    * @param string $today_class - The CSS class for the current day.
    */
    public function get_month_calendar($month, $year, $days_order = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'), $holydays=array(), $holidays_class='holyday', $today_class='today') 
    {
	$days = array();
	$num_days = cal_days_in_month(CAL_GREGORIAN, $month, $year);
	
	for($i=0; $num_days > $i; ++$i) {
	    $day = $i+1;
	    $day_name = date('D', strtotime($year.'-'.$month.'-'.$day));
	    if(!array_key_exists($day_name, $days)) {
		$days[$day_name] = array();
	    }
	    $days[$day_name][] = $day;
	}
	
	$day = 1;
	$html = '<table>';
	for($i=0; 6 > $i; ++$i) {
	    $html .= '<tr>';
	    foreach($days_order as $day_name) {
		$current_day_name = date('D', strtotime($year.'-'.$month.'-'.$day));
		if($day_name == $current_day_name && $day <= $num_days) {
		    if((int)date('d') == $day) {
			$class = $today_class;
		    } elseif(in_array($day, $holydays) || $day_name == 'Sat' || $day_name == 'Sun') {
			$class = $holidays_class;
		    } else {
			$class = '';
		    }
		    $html .= '<td class="'.$class.'">'.$day.'</td>';
		    ++$day;
		} else {
		    $html .= '<td> </td>';
		}
	    }
	    $html .= '</tr>';
	}
	$html .= '</table>';
	return $html;
    }
 
}
Download...