1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpOffice\PhpSpreadsheet\Style; |
4
|
|
|
|
5
|
|
|
use PhpOffice\PhpSpreadsheet\RichText\RichText; |
6
|
|
|
|
7
|
|
|
class NumberFormat extends Supervisor |
8
|
|
|
{ |
9
|
|
|
// Pre-defined formats |
10
|
|
|
const FORMAT_GENERAL = 'General'; |
11
|
|
|
|
12
|
|
|
const FORMAT_TEXT = '@'; |
13
|
|
|
|
14
|
|
|
const FORMAT_NUMBER = '0'; |
15
|
|
|
const FORMAT_NUMBER_0 = '0.0'; |
16
|
|
|
const FORMAT_NUMBER_00 = '0.00'; |
17
|
|
|
const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00'; |
18
|
|
|
const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-'; |
19
|
|
|
|
20
|
|
|
const FORMAT_PERCENTAGE = '0%'; |
21
|
|
|
const FORMAT_PERCENTAGE_0 = '0.0%'; |
22
|
|
|
const FORMAT_PERCENTAGE_00 = '0.00%'; |
23
|
|
|
|
24
|
|
|
const FORMAT_DATE_YYYYMMDD = 'yyyy-mm-dd'; |
25
|
|
|
const FORMAT_DATE_DDMMYYYY = 'dd/mm/yyyy'; |
26
|
|
|
const FORMAT_DATE_DMYSLASH = 'd/m/yy'; |
27
|
|
|
const FORMAT_DATE_DMYMINUS = 'd-m-yy'; |
28
|
|
|
const FORMAT_DATE_DMMINUS = 'd-m'; |
29
|
|
|
const FORMAT_DATE_MYMINUS = 'm-yy'; |
30
|
|
|
const FORMAT_DATE_XLSX14 = 'mm-dd-yy'; |
31
|
|
|
const FORMAT_DATE_XLSX14_ACTUAL = 'm/d/yyyy'; |
32
|
|
|
const FORMAT_DATE_XLSX15 = 'd-mmm-yy'; |
33
|
|
|
const FORMAT_DATE_XLSX16 = 'd-mmm'; |
34
|
|
|
const FORMAT_DATE_XLSX17 = 'mmm-yy'; |
35
|
|
|
const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm'; |
36
|
|
|
const FORMAT_DATE_XLSX22_ACTUAL = 'm/d/yyyy h:mm'; |
37
|
|
|
const FORMAT_DATE_DATETIME = 'd/m/yy h:mm'; |
38
|
|
|
const FORMAT_DATE_TIME1 = 'h:mm AM/PM'; |
39
|
|
|
const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM'; |
40
|
|
|
const FORMAT_DATE_TIME3 = 'h:mm'; |
41
|
|
|
const FORMAT_DATE_TIME4 = 'h:mm:ss'; |
42
|
|
|
const FORMAT_DATE_TIME5 = 'mm:ss'; |
43
|
|
|
const FORMAT_DATE_TIME6 = 'h:mm:ss'; |
44
|
|
|
const FORMAT_DATE_TIME7 = 'i:s.S'; |
45
|
|
|
const FORMAT_DATE_TIME8 = 'h:mm:ss;@'; |
46
|
|
|
const FORMAT_DATE_YYYYMMDDSLASH = 'yyyy/mm/dd;@'; |
47
|
|
|
const FORMAT_DATE_LONG_DATE = 'dddd, mmmm d, yyyy'; |
48
|
|
|
|
49
|
|
|
const DATE_TIME_OR_DATETIME_ARRAY = [ |
50
|
|
|
self::FORMAT_DATE_YYYYMMDD, |
51
|
|
|
self::FORMAT_DATE_DDMMYYYY, |
52
|
|
|
self::FORMAT_DATE_DMYSLASH, |
53
|
|
|
self::FORMAT_DATE_DMYMINUS, |
54
|
|
|
self::FORMAT_DATE_DMMINUS, |
55
|
|
|
self::FORMAT_DATE_MYMINUS, |
56
|
|
|
self::FORMAT_DATE_XLSX14, |
57
|
|
|
self::FORMAT_DATE_XLSX14_ACTUAL, |
58
|
|
|
self::FORMAT_DATE_XLSX15, |
59
|
|
|
self::FORMAT_DATE_XLSX16, |
60
|
|
|
self::FORMAT_DATE_XLSX17, |
61
|
|
|
self::FORMAT_DATE_XLSX22, |
62
|
|
|
self::FORMAT_DATE_XLSX22_ACTUAL, |
63
|
|
|
self::FORMAT_DATE_DATETIME, |
64
|
|
|
self::FORMAT_DATE_TIME1, |
65
|
|
|
self::FORMAT_DATE_TIME2, |
66
|
|
|
self::FORMAT_DATE_TIME3, |
67
|
|
|
self::FORMAT_DATE_TIME4, |
68
|
|
|
self::FORMAT_DATE_TIME5, |
69
|
|
|
self::FORMAT_DATE_TIME6, |
70
|
|
|
self::FORMAT_DATE_TIME7, |
71
|
|
|
self::FORMAT_DATE_TIME8, |
72
|
|
|
self::FORMAT_DATE_YYYYMMDDSLASH, |
73
|
|
|
self::FORMAT_DATE_LONG_DATE, |
74
|
|
|
]; |
75
|
|
|
const TIME_OR_DATETIME_ARRAY = [ |
76
|
|
|
self::FORMAT_DATE_XLSX22, |
77
|
|
|
self::FORMAT_DATE_DATETIME, |
78
|
|
|
self::FORMAT_DATE_TIME1, |
79
|
|
|
self::FORMAT_DATE_TIME2, |
80
|
|
|
self::FORMAT_DATE_TIME3, |
81
|
|
|
self::FORMAT_DATE_TIME4, |
82
|
|
|
self::FORMAT_DATE_TIME5, |
83
|
|
|
self::FORMAT_DATE_TIME6, |
84
|
|
|
self::FORMAT_DATE_TIME7, |
85
|
|
|
self::FORMAT_DATE_TIME8, |
86
|
|
|
]; |
87
|
|
|
|
88
|
|
|
const FORMAT_CURRENCY_USD_INTEGER = '$#,##0_-'; |
89
|
|
|
const FORMAT_CURRENCY_USD = '$#,##0.00_-'; |
90
|
|
|
const FORMAT_CURRENCY_EUR_INTEGER = '#,##0_-[$€]'; |
91
|
|
|
const FORMAT_CURRENCY_EUR = '#,##0.00_-[$€]'; |
92
|
|
|
const FORMAT_ACCOUNTING_USD = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; |
93
|
|
|
const FORMAT_ACCOUNTING_EUR = '_("€"* #,##0.00_);_("€"* \(#,##0.00\);_("€"* "-"??_);_(@_)'; |
94
|
|
|
|
95
|
|
|
const SHORT_DATE_INDEX = 14; |
96
|
|
|
const DATE_TIME_INDEX = 22; |
97
|
|
|
const FORMAT_SYSDATE_X = '[$-x-sysdate]'; |
98
|
|
|
const FORMAT_SYSDATE_F800 = '[$-F800]'; |
99
|
|
|
const FORMAT_SYSTIME_X = '[$-x-systime]'; |
100
|
|
|
const FORMAT_SYSTIME_F400 = '[$-F400]'; |
101
|
|
|
|
102
|
|
|
protected static string $shortDateFormat = self::FORMAT_DATE_XLSX14_ACTUAL; |
103
|
|
|
|
104
|
|
|
protected static string $longDateFormat = self::FORMAT_DATE_LONG_DATE; |
105
|
|
|
|
106
|
|
|
protected static string $dateTimeFormat = self::FORMAT_DATE_XLSX22_ACTUAL; |
107
|
|
|
|
108
|
|
|
protected static string $timeFormat = self::FORMAT_DATE_TIME2; |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Excel built-in number formats. |
112
|
|
|
*/ |
113
|
|
|
protected static array $builtInFormats; |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Excel built-in number formats (flipped, for faster lookups). |
117
|
|
|
*/ |
118
|
|
|
protected static array $flippedBuiltInFormats; |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Format Code. |
122
|
|
|
*/ |
123
|
|
|
protected ?string $formatCode = self::FORMAT_GENERAL; |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Built-in format Code. |
127
|
|
|
* |
128
|
|
|
* @var false|int |
129
|
|
|
*/ |
130
|
|
|
protected $builtInFormatCode = 0; |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Create a new NumberFormat. |
134
|
|
|
* |
135
|
|
|
* @param bool $isSupervisor Flag indicating if this is a supervisor or not |
136
|
|
|
* Leave this value at default unless you understand exactly what |
137
|
|
|
* its ramifications are |
138
|
|
|
* @param bool $isConditional Flag indicating if this is a conditional style or not |
139
|
|
|
* Leave this value at default unless you understand exactly what |
140
|
|
|
* its ramifications are |
141
|
|
|
*/ |
142
|
10579 |
|
public function __construct(bool $isSupervisor = false, bool $isConditional = false) |
143
|
|
|
{ |
144
|
|
|
// Supervisor? |
145
|
10579 |
|
parent::__construct($isSupervisor); |
146
|
|
|
|
147
|
10579 |
|
if ($isConditional) { |
148
|
402 |
|
$this->formatCode = null; |
149
|
402 |
|
$this->builtInFormatCode = false; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Get the shared style component for the currently active cell in currently active sheet. |
155
|
|
|
* Only used for style supervisor. |
156
|
|
|
*/ |
157
|
129 |
|
public function getSharedComponent(): self |
158
|
|
|
{ |
159
|
|
|
/** @var Style $parent */ |
160
|
129 |
|
$parent = $this->parent; |
161
|
|
|
|
162
|
129 |
|
return $parent->getSharedComponent()->getNumberFormat(); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Build style array from subcomponents. |
167
|
|
|
*/ |
168
|
675 |
|
public function getStyleArray(array $array): array |
169
|
|
|
{ |
170
|
675 |
|
return ['numberFormat' => $array]; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Apply styles from array. |
175
|
|
|
* |
176
|
|
|
* <code> |
177
|
|
|
* $spreadsheet->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray( |
178
|
|
|
* [ |
179
|
|
|
* 'formatCode' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE |
180
|
|
|
* ] |
181
|
|
|
* ); |
182
|
|
|
* </code> |
183
|
|
|
* |
184
|
|
|
* @param array $styleArray Array containing style information |
185
|
|
|
* |
186
|
|
|
* @return $this |
187
|
|
|
*/ |
188
|
713 |
|
public function applyFromArray(array $styleArray): static |
189
|
|
|
{ |
190
|
713 |
|
if ($this->isSupervisor) { |
191
|
1 |
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($styleArray)); |
192
|
|
|
} else { |
193
|
713 |
|
if (isset($styleArray['formatCode'])) { |
194
|
713 |
|
$this->setFormatCode($styleArray['formatCode']); |
195
|
|
|
} |
196
|
|
|
} |
197
|
|
|
|
198
|
713 |
|
return $this; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Get Format Code. |
203
|
|
|
*/ |
204
|
866 |
|
public function getFormatCode(bool $extended = false): ?string |
205
|
|
|
{ |
206
|
866 |
|
if ($this->isSupervisor) { |
207
|
129 |
|
return $this->getSharedComponent()->getFormatCode($extended); |
208
|
|
|
} |
209
|
866 |
|
$builtin = $this->getBuiltInFormatCode(); |
210
|
866 |
|
if (is_int($builtin)) { |
211
|
448 |
|
if ($extended) { |
212
|
107 |
|
if ($builtin === self::SHORT_DATE_INDEX) { |
213
|
2 |
|
return self::$shortDateFormat; |
214
|
|
|
} |
215
|
107 |
|
if ($builtin === self::DATE_TIME_INDEX) { |
216
|
2 |
|
return self::$dateTimeFormat; |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
446 |
|
return self::builtInFormatCode($builtin); |
221
|
|
|
} |
222
|
|
|
|
223
|
486 |
|
return $extended ? self::convertSystemFormats($this->formatCode) : $this->formatCode; |
224
|
|
|
} |
225
|
|
|
|
226
|
175 |
|
public static function convertSystemFormats(?string $formatCode): ?string |
227
|
|
|
{ |
228
|
175 |
|
if (is_string($formatCode)) { |
229
|
175 |
|
if (stripos($formatCode, self::FORMAT_SYSDATE_F800) !== false || stripos($formatCode, self::FORMAT_SYSDATE_X) !== false) { |
230
|
5 |
|
return self::$longDateFormat; |
231
|
|
|
} |
232
|
173 |
|
if (stripos($formatCode, self::FORMAT_SYSTIME_F400) !== false || stripos($formatCode, self::FORMAT_SYSTIME_X) !== false) { |
233
|
4 |
|
return self::$timeFormat; |
234
|
|
|
} |
235
|
|
|
} |
236
|
|
|
|
237
|
169 |
|
return $formatCode; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Set Format Code. |
242
|
|
|
* |
243
|
|
|
* @param string $formatCode see self::FORMAT_* |
244
|
|
|
* |
245
|
|
|
* @return $this |
246
|
|
|
*/ |
247
|
1486 |
|
public function setFormatCode(string $formatCode): static |
248
|
|
|
{ |
249
|
1486 |
|
if ($formatCode == '') { |
250
|
16 |
|
$formatCode = self::FORMAT_GENERAL; |
251
|
|
|
} |
252
|
1486 |
|
if ($this->isSupervisor) { |
253
|
674 |
|
$styleArray = $this->getStyleArray(['formatCode' => $formatCode]); |
254
|
674 |
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
255
|
|
|
} else { |
256
|
1476 |
|
$this->formatCode = $formatCode; |
257
|
1476 |
|
$this->builtInFormatCode = self::builtInFormatCodeIndex($formatCode); |
258
|
|
|
} |
259
|
|
|
|
260
|
1476 |
|
return $this; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Get Built-In Format Code. |
265
|
|
|
* |
266
|
|
|
* @return false|int |
267
|
|
|
*/ |
268
|
1201 |
|
public function getBuiltInFormatCode() |
269
|
|
|
{ |
270
|
1201 |
|
if ($this->isSupervisor) { |
271
|
1 |
|
return $this->getSharedComponent()->getBuiltInFormatCode(); |
272
|
|
|
} |
273
|
|
|
|
274
|
1201 |
|
return $this->builtInFormatCode; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Set Built-In Format Code. |
279
|
|
|
* |
280
|
|
|
* @param int $formatCodeIndex Id of the built-in format code to use |
281
|
|
|
* |
282
|
|
|
* @return $this |
283
|
|
|
*/ |
284
|
3 |
|
public function setBuiltInFormatCode(int $formatCodeIndex): static |
285
|
|
|
{ |
286
|
3 |
|
if ($this->isSupervisor) { |
287
|
3 |
|
$styleArray = $this->getStyleArray(['formatCode' => self::builtInFormatCode($formatCodeIndex)]); |
288
|
3 |
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
289
|
|
|
} else { |
290
|
1 |
|
$this->builtInFormatCode = $formatCodeIndex; |
291
|
1 |
|
$this->formatCode = self::builtInFormatCode($formatCodeIndex); |
292
|
|
|
} |
293
|
|
|
|
294
|
3 |
|
return $this; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Fill built-in format codes. |
299
|
|
|
*/ |
300
|
1697 |
|
private static function fillBuiltInFormatCodes(): void |
301
|
|
|
{ |
302
|
|
|
// [MS-OI29500: Microsoft Office Implementation Information for ISO/IEC-29500 Standard Compliance] |
303
|
|
|
// 18.8.30. numFmt (Number Format) |
304
|
|
|
// |
305
|
|
|
// The ECMA standard defines built-in format IDs |
306
|
|
|
// 14: "mm-dd-yy" |
307
|
|
|
// 22: "m/d/yy h:mm" |
308
|
|
|
// 37: "#,##0 ;(#,##0)" |
309
|
|
|
// 38: "#,##0 ;[Red](#,##0)" |
310
|
|
|
// 39: "#,##0.00;(#,##0.00)" |
311
|
|
|
// 40: "#,##0.00;[Red](#,##0.00)" |
312
|
|
|
// 47: "mmss.0" |
313
|
|
|
// KOR fmt 55: "yyyy-mm-dd" |
314
|
|
|
// Excel defines built-in format IDs |
315
|
|
|
// 14: "m/d/yyyy" |
316
|
|
|
// 22: "m/d/yyyy h:mm" |
317
|
|
|
// 37: "#,##0_);(#,##0)" |
318
|
|
|
// 38: "#,##0_);[Red](#,##0)" |
319
|
|
|
// 39: "#,##0.00_);(#,##0.00)" |
320
|
|
|
// 40: "#,##0.00_);[Red](#,##0.00)" |
321
|
|
|
// 47: "mm:ss.0" |
322
|
|
|
// KOR fmt 55: "yyyy/mm/dd" |
323
|
|
|
|
324
|
|
|
// Built-in format codes |
325
|
1697 |
|
if (empty(self::$builtInFormats)) { |
326
|
171 |
|
self::$builtInFormats = []; |
327
|
|
|
|
328
|
|
|
// General |
329
|
171 |
|
self::$builtInFormats[0] = self::FORMAT_GENERAL; |
330
|
171 |
|
self::$builtInFormats[1] = '0'; |
331
|
171 |
|
self::$builtInFormats[2] = '0.00'; |
332
|
171 |
|
self::$builtInFormats[3] = '#,##0'; |
333
|
171 |
|
self::$builtInFormats[4] = '#,##0.00'; |
334
|
|
|
|
335
|
171 |
|
self::$builtInFormats[9] = '0%'; |
336
|
171 |
|
self::$builtInFormats[10] = '0.00%'; |
337
|
171 |
|
self::$builtInFormats[11] = '0.00E+00'; |
338
|
171 |
|
self::$builtInFormats[12] = '# ?/?'; |
339
|
171 |
|
self::$builtInFormats[13] = '# ??/??'; |
340
|
171 |
|
self::$builtInFormats[14] = self::FORMAT_DATE_XLSX14_ACTUAL; // Despite ECMA 'mm-dd-yy'; |
341
|
171 |
|
self::$builtInFormats[15] = self::FORMAT_DATE_XLSX15; |
342
|
171 |
|
self::$builtInFormats[16] = 'd-mmm'; |
343
|
171 |
|
self::$builtInFormats[17] = 'mmm-yy'; |
344
|
171 |
|
self::$builtInFormats[18] = 'h:mm AM/PM'; |
345
|
171 |
|
self::$builtInFormats[19] = 'h:mm:ss AM/PM'; |
346
|
171 |
|
self::$builtInFormats[20] = 'h:mm'; |
347
|
171 |
|
self::$builtInFormats[21] = 'h:mm:ss'; |
348
|
171 |
|
self::$builtInFormats[22] = self::FORMAT_DATE_XLSX22_ACTUAL; // Despite ECMA 'm/d/yy h:mm'; |
349
|
|
|
|
350
|
171 |
|
self::$builtInFormats[37] = '#,##0_);(#,##0)'; // Despite ECMA '#,##0 ;(#,##0)'; |
351
|
171 |
|
self::$builtInFormats[38] = '#,##0_);[Red](#,##0)'; // Despite ECMA '#,##0 ;[Red](#,##0)'; |
352
|
171 |
|
self::$builtInFormats[39] = '#,##0.00_);(#,##0.00)'; // Despite ECMA '#,##0.00;(#,##0.00)'; |
353
|
171 |
|
self::$builtInFormats[40] = '#,##0.00_);[Red](#,##0.00)'; // Despite ECMA '#,##0.00;[Red](#,##0.00)'; |
354
|
|
|
|
355
|
171 |
|
self::$builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; |
356
|
171 |
|
self::$builtInFormats[45] = 'mm:ss'; |
357
|
171 |
|
self::$builtInFormats[46] = '[h]:mm:ss'; |
358
|
171 |
|
self::$builtInFormats[47] = 'mm:ss.0'; // Despite ECMA 'mmss.0'; |
359
|
171 |
|
self::$builtInFormats[48] = '##0.0E+0'; |
360
|
171 |
|
self::$builtInFormats[49] = '@'; |
361
|
|
|
|
362
|
|
|
// CHT |
363
|
171 |
|
self::$builtInFormats[27] = '[$-404]e/m/d'; |
364
|
171 |
|
self::$builtInFormats[30] = 'm/d/yy'; |
365
|
171 |
|
self::$builtInFormats[36] = '[$-404]e/m/d'; |
366
|
171 |
|
self::$builtInFormats[50] = '[$-404]e/m/d'; |
367
|
171 |
|
self::$builtInFormats[57] = '[$-404]e/m/d'; |
368
|
|
|
|
369
|
|
|
// THA |
370
|
171 |
|
self::$builtInFormats[59] = 't0'; |
371
|
171 |
|
self::$builtInFormats[60] = 't0.00'; |
372
|
171 |
|
self::$builtInFormats[61] = 't#,##0'; |
373
|
171 |
|
self::$builtInFormats[62] = 't#,##0.00'; |
374
|
171 |
|
self::$builtInFormats[67] = 't0%'; |
375
|
171 |
|
self::$builtInFormats[68] = 't0.00%'; |
376
|
171 |
|
self::$builtInFormats[69] = 't# ?/?'; |
377
|
171 |
|
self::$builtInFormats[70] = 't# ??/??'; |
378
|
|
|
|
379
|
|
|
// JPN |
380
|
171 |
|
self::$builtInFormats[28] = '[$-411]ggge"年"m"月"d"日"'; |
381
|
171 |
|
self::$builtInFormats[29] = '[$-411]ggge"年"m"月"d"日"'; |
382
|
171 |
|
self::$builtInFormats[31] = 'yyyy"年"m"月"d"日"'; |
383
|
171 |
|
self::$builtInFormats[32] = 'h"時"mm"分"'; |
384
|
171 |
|
self::$builtInFormats[33] = 'h"時"mm"分"ss"秒"'; |
385
|
171 |
|
self::$builtInFormats[34] = 'yyyy"年"m"月"'; |
386
|
171 |
|
self::$builtInFormats[35] = 'm"月"d"日"'; |
387
|
171 |
|
self::$builtInFormats[51] = '[$-411]ggge"年"m"月"d"日"'; |
388
|
171 |
|
self::$builtInFormats[52] = 'yyyy"年"m"月"'; |
389
|
171 |
|
self::$builtInFormats[53] = 'm"月"d"日"'; |
390
|
171 |
|
self::$builtInFormats[54] = '[$-411]ggge"年"m"月"d"日"'; |
391
|
171 |
|
self::$builtInFormats[55] = 'yyyy"年"m"月"'; |
392
|
171 |
|
self::$builtInFormats[56] = 'm"月"d"日"'; |
393
|
171 |
|
self::$builtInFormats[58] = '[$-411]ggge"年"m"月"d"日"'; |
394
|
|
|
|
395
|
|
|
// Flip array (for faster lookups) |
396
|
171 |
|
self::$flippedBuiltInFormats = array_flip(self::$builtInFormats); |
397
|
|
|
} |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Get built-in format code. |
402
|
|
|
*/ |
403
|
1164 |
|
public static function builtInFormatCode(int $index): string |
404
|
|
|
{ |
405
|
|
|
// Clean parameter |
406
|
1164 |
|
$index = (int) $index; |
407
|
|
|
|
408
|
|
|
// Ensure built-in format codes are available |
409
|
1164 |
|
self::fillBuiltInFormatCodes(); |
410
|
|
|
|
411
|
|
|
// Lookup format code |
412
|
1164 |
|
if (isset(self::$builtInFormats[$index])) { |
413
|
1164 |
|
return self::$builtInFormats[$index]; |
414
|
|
|
} |
415
|
|
|
|
416
|
20 |
|
return ''; |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* Get built-in format code index. |
421
|
|
|
* |
422
|
|
|
* @return false|int |
423
|
|
|
*/ |
424
|
1476 |
|
public static function builtInFormatCodeIndex(string $formatCodeIndex) |
425
|
|
|
{ |
426
|
|
|
// Ensure built-in format codes are available |
427
|
1476 |
|
self::fillBuiltInFormatCodes(); |
428
|
|
|
|
429
|
|
|
// Lookup format code |
430
|
1476 |
|
if (array_key_exists($formatCodeIndex, self::$flippedBuiltInFormats)) { |
431
|
1074 |
|
return self::$flippedBuiltInFormats[$formatCodeIndex]; |
432
|
|
|
} |
433
|
|
|
|
434
|
766 |
|
return false; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* Get hash code. |
439
|
|
|
* |
440
|
|
|
* @return string Hash code |
441
|
|
|
*/ |
442
|
1250 |
|
public function getHashCode(): string |
443
|
|
|
{ |
444
|
1250 |
|
if ($this->isSupervisor) { |
445
|
3 |
|
return $this->getSharedComponent()->getHashCode(); |
446
|
|
|
} |
447
|
|
|
|
448
|
1250 |
|
return md5( |
449
|
1250 |
|
$this->formatCode |
450
|
1250 |
|
. $this->builtInFormatCode |
451
|
1250 |
|
. __CLASS__ |
452
|
1250 |
|
); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* Convert a value in a pre-defined format to a PHP string. |
457
|
|
|
* |
458
|
|
|
* @param null|bool|float|int|RichText|string $value Value to format |
459
|
|
|
* @param string $format Format code: see = self::FORMAT_* for predefined values; |
460
|
|
|
* or can be any valid MS Excel custom format string |
461
|
|
|
* @param ?array $callBack Callback function for additional formatting of string |
462
|
|
|
* |
463
|
|
|
* @return string Formatted string |
464
|
|
|
*/ |
465
|
1262 |
|
public static function toFormattedString(mixed $value, string $format, ?array $callBack = null): string |
466
|
|
|
{ |
467
|
1262 |
|
return NumberFormat\Formatter::toFormattedString($value, $format, $callBack); |
468
|
|
|
} |
469
|
|
|
|
470
|
14 |
|
protected function exportArray1(): array |
471
|
|
|
{ |
472
|
14 |
|
$exportedArray = []; |
473
|
14 |
|
$this->exportArray2($exportedArray, 'formatCode', $this->getFormatCode()); |
474
|
|
|
|
475
|
14 |
|
return $exportedArray; |
476
|
|
|
} |
477
|
|
|
|
478
|
2 |
|
public static function getShortDateFormat(): string |
479
|
|
|
{ |
480
|
2 |
|
return self::$shortDateFormat; |
481
|
|
|
} |
482
|
|
|
|
483
|
2 |
|
public static function setShortDateFormat(string $shortDateFormat): void |
484
|
|
|
{ |
485
|
2 |
|
self::$shortDateFormat = $shortDateFormat; |
486
|
|
|
} |
487
|
|
|
|
488
|
2 |
|
public static function getLongDateFormat(): string |
489
|
|
|
{ |
490
|
2 |
|
return self::$longDateFormat; |
491
|
|
|
} |
492
|
|
|
|
493
|
2 |
|
public static function setLongDateFormat(string $longDateFormat): void |
494
|
|
|
{ |
495
|
2 |
|
self::$longDateFormat = $longDateFormat; |
496
|
|
|
} |
497
|
|
|
|
498
|
2 |
|
public static function getDateTimeFormat(): string |
499
|
|
|
{ |
500
|
2 |
|
return self::$dateTimeFormat; |
501
|
|
|
} |
502
|
|
|
|
503
|
2 |
|
public static function setDateTimeFormat(string $dateTimeFormat): void |
504
|
|
|
{ |
505
|
2 |
|
self::$dateTimeFormat = $dateTimeFormat; |
506
|
|
|
} |
507
|
|
|
|
508
|
2 |
|
public static function getTimeFormat(): string |
509
|
|
|
{ |
510
|
2 |
|
return self::$timeFormat; |
511
|
|
|
} |
512
|
|
|
|
513
|
2 |
|
public static function setTimeFormat(string $timeFormat): void |
514
|
|
|
{ |
515
|
2 |
|
self::$timeFormat = $timeFormat; |
516
|
|
|
} |
517
|
|
|
} |
518
|
|
|
|