$format = apply_filters( 'em_datetime_format_default', $format, $include_hour ); return $this->i18n( $format ); } /** * Provides a translated date and time according to the current blog language. * Useful if using formats that provide date-related names such as 'Monday' or 'January', which should be translated if displayed in another language. * @param string $format * @return string */ public function i18n( $format = 'Y-m-d H:i:s' ){ if( !$this->valid && $format == em_get_date_format()) return ''; // since we use WP's date functions which don't use DateTime (and if so, don't inherit our timezones), we need to preformat timezone related formats, adapted from date_i18n $format = $this->formatTimezones( $format ); // support for < WP 5.3.0 if( function_exists('wp_date') ){ return wp_date( $format, $this->getTimestamp(), $this->getTimezone() ); }else{ return date_i18n( $format, $this->getTimestampWithOffset(true) ); } } /** * Outputs a default mysql datetime formatted string. * @return string */ public function __toString(){ return $this->format('Y-m-d H:i:s'); } /** * Modifies the time of this object, if a mysql TIME valid format is provided (e.g. 14:30:00). * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * @param string $hour * @return EM_DateTime Returns object for chaining. */ public function setTimeString( $hour ){ if( preg_match('/^\d{2}:\d{2}:\d{2}$/', $hour) ){ $time = explode(':', $hour); $this->setTime($time[0], $time[1], $time[2]); }else{ $this->valid = false; } return $this; } #[\ReturnTypeWillChange] /** * Sets timestamp and returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * @param int $timestamp * @see DateTime::setTimestamp() * @return EM_DateTime */ public function setTimestamp( $timestamp ){ $return = parent::setTimestamp( $timestamp ); $this->valid = $return !== false; return $this; } #[\ReturnTypeWillChange] /** * Extends DateTime functionality by accepting a false or string value for a timezone. If set to false, default WP timezone will be used. * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * @param string|false $timezone * @see DateTime::setTimezone() * @return EM_DateTime Returns object for chaining. */ public function setTimezone( $timezone = false ){ if( $timezone == $this->getTimezone()->getName() ) return $this; $timezone = EM_DateTimeZone::create($timezone); $return = parent::setTimezone($timezone); $this->timezone_name = $timezone->getName(); $this->timezone_utc = $timezone->utc_offset !== false; $this->valid = $this->valid && $return !== false; // only ever valid if previously valid return $this; } #[\ReturnTypeWillChange] /** * Sets time along and returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * {@inheritDoc} * @see DateTime::setTime() */ public function setTime( $hour, $minute, $second = NULL, $microseconds = NULL ){ $return = parent::setTime( (int) $hour, (int) $minute, (int) $second ); $this->valid = $return !== false; return $this; } #[\ReturnTypeWillChange] /** * Sets date along and returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * {@inheritDoc} * @see DateTime::setDate() */ public function setDate( $year, $month, $day ){ $return = parent::setDate( $year, $month, $day ); $this->valid = $return !== false; return $this; } #[\ReturnTypeWillChange] /** * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * {@inheritDoc} * @see DateTime::setISODate() */ public function setISODate( $year, $week, $day = NULL ){ $return = parent::setISODate( $year, $week, $day ); $this->valid = $return !== false; return $this; } #[\ReturnTypeWillChange] /** * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * {@inheritDoc} * @see DateTime::modify() */ public function modify( $modify ){ $result = parent::modify($modify); $this->valid = $result !== false; return $this; } #[\ReturnTypeWillChange] /** * Extends DateTime function to allow string representation of argument passed to create a new DateInterval object. * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * @see DateTime::add() * @param string|DateInterval $DateInterval * @return EM_DateTime Returns object for chaining. * @throws Exception */ public function add( $DateInterval ){ if( is_object($DateInterval) ){ $result = parent::add($DateInterval); }else{ $result = parent::add( new DateInterval($DateInterval) ); } $this->valid = $result !== false; return $this; } #[\ReturnTypeWillChange] /** * Extends DateTime function to allow string representation of argument passed to create a new DateInterval object. * Returns EM_DateTime object in all cases, but $this->valid will be set to false if unsuccessful * @see DateTime::sub() * @param string|DateInterval $DateInterval * @return EM_DateTime * @throws Exception */ public function sub( $DateInterval ){ if( is_object($DateInterval) ){ $result = parent::sub($DateInterval); }else{ $result = parent::sub( new DateInterval($DateInterval) ); } $this->valid = $result !== false; return $this; } /** * @return EM_DateTime * @throws Exception */ public function setStartOfWeek(){ $day = $this->format('w'); $start_of_week = get_option('start_of_week'); $offset = $day - $start_of_week; if( $offset<0) { $offset += 7; } if( $offset > 0 ) { $this->sub( 'P' . $offset . 'D' ); } return $this; } /** * Easy chainable cloning function, useful for situations where you may want to manipulate the current date, * such as adding a month and getting the DATETIME string without changing the original value of this object. * @return EM_DateTime */ public function copy(){ return clone $this; } /** * Gets a timestamp with an offset, which will represent the local time equivalent in UTC time. * If using this to supply to a date() function, set $server_localized to true which will account for any rogue code * that sets the server default timezone to something other than UTC (which is WP sets it to at the start) * @param boolean $server_localized * @return int */ public function getTimestampWithOffset( $server_localized = false ){ //aside from the actual offset from the timezone, we also have a local server offset we need to deal with here... $server_offset = $server_localized ? date('Z',$this->getTimestamp()) : 0; return $this->getOffset() + $this->getTimestamp() - $server_offset; } #[\ReturnTypeWillChange] /** * Returns an EM_DateTimeZone object instead of the default DateTimeZone object. * @see DateTime::getTimezone() * @return EM_DateTimeZone */ public function getTimezone(){ return new EM_DateTimeZone($this->timezone_name); } /** * Returns a MySQL TIME formatted string, with the option of providing the UTC equivalent. * @param bool $utc If set to true a UTC relative time will be provided. * @return string */ public function getTime( $utc = false ){ if( $utc ){ $current_timezone = $this->getTimezone()->getName(); $this->setTimezone('UTC'); } $return = $this->format('H:i:s'); if( $utc ) $this->setTimezone($current_timezone); return $return; } /** * Returns a MySQL DATE formatted string. * @param bool $utc * @return string */ public function getDate( $utc = false ){ return $this->format('Y-m-d'); } /** * Returns a MySQL DATETIME formatted string, with the option of providing the UTC equivalent. * @param bool $utc If set to true a UTC relative time will be provided. * @return string */ public function getDateTime( $utc = false ){ if( $utc ){ $current_timezone = $this->getTimezone()->getName(); $this->setTimezone('UTC'); } $return = $this->format('Y-m-d H:i:s'); if( $utc ) $this->setTimezone($current_timezone); return $return; } #[\ReturnTypeWillChange] /** * Extends the DateTime::createFromFormat() function by setting the timezone to the default blog timezone if none is provided. * @param string $format * @param string $time * @param string|EM_DateTimeZone $timezone * @return false|EM_DateTime */ public static function createFromFormat( $format, $time, $timezone = null ){ $timezone = EM_DateTimeZone::create($timezone); $DateTime = parent::createFromFormat($format, $time, $timezone); if( $DateTime === false ) return false; return new EM_DateTime($DateTime->format('Y-m-d H:i:s'), $timezone); } /** * Gets a set of start/end dates for the relative week of this $EM_DateTime, until the day before the starting weekday as per WP Settings. * * Accepts two scopes for $scope, both which calculate relative dates until the day before next start day of week.: * 'this-week' - events for the rest of the week starting 'today' * 'week' - events from start of relative week since previous start day of week * * @param string $scope * @return string[] */ public function get_week_dates( $scope = 'week' ) { $start_of_week = get_option('start_of_week'); $days_of_week = array( 0 => 'Sunday', 1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday'); $EM_DateTime = $this->copy(); // so we don't modify this $EM_DateTime $today_day_of_week = $EM_DateTime->format('w'); $end_of_week = $start_of_week > 0 ? $start_of_week-1 : 6; $end_of_week_name = $days_of_week[$end_of_week]; // get stat date, either today if it's start of week or 'this-week' scope, or the previous start day of week if( $scope == 'this-week' || $today_day_of_week == $start_of_week ){ $start_date = $EM_DateTime->getDate(); }else{ $start_of_week_name = $days_of_week[$start_of_week]; $start_date = $EM_DateTime->modify('last '. $start_of_week_name)->getDate(); } $end_date = $start_date; // set as today in event it's the last day of week if( $scope == 'week' || $today_day_of_week != $end_of_week ){ // if we're looking for whole week, $EM_DateTime is set to start of week, so get relative end of week even if it's today $end_date = $EM_DateTime->modify('next '. $end_of_week_name)->getDate(); } return array($start_date, $end_date); } }