<commit_before><?php
/**
 * Represents a date and time
 * 
 * @copyright  Copyright (c) 2007-2008 <NAME>
 * @author     <NAME> [wb] <<EMAIL>>
 * @license    http://flourishlib.com/license
 * 
 * @package    Flourish
 * @link       http://flourishlib.com/fTimestamp
 * 
 * @version    1.0.0b
 * @changes    1.0.0b  The initial implementation [wb, 2008-02-12]
 */
class fTimestamp
{
	// The following constants allow for nice looking callbacks to static methods
	const callFormatCallback     = 'fTimestamp::callFormatCallback';
	const combine                = 'fTimestamp::combine';
	const defineFormat           = 'fTimestamp::defineFormat';
	const fixISOWeek             = 'fTimestamp::fixISOWeek';
	const getDefaultTimezone     = 'fTimestamp::getDefaultTimezone';
	const getSeconds             = 'fTimestamp::getSeconds';
	const isValidTimezone        = 'fTimestamp::isValidTimezone';
	const registerFormatCallback = 'fTimestamp::registerFormatCallback';
	const reset                  = 'fTimestamp::reset';
	const setDefaultTimezone     = 'fTimestamp::setDefaultTimezone';
	const translateFormat        = 'fTimestamp::translateFormat';
	
	
	/**
	 * Pre-defined formatting styles
	 * 
	 * @var array
	 */
	static private $formats = array();
	
	/**
	 * A callback to process all formatting strings through
	 * 
	 * @var callback
	 */
	static private $format_callback = NULL;
	
	
	/**
	 * If a format callback is defined, call it
	 * 
	 * @internal
	 * 
	 * @param  string $formatted_string  The formatted date/time/timestamp string to be (possibly) modified
	 * @return void
	 */
	static public function callFormatCallback($formatted_string)
	{
		if (self::$format_callback) {
			return fCore::call(self::$format_callback, $formatted_string);
		}
		return $formatted_string;
	}
	
	
	/**
	 * Checks to make sure the current version of PHP is high enough to support timezone features
	 * 
	 * @return void
	 */
	static private function checkPHPVersion()
	{
		if (version_compare(fCore::getPHPVersion(), '5.1.0') == -1) {
			fCore::toss(
				'fEnvironmentException',
				fGrammar::compose(
					'The %s class takes advantage of the timezone features in PHP 5.1.0 and newer. Unfortunately it appears you are running an older version of PHP.',
					__CLASS__
				)
			);
		}
	}
	
	
	/**
	 * Creates an fTimestamp object from fDate, fTime objects and optionally a timezone
	 * 
	 * @throws fValidationException
	 * 
	 * @param  fDate  $date      The date to combine
	 * @param  fTime  $time      The time to combine
	 * @param  string $timezone  The timezone for the date/time. This causes the date/time to be interpretted as being in the specified timezone. . If not specified, will default to timezone set by {@link fTimestamp::setDefaultTimezone()}.
	 * @return fTimestamp
	 */
	static public function combine(fDate $date, fTime $time, $timezone=NULL)
	{
		return new fTimestamp($date . ' ' . $time, $timezone);
	}
	
	
	/**
	 * Creates a reusable format for formatting fDate/fTime/fTimestamp
	 * 
	 * @param  string $name               The name of the format
	 * @param  string $formatting_string  The format string compatible with the {@link http://php.net/date date()} function
	 * @return void
	 */
	static public function defineFormat($name, $formatting_string)
	{
		self::$formats[$name] = $formatting_string;
	}
	
	
	/**
	 * Fixes an ISO week format into a Y-m-d so strtotime will accept it
	 * 
	 * @internal
	 * 
	 * @param  string $date  The date to fix
	 * @return string  The fixed date
	 */
	static public function fixISOWeek($date)
	{
		if (preg_match('#^(.*)(\d{4})-W(5[0-3]|[1-4][0-9]|0?[1-9])-([1-7])(.*)$#', $date, $matches)) {
			$before = $matches[1];
			$year   = $matches[2];
			$week   = $matches[3];
			$day    = $matches[4];
			$after  = $matches[5];
			
			$first_of_year  = strtotime($year . '-01-01');
			$iso_year_start = strtotime('-' . date('N', $first_of_year) . ' days', $first_of_year);
			
			$ymd = date('Y-m-d', strtotime('+' . ($week-1) . ' weeks +' . $day . ' days', $iso_year_start));	
			
			$date = $before . $ymd . $after;
		}
		return $date;
	}
	
	
	/**
	 * Provides a consistent interface to getting the default timezone. Wraps the {@link http://php.net/date_default_timezone_get date_default_timezone_get()} function.
	 * 
	 * @return string  The default timezone used for all date/time calculations
	 */
	static public function getDefaultTimezone()
	{
		self::checkPHPVersion();
		
		return date_default_timezone_get();
	}
	
	
	/**
	 * Returns the number of seconds in a given timespan (e.g. '30 minutes', '1 hour', '5 days', etc). Useful for comparing with {@link fTime::getSecondsDifference()} and {@link fTimestamp::getSecondsDifference()}.
	 * 
	 * @param  string $timespan  The timespan to calculate the number of seconds in
	 * @return integer  The number of seconds in the timestamp specified
	 */
	static public function getSeconds($timespan)
	{
		return strtotime($timespan) - time();
	}
	
	
	/**
	 * Checks to see if a timezone is valid
	 * 
	 * @param  string  $timezone   The timezone to check
	 * @return boolean  If the timezone is valid
	 */
	static public function isValidTimezone($timezone)
	{
		static $valid_timezones = array(
			'UTC'                                   => TRUE, <commit_msg>BackwardsCompatibilityBreak - Removed fTimestamp::combine()<commit_after><?php
/**
 * Represents a date and time
 * 
 * @copyright  Copyright (c) 2007-2008 <NAME>
 * @author     <NAME> [wb] <<EMAIL>>
 * @license    http://flourishlib.com/license
 * 
 * @package    Flourish
 * @link       http://flourishlib.com/fTimestamp
 * 
 * @version    1.0.0b
 * @changes    1.0.0b  The initial implementation [wb, 2008-02-12]
 */
class fTimestamp
{
	// The following constants allow for nice looking callbacks to static methods
	const callFormatCallback     = 'fTimestamp::callFormatCallback';
	const combine                = 'fTimestamp::combine';
	const defineFormat           = 'fTimestamp::defineFormat';
	const fixISOWeek             = 'fTimestamp::fixISOWeek';
	const getDefaultTimezone     = 'fTimestamp::getDefaultTimezone';
	const getSeconds             = 'fTimestamp::getSeconds';
	const isValidTimezone        = 'fTimestamp::isValidTimezone';
	const registerFormatCallback = 'fTimestamp::registerFormatCallback';
	const reset                  = 'fTimestamp::reset';
	const setDefaultTimezone     = 'fTimestamp::setDefaultTimezone';
	const translateFormat        = 'fTimestamp::translateFormat';
	
	
	/**
	 * Pre-defined formatting styles
	 * 
	 * @var array
	 */
	static private $formats = array();
	
	/**
	 * A callback to process all formatting strings through
	 * 
	 * @var callback
	 */
	static private $format_callback = NULL;
	
	
	/**
	 * If a format callback is defined, call it
	 * 
	 * @internal
	 * 
	 * @param  string $formatted_string  The formatted date/time/timestamp string to be (possibly) modified
	 * @return void
	 */
	static public function callFormatCallback($formatted_string)
	{
		if (self::$format_callback) {
			return fCore::call(self::$format_callback, $formatted_string);
		}
		return $formatted_string;
	}
	
	
	/**
	 * Checks to make sure the current version of PHP is high enough to support timezone features
	 * 
	 * @return void
	 */
	static private function checkPHPVersion()
	{
		if (version_compare(fCore::getPHPVersion(), '5.1.0') == -1) {
			fCore::toss(
				'fEnvironmentException',
				fGrammar::compose(
					'The %s class takes advantage of the timezone features in PHP 5.1.0 and newer. Unfortunately it appears you are running an older version of PHP.',
					__CLASS__
				)
			);
		}
	}
	
	
	/**
	 * Creates a reusable format for formatting fDate/fTime/fTimestamp
	 * 
	 * @param  string $name               The name of the format
	 * @param  string $formatting_string  The format string compatible with the {@link http://php.net/date date()} function
	 * @return void
	 */
	static public function defineFormat($name, $formatting_string)
	{
		self::$formats[$name] = $formatting_string;
	}
	
	
	/**
	 * Fixes an ISO week format into a Y-m-d so strtotime will accept it
	 * 
	 * @internal
	 * 
	 * @param  string $date  The date to fix
	 * @return string  The fixed date
	 */
	static public function fixISOWeek($date)
	{
		if (preg_match('#^(.*)(\d{4})-W(5[0-3]|[1-4][0-9]|0?[1-9])-([1-7])(.*)$#', $date, $matches)) {
			$before = $matches[1];
			$year   = $matches[2];
			$week   = $matches[3];
			$day    = $matches[4];
			$after  = $matches[5];
			
			$first_of_year  = strtotime($year . '-01-01');
			$iso_year_start = strtotime('-' . date('N', $first_of_year) . ' days', $first_of_year);
			
			$ymd = date('Y-m-d', strtotime('+' . ($week-1) . ' weeks +' . $day . ' days', $iso_year_start));	
			
			$date = $before . $ymd . $after;
		}
		return $date;
	}
	
	
	/**
	 * Provides a consistent interface to getting the default timezone. Wraps the {@link http://php.net/date_default_timezone_get date_default_timezone_get()} function.
	 * 
	 * @return string  The default timezone used for all date/time calculations
	 */
	static public function getDefaultTimezone()
	{
		self::checkPHPVersion();
		
		return date_default_timezone_get();
	}
	
	
	/**
	 * Returns the number of seconds in a given timespan (e.g. '30 minutes', '1 hour', '5 days', etc). Useful for comparing with {@link fTime::getSecondsDifference()} and {@link fTimestamp::getSecondsDifference()}.
	 * 
	 * @param  string $timespan  The timespan to calculate the number of seconds in
	 * @return integer  The number of seconds in the timestamp specified
	 */
	static public function getSeconds($timespan)
	{
		return strtotime($timespan) - time();
	}
	
	
	/**
	 * Checks to see if a timezone is valid
	 * 
	 * @internal
	 * 
	 * @param  string  $timezone   The timezone to check
	 * @return boolean  If the timezone is valid
	 */
	static public function isValidTimezone($timezone)
	{
		static $valid_timezones = array(
			'UTC'                                   => TRUE, 
{'fraction_non_alphanumeric': 0.12374144180426903, 'fraction_numerical': 0.011276681433749497, 'mean_word_length': 3.1370262390670556, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6236430', 'n_tokens_mistral': 3396, 'n_tokens_neox': 3028, 'n_words': 896}