Exemplo n.º 1
0
 /**
  * convert timestamp to date array, default UTC or adjusted for offset/timezone
  *
  * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**>
  * @since 2.15.1 - 2012-10-17
  * @param mixed   $timestamp
  * @param int     $parno
  * @param string  $wtz
  * @return array
  */
 public static function _timestamp2date($timestamp, $parno = 6, $wtz = null)
 {
     if (is_array($timestamp)) {
         $tz = isset($timestamp['tz']) ? $timestamp['tz'] : $wtz;
         $timestamp = $timestamp['timestamp'];
     }
     $tz = isset($tz) ? $tz : $wtz;
     if (empty($tz) || 'Z' == $tz || 'GMT' == strtoupper($tz)) {
         $tz = 'UTC';
     } elseif (iCalUtilityFunctions::_isOffset($tz)) {
         $offset = iCalUtilityFunctions::_tz2offset($tz);
         $tz = 'UTC';
     }
     try {
         $d = new DateTime("@{$timestamp}");
         // set UTC date
         if (isset($offset) && 0 != $offset) {
             // adjust for offset
             $d->modify($offset . ' seconds');
         } elseif ('UTC' != $tz) {
             $d->setTimezone(new DateTimeZone($tz));
         }
         // convert to local date
         $date = $d->format('Y-m-d-H-i-s');
         unset($d);
     } catch (Exception $e) {
         $date = date('Y-m-d-H-i-s', $timestamp);
     }
     $date = explode('-', $date);
     $output = array('year' => $date[0], 'month' => $date[1], 'day' => $date[2]);
     if (3 != $parno) {
         $output['hour'] = $date[3];
         $output['min'] = $date[4];
         $output['sec'] = $date[5];
         if ('UTC' == $tz && (!isset($offset) || 0 == $offset)) {
             $output['tz'] = 'Z';
         }
     }
     return $output;
 }
 /**
  * (very simple) conversion of a MS timezone to a PHP5 valid (Date-)timezone
  * matching (MS) UCT offset and time zone descriptors
  *
  * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**>
  * @since 2.10.29 - 2012-01-11
  * @param string $timezone, input/output variable reference
  * @return bool
  */
 public static function ms2phpTZ(&$timezone)
 {
     if (!class_exists('DateTimeZone')) {
         return FALSE;
     }
     if (empty($timezone)) {
         return FALSE;
     }
     $search = str_replace('"', '', $timezone);
     $search = str_replace(array('GMT', 'gmt', 'utc'), 'UTC', $search);
     if ('(UTC' != substr($search, 0, 4)) {
         return FALSE;
     }
     if (FALSE === ($pos = strpos($search, ')'))) {
         return FALSE;
     }
     $pos = strpos($search, ')');
     $searchOffset = substr($search, 4, $pos - 4);
     $searchOffset = iCalUtilityFunctions::_tz2offset(str_replace(':', '', $searchOffset));
     while (' ' == substr($search, $pos + 1)) {
         $pos += 1;
     }
     $searchText = trim(str_replace(array('(', ')', '&', ',', '  '), ' ', substr($search, $pos + 1)));
     $searchWords = explode(' ', $searchText);
     $timezone_abbreviations = DateTimeZone::listAbbreviations();
     $hits = array();
     foreach ($timezone_abbreviations as $name => $transitions) {
         foreach ($transitions as $cnt => $transition) {
             if (empty($transition['offset']) || empty($transition['timezone_id']) || $transition['offset'] != $searchOffset) {
                 continue;
             }
             $cWords = explode('/', $transition['timezone_id']);
             $cPrio = $hitCnt = $rank = 0;
             foreach ($cWords as $cWord) {
                 if (empty($cWord)) {
                     continue;
                 }
                 $cPrio += 1;
                 $sPrio = 0;
                 foreach ($searchWords as $sWord) {
                     if (empty($sWord) || 'time' == strtolower($sWord)) {
                         continue;
                     }
                     $sPrio += 1;
                     if (strtolower($cWord) == strtolower($sWord)) {
                         $hitCnt += 1;
                         $rank += $cPrio + $sPrio;
                     } else {
                         $rank += 10;
                     }
                 }
             }
             if (0 < $hitCnt) {
                 $hits[$rank][] = $transition['timezone_id'];
             }
         }
     }
     unset($timezone_abbreviations);
     if (empty($hits)) {
         return FALSE;
     }
     ksort($hits);
     foreach ($hits as $rank => $tzs) {
         if (!empty($tzs)) {
             $timezone = reset($tzs);
             return TRUE;
         }
     }
     return FALSE;
 }
Exemplo n.º 3
0
/**
 * Returns an array containing time zone data from vtimezone standard/daylight instances
 *
 * @param object $vtzc   an iCalcreator calendar standard/daylight instance
 * @return array         time zone data; array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname)
 *
 */
function expandTimezoneDates($vtzc)
{
    $tzdates = array();
    // prepare time zone "description" to attach to each change
    $tzbefore = array();
    $tzbefore['offsetHis'] = $vtzc->getProperty('tzoffsetfrom');
    $tzbefore['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzbefore['offsetHis']);
    if ('-' != substr((string) $tzbefore['offsetSec'], 0, 1) && '+' != substr((string) $tzbefore['offsetSec'], 0, 1)) {
        $tzbefore['offsetSec'] = '+' . $tzbefore['offsetSec'];
    }
    $tzafter = array();
    $tzafter['offsetHis'] = $vtzc->getProperty('tzoffsetto');
    $tzafter['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzafter['offsetHis']);
    if ('-' != substr((string) $tzafter['offsetSec'], 0, 1) && '+' != substr((string) $tzafter['offsetSec'], 0, 1)) {
        $tzafter['offsetSec'] = '+' . $tzafter['offsetSec'];
    }
    if (FALSE === ($tzafter['tzname'] = $vtzc->getProperty('tzname'))) {
        $tzafter['tzname'] = $tzafter['offsetHis'];
    }
    // find out where to start from
    $dtstart = $vtzc->getProperty('dtstart');
    $dtstarttimestamp = mktime($dtstart['hour'], $dtstart['min'], $dtstart['sec'], $dtstart['month'], $dtstart['day'], $dtstart['year']);
    if (!isset($dtstart['unparsedtext'])) {
        // ??
        $dtstart['unparsedtext'] = sprintf('%04d%02d%02dT%02d%02d%02d', $dtstart['year'], $dtstart['month'], $dtstart['day'], $dtstart['hour'], $dtstart['min'], $dtstart['sec']);
    }
    if ($dtstarttimestamp == 0) {
        // it seems that the dtstart string may not have parsed correctly
        // let's set a timestamp starting from 1902, using the time part of the original string
        // so that the time will change at the right time of day
        // at worst we'll get midnight again
        $origdtstartsplit = explode('T', $dtstart['unparsedtext']);
        $dtstarttimestamp = strtotime("19020101", 0);
        $dtstarttimestamp = strtotime($origdtstartsplit[1], $dtstarttimestamp);
    }
    // the date (in dtstart and opt RDATE/RRULE) is ALWAYS LOCAL (not utc!!), adjust from 'utc' to 'local' timestamp
    $diff = -1 * $tzbefore['offsetSec'];
    $dtstarttimestamp += $diff;
    // add this (start) change to the array of changes
    $tzdates[] = array('timestamp' => $dtstarttimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter);
    $datearray = getdate($dtstarttimestamp);
    // save original array to use time parts, because strtotime (used below) apparently loses the time
    $changetime = $datearray;
    // generate dates according to an RRULE line
    $rrule = $vtzc->getProperty('rrule');
    if (is_array($rrule)) {
        if ($rrule['FREQ'] == 'YEARLY') {
            // calculate transition dates starting from DTSTART
            $offsetchangetimestamp = $dtstarttimestamp;
            // calculate transition dates until 10 years in the future
            $stoptimestamp = strtotime("+10 year", time());
            // if UNTIL is set, calculate until then (however far ahead)
            if (isset($rrule['UNTIL']) && $rrule['UNTIL'] != '') {
                $stoptimestamp = mktime($rrule['UNTIL']['hour'], $rrule['UNTIL']['min'], $rrule['UNTIL']['sec'], $rrule['UNTIL']['month'], $rrule['UNTIL']['day'], $rrule['UNTIL']['year']);
            }
            $count = 0;
            $stopcount = isset($rrule['COUNT']) ? $rrule['COUNT'] : 0;
            $daynames = array('SU' => 'Sunday', 'MO' => 'Monday', 'TU' => 'Tuesday', 'WE' => 'Wednesday', 'TH' => 'Thursday', 'FR' => 'Friday', 'SA' => 'Saturday');
            // repeat so long as we're between DTSTART and UNTIL, or we haven't prepared COUNT dates
            while ($offsetchangetimestamp < $stoptimestamp && ($stopcount == 0 || $count < $stopcount)) {
                // break up the timestamp into its parts
                $datearray = getdate($offsetchangetimestamp);
                if (isset($rrule['BYMONTH']) && $rrule['BYMONTH'] != 0) {
                    // set the month
                    $datearray['mon'] = $rrule['BYMONTH'];
                }
                if (isset($rrule['BYMONTHDAY']) && $rrule['BYMONTHDAY'] != 0) {
                    // set specific day of month
                    $datearray['mday'] = $rrule['BYMONTHDAY'];
                } elseif (is_array($rrule['BYDAY'])) {
                    // find the Xth WKDAY in the month
                    // the starting point for this process is the first of the month set above
                    $datearray['mday'] = 1;
                    // turn $datearray as it is now back into a timestamp
                    $offsetchangetimestamp = mktime($datearray['hours'], $datearray['minutes'], $datearray['seconds'], $datearray['mon'], $datearray['mday'], $datearray['year']);
                    if ($rrule['BYDAY'][0] > 0) {
                        // to find Xth WKDAY in month, we find last WKDAY in month before
                        // we do that by finding first WKDAY in this month and going back one week
                        // then we add X weeks (below)
                        $offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']], $offsetchangetimestamp);
                        $offsetchangetimestamp = strtotime("-1 week", $offsetchangetimestamp);
                    } else {
                        // to find Xth WKDAY before the end of the month, we find the first WKDAY in the following month
                        // we do that by going forward one month and going to WKDAY there
                        // then we subtract X weeks (below)
                        $offsetchangetimestamp = strtotime("+1 month", $offsetchangetimestamp);
                        $offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']], $offsetchangetimestamp);
                    }
                    // now move forward or back the appropriate number of weeks, into the month we want
                    $offsetchangetimestamp = strtotime($rrule['BYDAY'][0] . " week", $offsetchangetimestamp);
                    $datearray = getdate($offsetchangetimestamp);
                }
                // convert the date parts back into a timestamp, setting the time parts according to the
                // original time data which we stored
                $offsetchangetimestamp = mktime($changetime['hours'], $changetime['minutes'], $changetime['seconds'] + $diff, $datearray['mon'], $datearray['mday'], $datearray['year']);
                // add this change to the array of changes
                $tzdates[] = array('timestamp' => $offsetchangetimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter);
                // update counters (timestamp and count)
                $offsetchangetimestamp = strtotime("+" . (isset($rrule['INTERVAL']) && $rrule['INTERVAL'] != 0 ? $rrule['INTERVAL'] : 1) . " year", $offsetchangetimestamp);
                $count += 1;
            }
        }
    }
    // generate dates according to RDATE lines
    while ($rdates = $vtzc->getProperty('rdate')) {
        if (is_array($rdates)) {
            foreach ($rdates as $rdate) {
                // convert the explicit change date to a timestamp
                $offsetchangetimestamp = mktime($rdate['hour'], $rdate['min'], $rdate['sec'] + $diff, $rdate['month'], $rdate['day'], $rdate['year']);
                // add this change to the array of changes
                $tzdates[] = array('timestamp' => $offsetchangetimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter);
            }
        }
    }
    return $tzdates;
}
Exemplo n.º 4
0
 private static function date2timestamp($datetime, $tz = null)
 {
     if (!isset($datetime['hour'])) {
         $datetime['hour'] = '0';
     }
     if (!isset($datetime['min'])) {
         $datetime['min'] = '0';
     }
     if (!isset($datetime['sec'])) {
         $datetime['sec'] = '0';
     }
     foreach ($datetime as $dkey => $dvalue) {
         if ('tz' != $dkey) {
             $datetime[$dkey] = (int) $dvalue;
         }
     }
     if ($tz) {
         $datetime['tz'] = $tz;
     }
     $offset = isset($datetime['tz']) && '' < trim($datetime['tz']) ? iCalUtilityFunctions::_tz2offset($datetime['tz']) : 0;
     return gmmktime($datetime['hour'], $datetime['min'], $datetime['sec'] + $offset, $datetime['month'], $datetime['day'], $datetime['year']);
 }
 /**
  * creates formatted output for calendar component property data value type date/date-time
  *
  * @author Kjell-Inge Gustafsson <*****@*****.**>
  * @since 2.4.8 - 2008-10-30
  * @param array   $datetime
  * @param int     $parno, optional, default 6
  * @return string
  */
 public static function _format_date_time($datetime, $parno = 6)
 {
     if (!isset($datetime['year']) && !isset($datetime['month']) && !isset($datetime['day']) && !isset($datetime['hour']) && !isset($datetime['min']) && !isset($datetime['sec'])) {
         return;
     }
     $output = null;
     // if( !isset( $datetime['day'] )) { $o=''; foreach($datetime as $k=>$v) {if(is_array($v)) $v=implode('-',$v);$o.=" $k=>$v";} echo " day SAKNAS : $o <br />\n"; }
     foreach ($datetime as $dkey => &$dvalue) {
         if ('tz' != $dkey) {
             $dvalue = (int) $dvalue;
         }
     }
     $output = date('Ymd', mktime(0, 0, 0, $datetime['month'], $datetime['day'], $datetime['year']));
     if (isset($datetime['hour']) || isset($datetime['min']) || isset($datetime['sec']) || isset($datetime['tz'])) {
         if (isset($datetime['tz']) && !isset($datetime['hour'])) {
             $datetime['hour'] = 0;
         }
         if (isset($datetime['hour']) && !isset($datetime['min'])) {
             $datetime['min'] = 0;
         }
         if (isset($datetime['hour']) && isset($datetime['min']) && !isset($datetime['sec'])) {
             $datetime['sec'] = 0;
         }
         $date = mktime($datetime['hour'], $datetime['min'], $datetime['sec'], $datetime['month'], $datetime['day'], $datetime['year']);
         $output .= date('\\THis', $date);
         if (isset($datetime['tz']) && '' < trim($datetime['tz'])) {
             $datetime['tz'] = trim($datetime['tz']);
             if ('Z' == $datetime['tz']) {
                 $output .= 'Z';
             }
             $offset = iCalUtilityFunctions::_tz2offset($datetime['tz']);
             if (0 != $offset) {
                 $date = mktime($datetime['hour'], $datetime['min'], $datetime['sec'] + $offset, $datetime['month'], $datetime['day'], $datetime['year']);
                 $output = date('Ymd\\THis\\Z', $date);
             }
         } elseif (7 == $parno) {
             $output .= 'Z';
         }
     }
     return $output;
 }