convert duration to date in array format based on dtstart value

@author Kjell-Inge Gustafsson <ical@kigkonsult.se>
@since 2.2.11 - 2007-12-02
@param array $startdate, optional
@param array $duration, optional
@return array, date format
350988
function duration2date($startdate=FALSE, $duration=FALSE) {
    if( $startdate && $duration ) {
      $d1               = $startdate;
      $dur              = $duration;
    }
    elseif( isset( $this->dtstart['value'] ) && isset( $this->duration['value'] )) {
      $d1               = $this->dtstart['value'];
      $dur              = $this->duration['value'];
    }
    else
      return null;
    $dateOnly         = ( isset( $d1['hour'] ) || isset( $d1['min'] ) || isset( $d1['sec'] )) ? FALSE : TRUE;
    $d1['hour']       = ( isset( $d1['hour'] )) ? $d1['hour'] : 0;
    $d1['min']        = ( isset( $d1['min'] ))  ? $d1['min']  : 0;
    $d1['sec']        = ( isset( $d1['sec'] ))  ? $d1['sec']  : 0;
    $dtend = mktime( $d1['hour']
                    , $d1['min']
                    , $d1['sec']
                    , $d1['month']
                    , $d1['day']
                    , $d1['year'] );
    if( isset( $dur['week'] ))
      $dtend += ( $dur['week'] * 7 * 24 * 60 * 60 );
    if( isset( $dur['day'] ))
      $dtend += ( $dur['day'] * 24 * 60 * 60 );
    if( isset( $dur['hour'] ))
      $dtend += ( $dur['hour'] * 60 *60 );
    if( isset( $dur['min'] ))
      $dtend += ( $dur['min'] * 60 );
    if( isset( $dur['sec'] ))
      $dtend +=   $dur['sec'];
    $dtend2 = array();
    $dtend2['year']   = date('Y', $dtend );
    $dtend2['month']  = date('m', $dtend );
    $dtend2['day']    = date('d', $dtend );
    $dtend2['hour']   = date('H', $dtend );
    $dtend2['min']    = date('i', $dtend );
    $dtend2['sec']    = date('s', $dtend );
    if( isset( $d1['tz'] ))
      $dtend2['tz']   = $d1['tz'];
    if( $dateOnly && (( 0 == $dtend2['hour'] ) && ( 0 == $dtend2['min'] ) && ( 0 == $dtend2['sec'] )))
      unset( $dtend2['hour'], $dtend2['min'], $dtend2['sec'] );
    return $dtend2;
  }
430847
public static function from(Date $start, $amount)
	{
		return self::cast(DateTimeRange::from(new DateTime($start), $amount, new DateInterval('P1D')));
	}
466500
protected function getStartDate()
    {
        $StartDate = false;
        $objStartDate = \Database::getInstance()->prepare("SELECT
                                                           MIN(`tstamp`) AS YMD
                                                           FROM `tl_dlstatdets`
                                                           WHERE 1")
                                                ->execute();
        if ($objStartDate->YMD !== null)
        {
            $StartDate = \Date::parse($GLOBALS['TL_CONFIG']['dateFormat'], $objStartDate->YMD);

        }

        return $StartDate;
    }
844381
private function createTimestampCalendar(
        DateTimeInterface $startDate,
        DateTimeInterface $endDate,
        CultureFeed_Cdb_Data_Calendar_TimestampList $calendar,
        $index = null
    ) {
        // Make a clone of the original calendar to avoid updating input param.
        $newCalendar = clone $calendar;

        $first24Hours = Period::createFromDuration($startDate, new DateInterval('P1D'));

        // Easy case an no seconds needed for indexing.
        if ($first24Hours->contains($endDate)) {
            $newCalendar->add(
                new CultureFeed_Cdb_Data_Calendar_Timestamp(
                    $startDate->format('Y-m-d'),
                    $this->formatDateTimeAsCdbTime($startDate),
                    $this->formatDateTimeAsCdbTime($endDate)
                )
            );
        } elseif (is_int($index)) {
            // Complex case and seconds needed for indexing.
            $period = new Period($startDate, $endDate);

            $startTimestamp = new CultureFeed_Cdb_Data_Calendar_Timestamp(
                $startDate->format('Y-m-d'),
                $this->formatDateTimeAsCdbTime($startDate, $index)
            );

            $endTimestamp = new CultureFeed_Cdb_Data_Calendar_Timestamp(
                $endDate->format('Y-m-d'),
                $this->createIndexedTimeString($index),
                $this->formatDateTimeAsCdbTime($endDate)
            );

            $untilEndOfSecondDay = new Period(
                $startDate,
                Chronos::instance($startDate)->addDay()->endOfDay()
            );

            if ($untilEndOfSecondDay->contains($endDate)) {
                $fillerTimestamps = [];
            } else {
                $days = iterator_to_array($period->getDatePeriod('1 DAY'));
                $fillerTimestamps = array_map(
                    function (DateTimeInterface $dateTime) use ($index) {
                        return new CultureFeed_Cdb_Data_Calendar_Timestamp(
                            $dateTime->format('Y-m-d'),
                            $this->createIndexedTimeString($index)
                        );
                    },
                    array_slice($days, 1, count($days) === 2 ? 2 : -1)
                );
            }

            $newCalendar = array_reduce(
                array_merge([$startTimestamp], $fillerTimestamps, [$endTimestamp]),
                function (CultureFeed_Cdb_Data_Calendar_TimestampList $calendar, $timestamp) {
                    $calendar->add($timestamp);
                    return $calendar;
                },
                $newCalendar
            );
        }

        return $newCalendar;
    }
668518
public function stats_blast($blast_id = null, $start_date = null, $end_date = null, array $data = [ ]) {
        $data['stat'] = 'blast';
        if (!is_null($blast_id)) {
            $data['blast_id'] = $blast_id;
        }
        if (!is_null($start_date)) {
            $data['start_date'] = $start_date;
        }
        if (!is_null($end_date)) {
            $data['end_date'] = $end_date;
        }
        return $this->stats($data);
    }
1154278
public static function startOf($interval, \DateTime $date = null) {
			$date = $date ?: new \DateTime();

			switch ($interval) {
				case self::INTERVAL_MINUTE:
					$date->setTime((int)$date->format('H'), (int)$date->format('i'), 0, 0);

					break;

				case self::INTVERAL_HOUR:
					$date->setTime((int)$date->format('H'), 0, 0, 0);

					break;

				case self::INTERVAL_DAY:
					$date->setTime(0, 0, 0, 0);

					break;

				case self::INTERVAL_WEEK:
					$date
						->sub(new \DateInterval('P' . (int)$date->format('w') . 'D'))
						->setTime(0, 0, 0, 0);

					break;

				case self::INTERVAL_MONTH:
					$date
						->sub(new \DateInterval('P' . ((int)$date->format('d') - 1) . 'D'))
						->setTime(0, 0, 0, 0);

					break;

				case self::INTERVAL_YEAR:
					$date
						->setTime(0, 0, 0, 0)
						->setDate((int)$date->format('Y'), 1, 1);

					break;

				default:
					throw new \InvalidArgumentException('$interval must be one of the INTERVAL_* class constants');
			}

			return $date;
		}
714691
public static function createFromEndAndDuration(Date $end, Duration $duration)
    {
        return static::create($end->sub($duration), $end);
    }
1081877
public static function create(CalendarDate $start, CalendarDate $end = null, Duration $duration, $recurrence = null)
    {
        return new static($start, $end, $duration, $recurrence);
    }
429522
public function getStartDate() : ?string 
    {
        if ( ! $this->hasStartDate()) {
            $this->setStartDate($this->getDefaultStartDate());
        }
        return $this->startDate;
    }
1057586
public static function getMonthStart($ts = 'now', $format = 'U', $tz = null) {
		if (!Util::isValidTimezone($tz)) {
			$tz = Util::getClientTimezone();
		}
		
		$dt = new DateTime(null, new DateTimeZone($tz));
		(is_int($ts)) ? $dt->setTimestamp($ts) : $dt->modify($ts);

		$month = (int) $dt->format('m'); // month
		$year = (int) $dt->format('Y'); // year

		$dt->setDate($year, $month, 1);
		$dt->setTime(0, 0, 0);

		return $dt->format($format);
	}
724054
public static function initDatesInRange($start_date, $end_date, $daysDifference = 1){
        $dates_in_range = [];
        $begin = new DateTime($start_date);
        $end = new DateTime($end_date);
        $endModify = $end->modify( '+'.$daysDifference.' day' ); 

        $interval = new DateInterval('P'.$daysDifference.'D');
        $daterange = new DatePeriod($begin, $interval ,$endModify);

        foreach($daterange as $date){
            $dates_in_range[$date->getTimestamp()] = $date->format("Y-m-d");
        }
        return $dates_in_range;
    }
39676
public function during($starting,$ending)
    {
        if(! is_numeric($starting) || ! is_numeric($ending))
            throw new \Edujugon\GoogleAds\Exceptions\Report('During clause only accepts the following date format: "Ymd" => e.g. 20170112');

        $this->during = [$starting,$ending];

        return $this;
    }
120534
public static function getMonthsRange($startData, $endDate) {
        $time1 = strtotime($startData); //absolute date comparison needs to be done here, because PHP doesn't do date comparisons
        $time2 = strtotime($endDate);
        //$my1 = date('mY', $time1); //need these to compare dates at 'month' granularity
        //$my2 = date('mY', $time2);
        $year1 = date('Y', $time1);
        $year2 = date('Y', $time2);
        $years = range($year1, $year2);
        $months = Array();
        foreach ($years as $year) {
            $months[$year] = array();
            while ($time1 < $time2) {
                if (date('Y', $time1) == $year) {
                    $months[$year][] = date('m', $time1);
                    $time1 = strtotime(date('Y-m-d', $time1) . ' +1 month');
                } else {
                    break;
                }
            }
            continue;
        }

        return $months;
    }
1193301
public function createCurrentMonthFromStartDate(\Carbon\Carbon $startDate)
    {
        $year = (int)$startDate->format('Y');
        $month = (int)$startDate->format('n');
        $day = (int)$startDate->format('d');

        $from = \Carbon\Carbon::create($year, $month, $day, 0, 0, 0, 'Europe/Berlin');

        $diffMonth = $from->month - $month;
        while ($diffMonth > 0) {
            $from = $from->copy()->subDay();
            $diffMonth = $from->month - $month;
        }
        return $from;
    }
387552
public function setStartDate(\DateTime $startDate)
    {
        $this->startDate = $startDate
            ->setTimezone(new \DateTimeZone('UTC'))
            ->setTime(0, 0, 0);

        return $this;
    }
365598
public function getOneTimeEvents($starttime = null, $endtime = null) {

		if (is_null($starttime)) {
			$starttime = time();
		}
		if (is_null($endtime)) {
			$endtime = strtotime('+1 year', $starttime);
		}

		$starttime = sanitize_int($starttime);
		$endtime = sanitize_int($endtime);
		$relationship_name = sanitize_string(self::EVENT_CALENDAR_RELATIONSHIP);

		$dbprefix = elgg_get_config('dbprefix');

		// for performance we'll denormalize metastrings first
		$mdr_name = elgg_get_metastring_id('repeat');
		$mdr_val = elgg_get_metastring_id(0);
		$mds_name = elgg_get_metastring_id('start_timestamp');
		$mde_name = elgg_get_metastring_id('end_timestamp');
		$options = array(
			'type' => 'object',
			'subtype' => Event::SUBTYPE,
			'joins' => array(
				"JOIN {$dbprefix}entity_relationships er ON er.guid_one = e.guid", // calendar relationship
				"JOIN {$dbprefix}metadata mdr ON mdr.entity_guid = e.guid", // repeating metadata
				"JOIN {$dbprefix}metadata mds ON mds.entity_guid = e.guid", // start time metadata
				"JOIN {$dbprefix}metastrings mss ON mss.id = mds.value_id", // start time metastring
				"JOIN {$dbprefix}metadata mde ON mde.entity_guid = e.guid", // end time metadata
				"JOIN {$dbprefix}metastrings mse ON mse.id = mde.value_id" // end time metastring
			),
			'wheres' => array(
				"er.guid_two = {$this->guid} AND er.relationship = '{$relationship_name}'",
				"mdr.name_id = {$mdr_name} AND mdr.value_id = {$mdr_val}",
				"mds.name_id = {$mds_name}",
				"mde.name_id = {$mde_name}",
				"((CAST(mss.string AS SIGNED) BETWEEN {$starttime} AND {$endtime})
					OR (CAST(mse.string AS SIGNED) BETWEEN {$starttime} AND {$endtime}))"
			),
			'limit' => false
		);

		return new ElggBatch('elgg_get_entities', $options);
	}
268729
public function setDateStart( $date )
	{
		if ( $date === $this->getDateStart() ) { return; }

		$this->_checkDateFormat($date);

		$this->_values['start'] = ( $date !== null ? (string) $date : null );
		$this->setModified();
	}