Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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 null|array|bool|float|int|string $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 null|array|bool|float|int|string $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 null|array|bool|float|int|string $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|DateTime|float|int|string 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(array|int|float|bool|null|string $hour, array|int|float|bool|null|string $minute, array|int|float|bool|null|string $second): array|string|float|int|DateTime
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 += (int) floor($second / 60);
91
            $second = 60 - abs($second % 60);
92
            if ($second == 60) {
93
                $second = 0;
94
            }
95
        } elseif ($second >= 60) {
96
            $minute += intdiv($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 += (int) floor($minute / 60);
105
            $minute = 60 - abs($minute % 60);
106
            if ($minute == 60) {
107
                $minute = 0;
108
            }
109
        } elseif ($minute >= 60) {
110
            $hour += intdiv($minute, 60);
111
            $minute = $minute % 60;
112
        }
113
    }
114
 
115
    /**
116
     * @param mixed $value expect int
117
     */
118
    private static function toIntWithNullBool(mixed $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
}