Sub
@param TimeValue $tm1
@param TimeValue $tm2
@return DayTimeDurationValue
542633
public static function Sub( $tm1, $tm2 )
	{
		try
		{
			if ( ! $tm1 instanceof TimeValue )
				throw new \InvalidArgumentException("$tm1");

			if ( ! $tm2 instanceof TimeValue )
				throw new \InvalidArgumentException("$tm2");

			$seconds1 = new DecimalValue( $tm1->Value->getTimestamp() );
			$seconds1->Add( $tm1->Value->microseconds );

			$seconds2 = new DecimalValue( $tm2->Value->getTimestamp() );
			$seconds2->Add( $tm2->Value->microseconds );

			$newSeconds = $seconds1->Sub( $seconds2 );
			$sign = $newSeconds->getIsNegative();

			$newSeconds = $newSeconds->getAbs();
			$days = $newSeconds->Div( 86400 )->getIntegerPart();
			$time = $newSeconds->Mod( 86400 );
			$hours = $time->Div( 3600 )->getIntegerPart();
			$time = $time->Sub( $hours * 3600 );
			$minutes = $time->Div( 60 )->getIntegerPart();
			$time = $time->Sub( $minutes * 60 );
			$seconds = $time->getIntegerPart();
			$micro = $time->getDecimalPart();

			$interval = new \DateInterval( sprintf( "P%02sDT%02sH%02sM%02sS", $days, $hours, $minutes, $seconds ) );
			$interval->hasValue = ! $newSeconds->getIsZero();
			$interval->invert = $sign;
			$interval->microseconds = $micro;

			return new DayTimeDurationValue( $interval );

			$diff = $tm2->Value->diff( $tm1->Value );
			return new DayTimeDurationValue( $diff );
		}
		catch( \OverflowException $ex )
		{
			throw XPath2Exception::withErrorCode( "FODT0001", Resources::FODT0001 );
		}
	}
1157549
private static long dateTimeDifference(final Temporal d1, final Temporal d2) {
      return ChronoUnit.SECONDS.between(d1, d2);
  }
677812
public static long subHours(final Date date1, final Date date2) {

    return subTime(date1, date2, DatePeriod.HOUR);
  }
219210
public function closest(ChronosInterface $dt1, ChronosInterface $dt2)
    {
        return $this->diffInSeconds($dt1) < $this->diffInSeconds($dt2) ? $dt1 : $dt2;
    }
388068
public static double[] timesMinusTimes(final double[] v1, final double s1, final double[] v2, final double s2) {
    assert v1.length == v2.length : ERR_VEC_DIMENSIONS;
    final double[] sub = new double[v1.length];
    for(int i = 0; i < v1.length; i++) {
      sub[i] = v1[i] * s1 - v2[i] * s2;
    }
    return sub;
  }
806143
public static long subYears(final Date date1, final Date date2) {

    return Math.abs(getYear(date1) - getYear(date2));
  }
767796
public static function getTime($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);

		$time = $dt->format('H') * self::SECONDS_IN_AN_HOUR;
		$time += $dt->format('i') * self::SECONDS_IN_A_MINUTE;
		$time += $dt->format('s');

		return $dt->setTimestamp($time)->format($format);
	}
144004
public static function compare($value1, $value2)
    {
        if (self::isIntlLoaded()) {
            return self::getCollator()->compare($value1, $value2);
        }
        
        return strnatcmp($value1, $value2);
    }
1302652
public static function AddDayTimeDuration( $tm, $duration )
	{
		try
		{
			if ( ! $tm instanceof TimeValue )
				throw new \InvalidArgumentException("$tm");

	   		if ( ! $duration instanceof DurationValue )
				throw new \InvalidArgumentException("$duration");

			// Shortcut for when there is no duration
			if ( ! $duration->Value->hasValue ) return $tm;

			$dt = $tm->Value;

			// This is a convoluted way to add dates.  But its necessary because the
			// PHP DateTime call cannot handle negative years and, so, not all the
			// weirdness that happens around year zero.  So instead of relying on the
			// ability of the DataTime class to handle negative year these lines convert
			// the date to the corresponding julian days and perform maths on this number
			// of days then converting the result back to a gregorian date.  Julian dates
			// rooted in 4713BC so maths on dates at the turn of the gregorian calendar
			// are 5000 years in the future.
			$durationSeconds = $duration->getTotalSeconds();
			$julianDay = gregoriantojd( $dt->format("m"), $dt->format("d"), $dt->format("Y") );
			$gregorianDate = jdtogregorian( $julianDay );
			$julianSeconds = new DecimalValue( $julianDay );

			$julianSeconds = $julianSeconds->Mul( 86400 )->Add( $dt->format("H") * 3600 )->Add( $dt->format("i") * 60 )->Add( $dt->format("s") )->Add( "0.{$dt->microseconds}" );
			$newSeconds = $julianSeconds->Add( $durationSeconds );
			$newDay = $newSeconds->Div( 86400 )->getIntegerPart();
			$newTime = $newSeconds->Mod( 86400 );
			$newHour = $newTime->Div( 3600 )->getIntegerPart();
			$newTime = $newTime->Sub( $newHour * 3600 );
			$newMinute = $newTime->Div( 60 )->getIntegerPart();
			$newTime = $newTime->Sub( $newMinute * 60 );
			$newSecond = $newTime->getIntegerPart();
			$newMicro = $newTime->getDecimalPart();

			$today = new \DateTime();
			$year = $today->format("Y");
			$month = $today->format("m");
			$day = $today->format("d");

			// $gregorianDate = jdtogregorian( $newDay );
			// if ( ! preg_match( "!^(?<month>\d+?)/(?<day>\d+?)/(?<sign>-?)(?<year>\d+?)$!", $gregorianDate, $matches ) )
			// 	throw new \UnexpectedValueException();

			$sign = ! empty( $matches['sign'] );

			$gregorianDate = sprintf( "%04s-%02s-%02sT%02d:%02d:%02d.%d", $year, $month, $day, $newHour, $newMinute, $newSecond, $newMicro );
			$newDate = new \DateTime( $gregorianDate, $tm->IsLocal ? null : $dt->getTimezone() );
			$newDate->microseconds = $newMicro;
			return new TimeValue( $newDate, ! $tm->IsLocal );

			// return new TimeValue( $tm->Value->add( $duration->Value ) );
		}
		catch( ArgumentOutOfRangeException $ex )
		{
			throw XPath2Exception::withErrorCode( "FODT0001", Resources::FODT0001 );
		}
	}
695776
protected function Sub( $value )
	{
	    switch ( $value->GetValueCode() )
	    {
	        case TimeProxyFactory::Code:
	            return new DayTimeDurationProxy( TimeValue::Sub( $this->_value, /* TimeValue */ $value->getValue() ) );

	        case DayTimeDurationProxyFactory::Code:
	        	/**
	        	 * @var DayTimeDurationProxy $value
	        	 */
	        	// Clone the DateValue contained in the proxy or the original is changed
	        	$clone = new TimeValue( clone $this->_value->Value );
	        	$value->getValue()->Value->invert = ! $value->getValue()->Value->invert;
	        	return new TimeProxy( TimeValue::AddDayTimeDuration( $clone, $value->getValue() ) );
	        	// return new TimeProxy( TimeValue::Add(  $this->_value, - /* DayTimeDurationValue */ $value->getValue() ) );

	        default:
	            throw XPath2Exception::withErrorCodeAndParams( "XPTY0004", Resources::BinaryOperatorNotDefined,
					array(
						"op:sub",
						SequenceType::WithTypeCodeAndCardinality( SequenceType::GetXmlTypeCodeFromObject( $this->_value), XmlTypeCardinality::One ),
						SequenceType::WithTypeCodeAndCardinality( SequenceType::GetXmlTypeCodeFromObject( $value->getValue() ), XmlTypeCardinality::One )
					)
				);
	    }
	}
1124727
public function withTimeAt(
        int $hour = null,
        int $minute = null,
        int $second = null,
        int $microsecond = null
    ) : self {
        
        $instance = clone $this;
        
        $hour        = $hour        === null ? $this->hour()        : $hour;
        $minute      = $minute      === null ? $this->minute()      : $minute;
        $second      = $second      === null ? $this->second()      : $second;
        $microsecond = $microsecond === null ? $this->microsecond() : $microsecond;
        
        $instance->date->setTime($hour, $minute, $second);
        
        // There is no API for setting the microsecond explicitly so a new instance has to be constructed.
        $format         = 'Y-m-d H:i:s';
        $value          = $instance->format($format) . '.' . substr($microsecond, 0, 6);
        $instance->date = \DateTime::createFromFormat("$format.u", $value);
        
        return $instance;
    }
1279476
public static long subMonths(final String dateString1, final String dateString2) {

    Date date1 = getDateFromString(dateString1, DEFAULT_DATE_SIMPLE_PATTERN);
    Date date2 = getDateFromString(dateString2, DEFAULT_DATE_SIMPLE_PATTERN);
    return subMonths(date1, date2);
  }
1241087
public static function timeDiffSeconds(DateTime $time1, DateTime $time2)
    {
        $interval = $time1->diff($time2);

        return self::totalSeconds($interval);
    }
573840
public static DateTimeValue toDateTimeValue(long millisFromEpoch, TimeZone zone) {
		GregorianCalendar c = new GregorianCalendar(zone);
		c.clear();
		c.setTimeInMillis(millisFromEpoch);
		//@formatter:off
		return new DateTimeValueImpl (
			c.get(Calendar.YEAR),
			c.get(Calendar.MONTH) + 1,
			c.get(Calendar.DAY_OF_MONTH),
			c.get(Calendar.HOUR_OF_DAY),
			c.get(Calendar.MINUTE),
			c.get(Calendar.SECOND)
		);
		//@formatter:on
	}
928767
public static function Divide( $a, $b )
	{
		if ( ! is_numeric( $b ) )
			throw new \InvalidArgumentException( "Division denominator is not a number" );

	    if ( is_nan( $b ) )
	        throw XPath2Exception::withErrorCode( "FOCA0005", Resources::FOCA0005 );

        // if ( $b == INF || $b == -INF )
        //	throw XPath2Exception::withErrorCode( "FOCA0005", Resources::FOCA0005 );

	    if ( $b == 0.0 )
	        throw XPath2Exception::withErrorCode( "FODT0002", Resources::FODT0002 );

		if ( ! $a instanceof DayTimeDurationValue )
	        throw new ArgumentException("$a");

		// Create a new interval with the multiplied days. ->days is created by the ->diff function to hold the total days.
		$dividedSeconds = doubleval( $a->getTotalSeconds()->getValue() / $b );
		$dividedInterval = new \DateInterval("P0D");
		if ( round( $dividedSeconds ) == 0 )
		{
			$dividedInterval->hasValue = false;
			$dividedInterval->microseconds = 0;
			return new DayTimeDurationValue( $dividedInterval );
		}

		$dividedInterval->s = intval( $dividedSeconds );
		$microseconds = round( $dividedSeconds - $dividedInterval->s, 3 ) * 1000;

		// Finally convert $multipliedInterval into a normalized interval
		$dt = new \DateTimeImmutable();
		$tz = new \DateTimeZone("Z");
		$dt = $dt->setTimezone( $tz );
		$diff = $dt->add( $dividedInterval )->diff( $dt );
		$diff->hasValue = $dividedSeconds != 0;
		$diff->invert = ! $diff->invert;
		$diff->microseconds = $microseconds;

	    return new DayTimeDurationValue( $diff );
	}
626832
function _date2timestamp( $datetime, $tz=null ) {
    $output = 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] = (integer) $dvalue;
    }
    if( $tz )
      $datetime['tz'] = $tz;
    $offset = 0;
    if( isset( $datetime['tz'] ) && ( '' < trim ( $datetime['tz'] )))
      $offset = $this->_tz2offset( $datetime['tz'] );
    $output          = mktime( $datetime['hour']
                             , $datetime['min']
                             , $datetime['sec'] + $offset
                             , $datetime['month']
                             , $datetime['day']
                             , $datetime['year'] );
    return $output;
  }
153304
static public function getTimestamp($hour, $min, $sec, $mon = false, $day = false, $year = false, $is_gmt = false)
    {
        if ($mon === false) {
            return $is_gmt ? @gmmktime($hour, $min, $sec) : @mktime($hour, $min, $sec);
        }
        return $is_gmt ? @gmmktime($hour, $min, $sec, $mon, $day, $year) : @mktime($hour, $min, $sec, $mon, $day, $year);
    }