PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.8
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / openspout / openspout / src / Reader / XLSX / Helper / DateFormatHelper.php

DateFormatHelper.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 4.0.8, at vendor/openspout/openspout/src/Reader/XLSX/Helper/DateFormatHelper.php

123 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace OpenSpout\Reader\XLSX\Helper;
4
5 /**
6 * This class provides helper functions to format Excel dates.
7 */
8 class DateFormatHelper
9 {
10 public const KEY_GENERAL = 'general';
11 public const KEY_HOUR_12 = '12h';
12 public const KEY_HOUR_24 = '24h';
13
14 /**
15 * This map is used to replace Excel format characters by their PHP equivalent.
16 * Keys should be ordered from longest to smallest.
17 *
18 * @var array Mapping between Excel format characters and PHP format characters
19 */
20 private static $excelDateFormatToPHPDateFormatMapping = [
21 self::KEY_GENERAL => [
22 // Time
23 'am/pm' => 'A', // Uppercase Ante meridiem and Post meridiem
24 ':mm' => ':i', // Minutes with leading zeros - if preceded by a ":" (otherwise month)
25 'mm:' => 'i:', // Minutes with leading zeros - if followed by a ":" (otherwise month)
26 'ss' => 's', // Seconds, with leading zeros
27 '.s' => '', // Ignore (fractional seconds format does not exist in PHP)
28
29 // Date
30 'e' => 'Y', // Full numeric representation of a year, 4 digits
31 'yyyy' => 'Y', // Full numeric representation of a year, 4 digits
32 'yy' => 'y', // Two digit representation of a year
33 'mmmmm' => 'M', // Short textual representation of a month, three letters ("mmmmm" should only contain the 1st letter...)
34 'mmmm' => 'F', // Full textual representation of a month
35 'mmm' => 'M', // Short textual representation of a month, three letters
36 'mm' => 'm', // Numeric representation of a month, with leading zeros
37 'm' => 'n', // Numeric representation of a month, without leading zeros
38 'dddd' => 'l', // Full textual representation of the day of the week
39 'ddd' => 'D', // Textual representation of a day, three letters
40 'dd' => 'd', // Day of the month, 2 digits with leading zeros
41 'd' => 'j', // Day of the month without leading zeros
42 ],
43 self::KEY_HOUR_12 => [
44 'hh' => 'h', // 12-hour format of an hour without leading zeros
45 'h' => 'g', // 12-hour format of an hour without leading zeros
46 ],
47 self::KEY_HOUR_24 => [
48 'hh' => 'H', // 24-hour hours with leading zero
49 'h' => 'G', // 24-hour format of an hour without leading zeros
50 ],
51 ];
52
53 /**
54 * Converts the given Excel date format to a format understandable by the PHP date function.
55 *
56 * @param string $excelDateFormat Excel date format
57 *
58 * @return string PHP date format (as defined here: http://php.net/manual/en/function.date.php)
59 */
60 public static function toPHPDateFormat($excelDateFormat)
61 {
62 // Remove brackets potentially present at the beginning of the format string
63 // and text portion of the format at the end of it (starting with ";")
64 // See §18.8.31 of ECMA-376 for more detail.
65 $dateFormat = preg_replace('/^(?:\[\$[^\]]+?\])?([^;]*).*/', '$1', $excelDateFormat);
66
67 // Double quotes are used to escape characters that must not be interpreted.
68 // For instance, ["Day " dd] should result in "Day 13" and we should not try to interpret "D", "a", "y"
69 // By exploding the format string using double quote as a delimiter, we can get all parts
70 // that must be transformed (even indexes) and all parts that must not be (odd indexes).
71 $dateFormatParts = explode('"', $dateFormat);
72
73 foreach ($dateFormatParts as $partIndex => $dateFormatPart) {
74 // do not look at odd indexes
75 if (1 === $partIndex % 2) {
76 continue;
77 }
78
79 // Make sure all characters are lowercase, as the mapping table is using lowercase characters
80 $transformedPart = strtolower($dateFormatPart);
81
82 // Remove escapes related to non-format characters
83 $transformedPart = str_replace('\\', '', $transformedPart);
84
85 // Apply general transformation first...
86 $transformedPart = strtr($transformedPart, self::$excelDateFormatToPHPDateFormatMapping[self::KEY_GENERAL]);
87
88 // ... then apply hour transformation, for 12-hour or 24-hour format
89 if (self::has12HourFormatMarker($dateFormatPart)) {
90 $transformedPart = strtr($transformedPart, self::$excelDateFormatToPHPDateFormatMapping[self::KEY_HOUR_12]);
91 } else {
92 $transformedPart = strtr($transformedPart, self::$excelDateFormatToPHPDateFormatMapping[self::KEY_HOUR_24]);
93 }
94
95 // overwrite the parts array with the new transformed part
96 $dateFormatParts[$partIndex] = $transformedPart;
97 }
98
99 // Merge all transformed parts back together
100 $phpDateFormat = implode('"', $dateFormatParts);
101
102 // Finally, to have the date format compatible with the DateTime::format() function, we need to escape
103 // all characters that are inside double quotes (and double quotes must be removed).
104 // For instance, ["Day " dd] should become [\D\a\y\ dd]
105 return preg_replace_callback('/"(.+?)"/', function ($matches) {
106 $stringToEscape = $matches[1];
107 $letters = preg_split('//u', $stringToEscape, -1, PREG_SPLIT_NO_EMPTY);
108
109 return '\\'.implode('\\', $letters);
110 }, $phpDateFormat);
111 }
112
113 /**
114 * @param string $excelDateFormat Date format as defined by Excel
115 *
116 * @return bool Whether the given date format has the 12-hour format marker
117 */
118 private static function has12HourFormatMarker($excelDateFormat)
119 {
120 return false !== stripos($excelDateFormat, 'am/pm');
121 }
122 }
123