Exemplo n.º 1
0
 /**
  * Extended greatest common divisor
  * Compute the gcd as a multiple of the inputs:
  * gcd(a, b) = a*a' + b*b'
  * https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
  * Knuth, The Art of Computer Programming, Volume 2, 4.5.2 Algorithm X.
  *
  * @param  int $a
  * @param  int $b
  *
  * @return array [gcd, a', b']
  */
 public static function extendedGCD(int $a, int $b) : array
 {
     // Base cases
     if ($a == 0) {
         return [$b, 0, 1];
     }
     if ($b == 0) {
         return [$a, 1, 0];
     }
     $x₂ = 1;
     $x₁ = 0;
     $y₂ = 0;
     $y₁ = 1;
     while ($b > 0) {
         $q = intdiv($a, $b);
         $r = $a % $b;
         $x = $x₂ - $q * $x₁;
         $y = $y₂ - $q * $y₁;
         $x₂ = $x₁;
         $x₁ = $x;
         $y₂ = $y₁;
         $y₁ = $y;
         $a = $b;
         $b = $r;
     }
     return [$a, $x₂, $y₂];
 }
function main()
{
    include_once 'numbers.php';
    $numbers = listToArray($numberList);
    $digitCount = count($numbers[0]);
    $numberCount = count($numbers);
    $realSum = [];
    $startUnit = 0;
    /**
     * This use the elementary sum method from right to left.
     */
    for ($i = $digitCount - 1; $i >= 0; $i--) {
        $sum = 0;
        for ($j = 0; $j < $numberCount; $j++) {
            $sum += intval($numbers[$j][$i]);
        }
        $sumSplit = array_reverse(str_split(strval($sum)));
        for ($k = 0; $k < count($sumSplit); $k++) {
            // NOTE: This null coalesce (??) only works on PHP 7
            $realSum[$startUnit + $k] = $realSum[$startUnit + $k] ?? 0;
            // Get the sum by column
            $colSum = $realSum[$startUnit + $k] + intval($sumSplit[$k]);
            // Put remainder to the current result column
            $realSum[$startUnit + $k] = $colSum % 10;
            // If the column sum is >= 10, put the carry number to the next result column
            if ($colSum >= 10) {
                $realSum[$startUnit + $k + 1] = $realSum[$startUnit + $k + 1] ?? 0;
                // NOTE: This intdiv() is also only on PHP 7
                $realSum[$startUnit + $k + 1] += intdiv($colSum, 10);
            }
        }
        $startUnit++;
    }
    var_dump(implode(array_reverse($realSum)));
}
Exemplo n.º 3
0
 /**
  * Returns the largest integer value that is less than or equal to the algebraic quotient.
  *
  * @param integer $a The first argument, validated as an integer.
  * @param integer $b The second argument, validated as a non-zero integer.
  *
  * @return integer
  */
 public static function floorDiv($a, $b)
 {
     $r = intdiv($a, $b);
     // If the signs are different and modulo not zero, round down.
     if (($a ^ $b) < 0 && $r * $b != $a) {
         $r--;
     }
     return $r;
 }
Exemplo n.º 4
0
 /** @return int */
 public final function quotient()
 {
     if (!function_exists('intdiv')) {
         // This method isn't actually used internally by the library
         // currently so no hard dependency on these polyfills.
         // @codeCoverageIgnoreStart
         throw new \LogicException(sprintf('%s() requires the intdiv() function which was added in PHP 7' . ' you could use a polyfill such as michaelc/intdiv-compat or' . ' symfony/polyfill-php70 to provide this function', __METHOD__));
         // @codeCoverageIgnoreEnd
     }
     return intdiv($this->result, $this->divisor);
 }
Exemplo n.º 5
0
function lyn_convertToMinutes($seconds)
{
    $sec = $seconds % 60;
    if (function_exists('intdiv')) {
        $min = intdiv($seconds, 60);
    } else {
        $min = ($seconds - $sec) / 60;
    }
    $sec = abs($sec);
    $sec = $sec < 10 ? '0' . $sec : $sec;
    return "{$min}:{$sec}";
}
Exemplo n.º 6
0
 /**
  * @param TweetCriteria $criteria
  * @return Tweet[]
  */
 public function getTweets(TweetCriteria $criteria)
 {
     $results = array();
     try {
         $refreshCursor = null;
         if ($criteria->getMaxTweets() == 0) {
             return $results;
         }
         do {
             $response = $this->getUrlResponse($criteria->getUsername(), $criteria->getSince(), $criteria->getUntil(), $criteria->getQuerySearch(), $refreshCursor);
             $refreshCursor = $response['min_position'];
             $htmlCrawler = new Crawler($response['items_html']);
             $tweetsCrawler = $htmlCrawler->filter('div.js-stream-tweet');
             if ($tweetsCrawler->count() == 0) {
                 break;
             }
             $tweetsCrawler->each(function ($tweet) use(&$results) {
                 /** @var $tweet \Symfony\Component\DomCrawler\Crawler */
                 $username = $tweet->filter('span.username.js-action-profile-name b')->first()->text();
                 $text = str_replace('[^\\u0000-\\uFFFF]', '', $tweet->filter('p.js-tweet-text')->first()->text());
                 $retweets = intval(str_replace(',', '', $tweet->filter('span.ProfileTweet-action--retweet span.ProfileTweet-actionCount')->first()->attr('data-tweet-stat-count')));
                 $favorites = intval(str_replace(',', '', $tweet->filter('span.ProfileTweet-action--favorite span.ProfileTweet-actionCount')->first()->attr('data-tweet-stat-count')));
                 $date = new \DateTime('@' . intdiv(intval($tweet->filter('small.time span.js-short-timestamp')->first()->attr('data-time-ms')), 1000));
                 $id = $tweet->first()->attr('data-tweet-id');
                 $permalink = $tweet->first()->attr('data-permalink-path');
                 preg_match("(@\\w*)", $text, $mentions);
                 preg_match("(#\\w*)", $text, $hashtags);
                 $geo = '';
                 $geoElement = $tweet->filter('span.Tweet-geo')->first();
                 if ($geoElement->count() > 0) {
                     $geo = $geoElement->attr('title');
                 }
                 $resultTweet = new Tweet();
                 $resultTweet->setId($id);
                 $resultTweet->setPermalink("https://twitter.com" . $permalink);
                 $resultTweet->setUsername($username);
                 $resultTweet->setText($text);
                 $resultTweet->setDate($date);
                 $resultTweet->setRetweets($retweets);
                 $resultTweet->setFavorites($favorites);
                 $resultTweet->setMentions($mentions);
                 $resultTweet->setHashtags($hashtags);
                 $resultTweet->setGeo($geo);
                 $results[] = $resultTweet;
             });
         } while (count($results) < $criteria->getMaxTweets());
     } catch (\Exception $e) {
         $this->handleException($e);
         return $results;
     }
     return $results;
 }
Exemplo n.º 7
0
 /**
  * Find index for a value based
  *
  * @param mixed $value
  * @param int $compareLimit
  * @return int
  */
 protected function findIndex($value, int $compareLimit) : int
 {
     $begin = 0;
     $end = count($this->values) - 1;
     while ($begin <= $end) {
         $middle = intdiv($begin + $end, 2);
         if (($this->values[$middle] <=> $value) <= $compareLimit) {
             $begin = $middle + 1;
             continue;
         }
         $end = $middle - 1;
     }
     return $begin;
 }
function convertMetersToYards($meters)
{
    // Convert meters to tenths of a millimeter
    $mmx10 = $meters * 10000;
    // Divide by 9144 to get yards
    $y = intdiv($mmx10, 9144);
    // Use modulo division to get the remainder
    $f = $mmx10 % 9144;
    // Divide by 3048 to get feet
    $ft = intdiv($f, 3048);
    // Get the remainder and convert to inches
    $i = $f % 3048;
    $i = number_format($i / 254, 2);
    return "{$y} yards {$ft} feet {$i} inches";
}
Exemplo n.º 9
0
 /**
  * Calculate the median average of a list of numbers
  *
  * @param array $numbers
  *
  * @return number
  */
 public static function median(array $numbers)
 {
     if (empty($numbers)) {
         return null;
     }
     // Reset the array key indexes because we don't know what might be passed in
     $numbers = array_values($numbers);
     // For odd number of numbers, take the middle indexed number
     if (count($numbers) % 2 == 1) {
         $middle_index = intdiv(count($numbers), 2);
         return self::kthSmallest($numbers, $middle_index);
     }
     // For even number of items, take the mean of the middle two indexed numbers
     $left_middle_index = intdiv(count($numbers), 2) - 1;
     $left_median = self::kthSmallest($numbers, $left_middle_index);
     $right_middle_index = $left_middle_index + 1;
     $right_median = self::kthSmallest($numbers, $right_middle_index);
     return self::mean([$left_median, $right_median]);
 }
Exemplo n.º 10
0
<?php

var_dump(intdiv(3, 2));
var_dump(intdiv(-3, 2));
var_dump(intdiv(3, -2));
var_dump(intdiv(-3, -2));
var_dump(intdiv(PHP_INT_MAX, PHP_INT_MAX));
var_dump(intdiv(-PHP_INT_MAX - 1, -PHP_INT_MAX - 1));
try {
    var_dump(intdiv(-PHP_INT_MAX - 1, -1));
} catch (Exception $e) {
    var_dump($e->getMessage());
}
try {
    var_dump(intdiv(PHP_INT_MIN, -1));
} catch (Exception $e) {
    var_dump($e->getMessage());
}
try {
    var_dump(intdiv(1, 0));
} catch (Exception $e) {
    var_dump($e->getMessage());
}
Exemplo n.º 11
0
 /**
  * Returns a copy of this Period with the years and months normalized.
  *
  * This normalizes the years and months units, leaving the days unit unchanged.
  * The months unit is adjusted to have an absolute value less than 12,
  * with the years unit being adjusted to compensate. For example, a period of
  * "1 year and 15 months" will be normalized to "2 years and 3 months".
  *
  * The sign of the years and months units will be the same after normalization.
  * For example, a period of "1 year and -25 months" will be normalized to
  * "-1 year and -1 month".
  *
  * @return Period
  */
 public function normalized()
 {
     $totalMonths = $this->years * LocalTime::MONTHS_PER_YEAR + $this->months;
     $splitYears = intdiv($totalMonths, 12);
     $splitMonths = $totalMonths % 12;
     if ($splitYears === $this->years || $splitMonths === $this->months) {
         return $this;
     }
     return new Period($splitYears, $splitMonths, $this->days);
 }
Exemplo n.º 12
0
 /**
  * @expectedException DivisionByZeroError
  */
 public function testIntdivByZero()
 {
     intdiv(1, 0);
 }
Exemplo n.º 13
0
 /**
  * Get (and increment) the nonce for AES-CTR
  * 
  * @param int $increment
  * @return string
  */
 protected function getNonce(int $increment = 0) : string
 {
     $nonce = '';
     $ctr = $this->counter;
     while ($ctr > 0) {
         $nonce = \chr($ctr & 0xff) . $nonce;
         $ctr >>= 8;
     }
     $this->counter += intdiv($increment + $increment % 16, 16);
     return \str_pad($nonce, 16, "", STR_PAD_LEFT);
 }
Exemplo n.º 14
0
 /**
  * Used by all styles of Eve APIs to prepare and execute their SQL 'upsert' queries.
  *
  * 'Upsert' is a commonly used term for updating any existing rows in a table and inserting all the ones that don't
  * already exist together at one time.
  *
  * The method also tracks if the prepared query can be re-used or not to take fuller advantage of them in cases
  * where all queries have the same number of database rows as is common with some of the larger APIs and a few that
  * always have a fixed number of rows.
  *
  * @param string[] $columns
  * @param string[] $columnNames
  * @param string   $tableName
  *
  * @return self Fluent interface.
  * @throws \DomainException
  * @throws \InvalidArgumentException
  * @throws \LogicException
  */
 protected function flush(array $columns, array $columnNames, string $tableName)
 {
     if (0 === count($columns)) {
         return $this;
     }
     $rowCount = intdiv(count($columns), count($columnNames));
     $mess = sprintf('Have %1$s row(s) to upsert into %2$s table', $rowCount, $tableName);
     $this->getYem()->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $mess);
     $isNotPrepared = $this->lastColumnCount !== count($columnNames) || $this->lastRowCount !== $rowCount || null === $this->pdoStatement;
     if ($isNotPrepared) {
         $sql = $this->getCsq()->getUpsert($tableName, $columnNames, $rowCount);
         $mess = preg_replace('%(,\\([?,]*\\))+%', ',...', $sql);
         $lastError = preg_last_error();
         if (PREG_NO_ERROR !== $lastError) {
             $constants = array_flip(get_defined_constants(true)['pcre']);
             $lastError = $constants[$lastError];
             $mess = 'Received preg error ' . $lastError;
             throw new \DomainException($mess);
         }
         $this->getYem()->triggerLogEvent('Yapeal.Log.log', Logger::INFO, $mess);
         $this->pdoStatement = $this->getPdo()->prepare($sql);
         $this->lastColumnCount = count($columnNames);
         $this->lastRowCount = $rowCount;
     }
     $mess = '';
     foreach ($columns as $column) {
         $mess .= $column . ',';
         if (256 <= strlen($mess)) {
             break;
         }
     }
     $mess = substr($mess, 0, 256) . '...';
     $this->getYem()->triggerLogEvent('Yapeal.Log.log', Logger::DEBUG, $mess);
     $this->pdoStatement->execute($columns);
     return $this;
 }
Exemplo n.º 15
0
 /**
  * @expectedException ArithmeticError
  */
 public function testSmallestNumber()
 {
     intdiv(~PHP_INT_MAX, -1);
 }
Exemplo n.º 16
0
 /**
  * Returns a copy of this LocalTime with the specified period in seconds added.
  *
  * @param integer $seconds The seconds to add, may be negative.
  *
  * @return LocalTime A LocalTime based on this time with the seconds added.
  */
 public function plusSeconds($seconds)
 {
     $seconds = Cast::toInteger($seconds);
     if ($seconds === 0) {
         return $this;
     }
     $sofd = $this->hour * self::SECONDS_PER_HOUR + $this->minute * self::SECONDS_PER_MINUTE + $this->second;
     $newSofd = ($seconds % self::SECONDS_PER_DAY + $sofd + self::SECONDS_PER_DAY) % self::SECONDS_PER_DAY;
     if ($sofd === $newSofd) {
         return $this;
     }
     $hour = intdiv($newSofd, self::SECONDS_PER_HOUR);
     $minute = intdiv($newSofd, self::SECONDS_PER_MINUTE) % self::MINUTES_PER_HOUR;
     $second = $newSofd % self::SECONDS_PER_MINUTE;
     return new LocalTime($hour, $minute, $second, $this->nano);
 }
Exemplo n.º 17
0
 /**
  * @throws NegativeExponentException
  * @throws BaseIsZeroException
  * @param Integer $exp
  * @return Integer
  */
 public function power(Integer $exp) : Integer
 {
     if ($exp->isNegative()) {
         throw new NegativeExponentException();
     }
     if (0 == $this->value) {
         throw new BaseIsZeroException();
     }
     $value = 1;
     $expValue = $exp->getValue();
     $base = $this->value;
     while (0 < $expValue) {
         if ($expValue % 2 == 1) {
             $value *= $base;
         }
         $expValue = intdiv($expValue, 2);
         $base *= $base;
         // potential overflow
     }
     return new static($value);
 }
Exemplo n.º 18
0
 public function snoob(int $n) : int
 {
     if ($n === 0) {
         return $n;
     }
     $smallest = $n & -$n;
     $ripple = $n + $smallest;
     $ones = $n ^ $ripple;
     $ones = intdiv($ones >> 2, $smallest);
     return $ripple | $ones;
 }
Exemplo n.º 19
0
 public function __get(string $propertyName)
 {
     if ($propertyName === "length") {
         return intdiv($this->byteLength, static::BYTES_PER_ELEMENT);
     } else {
         return ArrayBufferView::__get($propertyName);
     }
 }
Exemplo n.º 20
0
 /**
  * Quartiles - Inclusive method (R method)
  * Three points that divide the data set into four equal groups, each group comprising a quarter of the data.
  * https://en.wikipedia.org/wiki/Quartile
  *
  * 0% is smallest number
  * Q1 (25%) is first quartile (lower quartile, 25th percentile)
  * Q2 (50%) is second quartile (median, 50th percentile)
  * Q3 (75%) is third quartile (upper quartile, 75th percentile)
  * 100% is largest number
  * interquartile_range is the difference between the upper and lower quartiles. (IQR = Q₃ - Q₁)
  *
  * Method used
  *  - Use the median to divide the ordered data set into two halves.
  *   - If there are an odd number of data points in the original ordered data set,
  *     include the median (the central value in the ordered list) in both halves.
  *   - If there are an even number of data points in the original ordered data set,
  *     split this data set exactly in half.
  *  - The lower quartile value is the median of the lower half of the data.
  *    The upper quartile value is the median of the upper half of the data.
  *
  * The values found by this method are also known as "Tukey's hinges".
  * This is the method that the programming language R uses by default.
  *
  * @param array $numbers
  * @return array [ 0%, Q1, Q2, Q3, 100%, IQR ]
  */
 public static function quartilesInclusive(array $numbers) : array
 {
     if (empty($numbers)) {
         return array();
     }
     sort($numbers);
     $length = count($numbers);
     if ($length % 2 == 0) {
         $lower_half = array_slice($numbers, 0, $length / 2);
         $upper_half = array_slice($numbers, $length / 2);
     } else {
         $lower_half = array_slice($numbers, 0, intdiv($length, 2));
         $upper_half = array_slice($numbers, intdiv($length, 2) + 1);
         // Add median to both halves
         $median = Average::median($numbers);
         array_push($lower_half, $median);
         array_unshift($upper_half, $median);
     }
     $lower_quartile = Average::median($lower_half);
     $upper_quartile = Average::median($upper_half);
     return ['0%' => min($numbers), 'Q1' => $lower_quartile, 'Q2' => Average::median($numbers), 'Q3' => $upper_quartile, '100%' => max($numbers), 'IQR' => $upper_quartile - $lower_quartile];
 }
Exemplo n.º 21
0
 /**
  * Return the given subnet for an IPv6 address and mask bits
  *
  * @param string $ip
  * @param int $maskBits
  * @return string
  */
 public function getIPv6Subnet(string $ip, int $maskBits = 48) : string
 {
     $binary = \inet_pton($ip);
     for ($i = 128; $i > $maskBits; $i -= 8) {
         $j = \intdiv($i, 8) - 1;
         $k = (int) \min(8, $i - $maskBits);
         $mask = 0xff - (2 ** $k - 1);
         $int = \unpack('C', $binary[$j]);
         $binary[$j] = \pack('C', $int[1] & $mask);
     }
     return \inet_ntop($binary) . '/' . $maskBits;
 }
Exemplo n.º 22
0
 /**
  * Returns the number of days since the UNIX epoch of 1st January 1970.
  *
  * @return integer
  */
 public function toEpochDay()
 {
     $y = $this->year;
     $m = $this->month;
     $total = 365 * $y;
     if ($y >= 0) {
         $total += intdiv($y + 3, 4) - intdiv($y + 99, 100) + intdiv($y + 399, 400);
     } else {
         $total -= intdiv($y, -4) - intdiv($y, -100) + intdiv($y, -400);
     }
     $total += intdiv(367 * $m - 362, 12);
     $total += $this->day - 1;
     if ($m > 2) {
         $total--;
         if (!$this->isLeapYear()) {
             $total--;
         }
     }
     return $total - self::DAYS_0000_TO_1970;
 }
Exemplo n.º 23
0
/**
 * Pager section
 *
 * @param array $§
 *
 * @return string
 */
function section_pager(array &$§) : string
{
    $§['vars'] += ['size' => 0, 'limit' => 0, 'links' => [], 'params' => []];
    if ($§['vars']['size'] < 1 || $§['vars']['limit'] < 1) {
        return '';
    }
    $§['vars']['pages'] = (int) ceil($§['vars']['size'] / $§['vars']['limit']);
    $§['vars']['page'] = max($§['vars']['params']['page'] ?? 0, 1);
    $§['vars']['offset'] = ($§['vars']['page'] - 1) * $§['vars']['limit'];
    unset($§['vars']['params']['page']);
    $c = max(0, data('limit', 'pager'));
    $min = max(1, min($§['vars']['page'] - intdiv($c, 2), $§['vars']['pages'] - $c + 1));
    $max = min($min + $c - 1, $§['vars']['pages']);
    if ($§['vars']['page'] >= 2) {
        $p = $§['vars']['page'] === 2 ? $§['vars']['params'] : ['page' => $§['vars']['page'] - 1] + $§['vars']['params'];
        $§['vars']['links'][] = ['name' => _('Previous'), 'params' => $p];
    }
    for ($i = $min; $min < $max && $i <= $max; $i++) {
        $p = $i > 1 ? ['page' => $i] + $§['vars']['params'] : $§['vars']['params'];
        $§['vars']['links'][] = ['name' => $i, 'params' => $p, 'active' => $i === $§['vars']['page']];
    }
    if ($§['vars']['page'] < $§['vars']['pages']) {
        $p = ['page' => $§['vars']['page'] + 1] + $§['vars']['params'];
        $§['vars']['links'][] = ['name' => _('Next'), 'params' => $p];
    }
    return render($§);
}
Exemplo n.º 24
0
<?php

var_dump(intdiv(100, 3));
//33 返回100的整数倍数
Exemplo n.º 25
0
<?php

// (int)(PHP_INT_MAX / 3) gives a different result
var_dump(intdiv(PHP_INT_MAX, 3));
Exemplo n.º 26
0
 /**
  * Get the value within a group (i.e. 1.0.3 => 1000300)
  * 
  * @param int $value An expanded version
  * @param int $group
  * @return int
  */
 public static function getGroup(int $value, int $group = self::GROUP_INCREMENT) : int
 {
     switch ($group) {
         // [W...W]XXYYZZ
         case self::GROUP_MAJOR:
             $left = $value - $value % self::GROUP_MAJOR;
             return intdiv($left, self::GROUP_MAJOR);
             // W...W[XX]YYZZ
         // W...W[XX]YYZZ
         case self::GROUP_MINOR:
             $left = $value - $value % self::GROUP_MINOR;
             $left %= self::GROUP_MAJOR;
             return intdiv($left, self::GROUP_MINOR);
             // W...WXX[YY]ZZ
         // W...WXX[YY]ZZ
         case self::GROUP_PATCH:
             $left = $value - $value % self::GROUP_PATCH;
             $left %= self::GROUP_MINOR;
             return intdiv($left, self::GROUP_PATCH);
         default:
             throw new \InvalidArgumentException(\__('%s: $group must be a constant', 'default', __METHOD__));
     }
 }
Exemplo n.º 27
0
<?php

// Convert $total_minutes to hours and minutes.
$total_minutes = 640;
$minutes = $total_minutes % 60;
//$hours = ($total_minutes - $minutes) / 60;
$hours = intdiv($total_minutes, 60);
echo "Time taken was {$hours} hours {$minutes} minutes";
Exemplo n.º 28
0
 /**
  * This method returns the result of dividing the specified value against this object's
  * value.
  *
  * @access public
  * @static
  * @param IInt32\Type $x                                    the left operand
  * @param IInt32\Type $y                                    the right operand
  * @return IInt32\Type                                      the result
  */
 public static function divide(IInt32\Type $x, IInt32\Type $y) : IInt32\Type
 {
     return IInt32\Type::box(intdiv($x->unbox(), $y->unbox()));
 }
Exemplo n.º 29
0
 /**
  * Returns a copy of this `LocalDateTime` with the specified period added.
  *
  * @param integer $hours   The hours to add, validated as an integer. May be negative.
  * @param integer $minutes The minutes to add, validated as an integer. May be negative.
  * @param integer $seconds The seconds to add, validated as an integer. May be negative.
  * @param integer $nanos   The nanos to add, validated as an integer. May be negative.
  * @param integer $sign    The sign, validated as an integer of value `1` to add or `-1` to subtract.
  *
  * @return LocalDateTime The combined result.
  */
 private function plusWithOverflow($hours, $minutes, $seconds, $nanos, $sign)
 {
     $totDays = intdiv($hours, LocalTime::HOURS_PER_DAY) + intdiv($minutes, LocalTime::MINUTES_PER_DAY) + intdiv($seconds, LocalTime::SECONDS_PER_DAY);
     $totDays *= $sign;
     $totSeconds = $seconds % LocalTime::SECONDS_PER_DAY + $minutes % LocalTime::MINUTES_PER_DAY * LocalTime::SECONDS_PER_MINUTE + $hours % LocalTime::HOURS_PER_DAY * LocalTime::SECONDS_PER_HOUR;
     $curSoD = $this->time->toSecondOfDay();
     $totSeconds = $totSeconds * $sign + $curSoD;
     $totNanos = $nanos * $sign + $this->time->getNano();
     $totSeconds += Math::floorDiv($totNanos, LocalTime::NANOS_PER_SECOND);
     $newNano = Math::floorMod($totNanos, LocalTime::NANOS_PER_SECOND);
     $totDays += Math::floorDiv($totSeconds, LocalTime::SECONDS_PER_DAY);
     $newSoD = Math::floorMod($totSeconds, LocalTime::SECONDS_PER_DAY);
     $newTime = $newSoD === $curSoD ? $this->time : LocalTime::ofSecondOfDay($newSoD, $newNano);
     return $this->with($this->date->plusDays($totDays), $newTime);
 }
Exemplo n.º 30
0
 /**
  * Write the data to file name using randomized tmp file, exclusive locking, and time limits.
  *
  * Things that can cause write to fail:
  *
  *   * Unable to acquire exclusive file handle within calculated time or tries limits.
  *   * Write stalls without making any progress or repeatedly stalls to often.
  *   * Exceeds estimated write time based on file size with 2 second minimum enforced.
  *
  * @param string $pathFile File name with absolute path.
  *
  * @param string $data     Contents to be written to file.
  *
  * @return bool Returns true if contents written, false on any problem that prevents write.
  */
 private function safeDataWrite(string $pathFile, string $data) : bool
 {
     $amountToWrite = strlen($data);
     // Buffer size between 4KB and 256KB with 16MB file size uses a 100KB buffer.
     $bufferSize = (int) (1 + floor(log($amountToWrite, 2))) << 12;
     // Write timeout calculated by using file size and write speed of
     // 16MB/sec with 2 second minimum time enforced.
     $timeout = max(2, intdiv($amountToWrite, 1 << 24));
     $handle = $this->acquireLockedHandle($pathFile, $timeout);
     if (false === $handle) {
         return false;
     }
     $dataWritten = 0;
     $tries = 0;
     $timeout = time() + $timeout;
     while ($dataWritten < $amountToWrite) {
         if (++$tries > 10 || time() > $timeout) {
             $this->releaseHandle($handle);
             $this->deleteWithRetry($pathFile);
             return false;
         }
         $written = fwrite($handle, substr($data, $dataWritten, $bufferSize));
         // Decrease $tries while making progress but NEVER $tries <= 0.
         if ($written > 0 && $tries > 0) {
             --$tries;
         }
         $dataWritten += $written;
     }
     $this->releaseHandle($handle);
     return true;
 }