Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 400 and 401]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
   4  
   5  use DateTime;
   6  use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
   7  use PhpOffice\PhpSpreadsheet\Calculation\Exception;
   8  use PhpOffice\PhpSpreadsheet\Calculation\Functions;
   9  use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
  10  use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
  11  
  12  class Time
  13  {
  14      use ArrayEnabled;
  15  
  16      /**
  17       * TIME.
  18       *
  19       * The TIME function returns a value that represents a particular time.
  20       *
  21       * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time
  22       * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way.
  23       *
  24       * Excel Function:
  25       *        TIME(hour,minute,second)
  26       *
  27       * @param array|int $hour A number from 0 (zero) to 32767 representing the hour.
  28       *                                    Any value greater than 23 will be divided by 24 and the remainder
  29       *                                    will be treated as the hour value. For example, TIME(27,0,0) =
  30       *                                    TIME(3,0,0) = .125 or 3:00 AM.
  31       * @param array|int $minute A number from 0 to 32767 representing the minute.
  32       *                                    Any value greater than 59 will be converted to hours and minutes.
  33       *                                    For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM.
  34       * @param array|int $second A number from 0 to 32767 representing the second.
  35       *                                    Any value greater than 59 will be converted to hours, minutes,
  36       *                                    and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148
  37       *                                    or 12:33:20 AM
  38       *         If an array of numbers is passed as the argument, then the returned result will also be an array
  39       *            with the same dimensions
  40       *
  41       * @return array|mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object,
  42       *                        depending on the value of the ReturnDateType flag
  43       *         If an array of numbers is passed as the argument, then the returned result will also be an array
  44       *            with the same dimensions
  45       */
  46      public static function fromHMS($hour, $minute, $second)
  47      {
  48          if (is_array($hour) || is_array($minute) || is_array($second)) {
  49              return self::evaluateArrayArguments([self::class, __FUNCTION__], $hour, $minute, $second);
  50          }
  51  
  52          try {
  53              $hour = self::toIntWithNullBool($hour);
  54              $minute = self::toIntWithNullBool($minute);
  55              $second = self::toIntWithNullBool($second);
  56          } catch (Exception $e) {
  57              return $e->getMessage();
  58          }
  59  
  60          self::adjustSecond($second, $minute);
  61          self::adjustMinute($minute, $hour);
  62  
  63          if ($hour > 23) {
  64              $hour = $hour % 24;
  65          } elseif ($hour < 0) {
  66              return ExcelError::NAN();
  67          }
  68  
  69          // Execute function
  70          $retType = Functions::getReturnDateType();
  71          if ($retType === Functions::RETURNDATE_EXCEL) {
  72              $calendar = SharedDateHelper::getExcelCalendar();
  73              $date = (int) ($calendar !== SharedDateHelper::CALENDAR_WINDOWS_1900);
  74  
  75              return (float) SharedDateHelper::formattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second);
  76          }
  77          if ($retType === Functions::RETURNDATE_UNIX_TIMESTAMP) {
  78              return (int) SharedDateHelper::excelToTimestamp(SharedDateHelper::formattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; //    -2147472000 + 3600
  79          }
  80          // RETURNDATE_PHP_DATETIME_OBJECT
  81          // Hour has already been normalized (0-23) above
  82          $phpDateObject = new DateTime('1900-01-01 ' . $hour . ':' . $minute . ':' . $second);
  83  
  84          return $phpDateObject;
  85      }
  86  
  87      private static function adjustSecond(int &$second, int &$minute): void
  88      {
  89          if ($second < 0) {
  90              $minute += floor($second / 60);
  91              $second = 60 - abs($second % 60);
  92              if ($second == 60) {
  93                  $second = 0;
  94              }
  95          } elseif ($second >= 60) {
  96              $minute += floor($second / 60);
  97              $second = $second % 60;
  98          }
  99      }
 100  
 101      private static function adjustMinute(int &$minute, int &$hour): void
 102      {
 103          if ($minute < 0) {
 104              $hour += floor($minute / 60);
 105              $minute = 60 - abs($minute % 60);
 106              if ($minute == 60) {
 107                  $minute = 0;
 108              }
 109          } elseif ($minute >= 60) {
 110              $hour += floor($minute / 60);
 111              $minute = $minute % 60;
 112          }
 113      }
 114  
 115      /**
 116       * @param mixed $value expect int
 117       */
 118      private static function toIntWithNullBool($value): int
 119      {
 120          $value = $value ?? 0;
 121          if (is_bool($value)) {
 122              $value = (int) $value;
 123          }
 124          if (!is_numeric($value)) {
 125              throw new Exception(ExcelError::VALUE());
 126          }
 127  
 128          return (int) $value;
 129      }
 130  }