2023-01-02 11:47:31 +08:00
|
|
|
|
// Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
|
2022-02-13 00:06:30 +08:00
|
|
|
|
// this source code is governed by a BSD-style license that can be found in
|
|
|
|
|
// the LICENSE file.
|
|
|
|
|
//
|
2022-02-17 00:09:11 +08:00
|
|
|
|
// Package excelize providing a set of functions that allow you to write to and
|
|
|
|
|
// read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and
|
|
|
|
|
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
|
|
|
|
|
// Supports complex components by high compatibility, and provided streaming
|
|
|
|
|
// API for generating or reading data from a worksheet with huge amounts of
|
2023-01-02 11:47:31 +08:00
|
|
|
|
// data. This library needs Go version 1.16 or later.
|
2022-02-13 00:06:30 +08:00
|
|
|
|
|
|
|
|
|
package excelize
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2022-03-19 00:05:47 +08:00
|
|
|
|
"math"
|
2022-02-13 00:06:30 +08:00
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/xuri/nfp"
|
|
|
|
|
)
|
|
|
|
|
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// languageInfo defined the required fields of localization support for number
|
|
|
|
|
// format.
|
2022-02-14 00:05:47 +08:00
|
|
|
|
type languageInfo struct {
|
|
|
|
|
apFmt string
|
|
|
|
|
tags []string
|
|
|
|
|
localMonth func(t time.Time, abbr int) string
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// numberFormat directly maps the number format parser runtime required
|
|
|
|
|
// fields.
|
|
|
|
|
type numberFormat struct {
|
2023-05-06 20:34:18 +08:00
|
|
|
|
opts *Options
|
2023-04-30 11:10:51 +08:00
|
|
|
|
cellType CellType
|
|
|
|
|
section []nfp.Section
|
|
|
|
|
t time.Time
|
|
|
|
|
sectionIdx int
|
2023-05-04 10:52:26 +08:00
|
|
|
|
date1904, isNumeric, hours, seconds, useMillisecond bool
|
2023-04-30 11:10:51 +08:00
|
|
|
|
number float64
|
|
|
|
|
ap, localCode, result, value, valueSectionType string
|
2023-05-04 10:52:26 +08:00
|
|
|
|
switchArgument, currencyString string
|
2023-04-30 11:10:51 +08:00
|
|
|
|
fracHolder, fracPadding, intHolder, intPadding, expBaseLen int
|
|
|
|
|
percent int
|
|
|
|
|
useCommaSep, usePointer, usePositive, useScientificNotation bool
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-11 09:08:38 +08:00
|
|
|
|
// CultureName is the type of supported language country codes types for apply
|
|
|
|
|
// number format.
|
|
|
|
|
type CultureName byte
|
|
|
|
|
|
|
|
|
|
// This section defines the currently supported country code types enumeration
|
|
|
|
|
// for apply number format.
|
|
|
|
|
const (
|
|
|
|
|
CultureNameUnknown CultureName = iota
|
|
|
|
|
CultureNameEnUS
|
|
|
|
|
CultureNameZhCN
|
|
|
|
|
)
|
|
|
|
|
|
2022-02-14 00:05:47 +08:00
|
|
|
|
var (
|
2023-05-11 09:08:38 +08:00
|
|
|
|
// Excel styles can reference number formats that are built-in, all of which
|
|
|
|
|
// have an id less than 164. Note that this number format code list is under
|
|
|
|
|
// English localization.
|
|
|
|
|
builtInNumFmt = map[int]string{
|
|
|
|
|
0: "general",
|
|
|
|
|
1: "0",
|
|
|
|
|
2: "0.00",
|
|
|
|
|
3: "#,##0",
|
|
|
|
|
4: "#,##0.00",
|
|
|
|
|
9: "0%",
|
|
|
|
|
10: "0.00%",
|
|
|
|
|
11: "0.00E+00",
|
|
|
|
|
12: "# ?/?",
|
|
|
|
|
13: "# ??/??",
|
|
|
|
|
14: "mm-dd-yy",
|
|
|
|
|
15: "d-mmm-yy",
|
|
|
|
|
16: "d-mmm",
|
|
|
|
|
17: "mmm-yy",
|
|
|
|
|
18: "h:mm AM/PM",
|
|
|
|
|
19: "h:mm:ss AM/PM",
|
|
|
|
|
20: "hh:mm",
|
|
|
|
|
21: "hh:mm:ss",
|
|
|
|
|
22: "m/d/yy hh:mm",
|
|
|
|
|
37: "#,##0 ;(#,##0)",
|
|
|
|
|
38: "#,##0 ;[red](#,##0)",
|
|
|
|
|
39: "#,##0.00 ;(#,##0.00)",
|
|
|
|
|
40: "#,##0.00 ;[red](#,##0.00)",
|
|
|
|
|
41: `_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)`,
|
|
|
|
|
42: `_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)`,
|
|
|
|
|
43: `_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)`,
|
|
|
|
|
44: `_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)`,
|
|
|
|
|
45: "mm:ss",
|
|
|
|
|
46: "[h]:mm:ss",
|
|
|
|
|
47: "mm:ss.0",
|
|
|
|
|
48: "##0.0E+0",
|
|
|
|
|
49: "@",
|
|
|
|
|
}
|
|
|
|
|
// langNumFmt defined number format code provided for language glyphs where
|
|
|
|
|
// they occur in different language.
|
|
|
|
|
langNumFmt = map[string]map[int]string{
|
|
|
|
|
"zh-tw": {
|
|
|
|
|
27: "[$-404]e/m/d",
|
|
|
|
|
28: `[$-404]e"年"m"月"d"日"`,
|
|
|
|
|
29: `[$-404]e"年"m"月"d"日"`,
|
|
|
|
|
30: "m/d/yy",
|
|
|
|
|
31: `yyyy"年"m"月"d"日"`,
|
|
|
|
|
32: `hh"時"mm"分"`,
|
|
|
|
|
33: `hh"時"mm"分"ss"秒"`,
|
|
|
|
|
34: `上午/下午 hh"時"mm"分"`,
|
|
|
|
|
35: `上午/下午 hh"時"mm"分"ss"秒"`,
|
|
|
|
|
36: "[$-404]e/m/d",
|
|
|
|
|
50: "[$-404]e/m/d",
|
|
|
|
|
51: `[$-404]e"年"m"月"d"日"`,
|
|
|
|
|
52: `上午/下午 hh"時"mm"分"`,
|
|
|
|
|
53: `上午/下午 hh"時"mm"分"ss"秒"`,
|
|
|
|
|
54: `[$-404]e"年"m"月"d"日"`,
|
|
|
|
|
55: `上午/下午 hh"時"mm"分"`,
|
|
|
|
|
56: `上午/下午 hh"時"mm"分"ss"秒"`,
|
|
|
|
|
57: "[$-404]e/m/d",
|
|
|
|
|
58: `[$-404]e"年"m"月"d"日"`,
|
|
|
|
|
},
|
|
|
|
|
"zh-cn": {
|
|
|
|
|
27: `yyyy"年"m"月"`,
|
|
|
|
|
28: `m"月"d"日"`,
|
|
|
|
|
29: `m"月"d"日"`,
|
|
|
|
|
30: "m/d/yy",
|
|
|
|
|
31: `yyyy"年"m"月"d"日"`,
|
|
|
|
|
32: `h"时"mm"分"`,
|
|
|
|
|
33: `h"时"mm"分"ss"秒"`,
|
|
|
|
|
34: `上午/下午 h"时"mm"分"`,
|
|
|
|
|
35: `上午/下午 h"时"mm"分"ss"秒"`,
|
|
|
|
|
36: `yyyy"年"m"月"`,
|
|
|
|
|
50: `yyyy"年"m"月"`,
|
|
|
|
|
51: `m"月"d"日"`,
|
|
|
|
|
52: `yyyy"年"m"月"`,
|
|
|
|
|
53: `m"月"d"日"`,
|
|
|
|
|
54: `m"月"d"日"`,
|
|
|
|
|
55: `上午/下午 h"时"mm"分"`,
|
|
|
|
|
56: `上午/下午 h"时"mm"分"ss"秒"`,
|
|
|
|
|
57: `yyyy"年"m"月"`,
|
|
|
|
|
58: `m"月"d"日"`,
|
|
|
|
|
},
|
|
|
|
|
"ja-jp": {
|
|
|
|
|
27: "[$-411]ge.m.d",
|
|
|
|
|
28: `[$-411]ggge"年"m"月"d"日"`,
|
|
|
|
|
29: `[$-411]ggge"年"m"月"d"日"`,
|
|
|
|
|
30: "m/d/yy",
|
|
|
|
|
31: `yyyy"年"m"月"d"日"`,
|
|
|
|
|
32: `h"時"mm"分"`,
|
|
|
|
|
33: `h"時"mm"分"ss"秒"`,
|
|
|
|
|
34: `yyyy"年"m"月"`,
|
|
|
|
|
35: `m"月"d"日"`,
|
|
|
|
|
36: "[$-411]ge.m.d",
|
|
|
|
|
50: "[$-411]ge.m.d",
|
|
|
|
|
51: `[$-411]ggge"年"m"月"d"日"`,
|
|
|
|
|
52: `yyyy"年"m"月"`,
|
|
|
|
|
53: `m"月"d"日"`,
|
|
|
|
|
54: `[$-411]ggge"年"m"月"d"日"`,
|
|
|
|
|
55: `yyyy"年"m"月"`,
|
|
|
|
|
56: `m"月"d"日"`,
|
|
|
|
|
57: "[$-411]ge.m.d",
|
|
|
|
|
58: `[$-411]ggge"年"m"月"d"日"`,
|
|
|
|
|
},
|
|
|
|
|
"ko-kr": {
|
|
|
|
|
27: `yyyy"年" mm"月" dd"日"`,
|
|
|
|
|
28: "mm-dd",
|
|
|
|
|
29: "mm-dd",
|
|
|
|
|
30: "mm-dd-yy",
|
|
|
|
|
31: `yyyy"년" mm"월" dd"일"`,
|
|
|
|
|
32: `h"시" mm"분"`,
|
|
|
|
|
33: `h"시" mm"분" ss"초"`,
|
|
|
|
|
34: `yyyy-mm-dd`,
|
|
|
|
|
35: `yyyy-mm-dd`,
|
|
|
|
|
36: `yyyy"年" mm"月" dd"日"`,
|
|
|
|
|
50: `yyyy"年" mm"月" dd"日"`,
|
|
|
|
|
51: "mm-dd",
|
|
|
|
|
52: "yyyy-mm-dd",
|
|
|
|
|
53: "yyyy-mm-dd",
|
|
|
|
|
54: "mm-dd",
|
|
|
|
|
55: "yyyy-mm-dd",
|
|
|
|
|
56: "yyyy-mm-dd",
|
|
|
|
|
57: `yyyy"年" mm"月" dd"日"`,
|
|
|
|
|
58: "mm-dd",
|
|
|
|
|
},
|
|
|
|
|
"th-th": {
|
|
|
|
|
59: "t0",
|
|
|
|
|
60: "t0.00",
|
|
|
|
|
61: "t#,##0",
|
|
|
|
|
62: "t#,##0.00",
|
|
|
|
|
67: "t0%",
|
|
|
|
|
68: "t0.00%",
|
|
|
|
|
69: "t# ?/?",
|
|
|
|
|
70: "t# ??/??",
|
|
|
|
|
71: "ว/ด/ปปปป",
|
|
|
|
|
72: "ว-ดดด-ปป",
|
|
|
|
|
73: "ว-ดดด",
|
|
|
|
|
74: "ดดด-ปป",
|
|
|
|
|
75: "ช:นน",
|
|
|
|
|
76: "ช:นน:ทท",
|
|
|
|
|
77: "ว/ด/ปปปป ช:นน",
|
|
|
|
|
78: "นน:ทท",
|
|
|
|
|
79: "[ช]:นน:ทท",
|
|
|
|
|
80: "นน:ทท.0",
|
|
|
|
|
81: "d/m/bb",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
// currencyNumFmt defined the currency number format map.
|
|
|
|
|
currencyNumFmt = map[int]string{
|
|
|
|
|
164: `"¥"#,##0.00`,
|
|
|
|
|
165: "[$$-409]#,##0.00",
|
|
|
|
|
166: "[$$-45C]#,##0.00",
|
|
|
|
|
167: "[$$-1004]#,##0.00",
|
|
|
|
|
168: "[$$-404]#,##0.00",
|
|
|
|
|
169: "[$$-C09]#,##0.00",
|
|
|
|
|
170: "[$$-2809]#,##0.00",
|
|
|
|
|
171: "[$$-1009]#,##0.00",
|
|
|
|
|
172: "[$$-2009]#,##0.00",
|
|
|
|
|
173: "[$$-1409]#,##0.00",
|
|
|
|
|
174: "[$$-4809]#,##0.00",
|
|
|
|
|
175: "[$$-2C09]#,##0.00",
|
|
|
|
|
176: "[$$-2409]#,##0.00",
|
|
|
|
|
177: "[$$-1000]#,##0.00",
|
|
|
|
|
178: `#,##0.00\ [$$-C0C]`,
|
|
|
|
|
179: "[$$-475]#,##0.00",
|
|
|
|
|
180: "[$$-83E]#,##0.00",
|
|
|
|
|
181: `[$$-86B]\ #,##0.00`,
|
|
|
|
|
182: `[$$-340A]\ #,##0.00`,
|
|
|
|
|
183: "[$$-240A]#,##0.00",
|
|
|
|
|
184: `[$$-300A]\ #,##0.00`,
|
|
|
|
|
185: "[$$-440A]#,##0.00",
|
|
|
|
|
186: "[$$-80A]#,##0.00",
|
|
|
|
|
187: "[$$-500A]#,##0.00",
|
|
|
|
|
188: "[$$-540A]#,##0.00",
|
|
|
|
|
189: `[$$-380A]\ #,##0.00`,
|
|
|
|
|
190: "[$£-809]#,##0.00",
|
|
|
|
|
191: "[$£-491]#,##0.00",
|
|
|
|
|
192: "[$£-452]#,##0.00",
|
|
|
|
|
193: "[$¥-804]#,##0.00",
|
|
|
|
|
194: "[$¥-411]#,##0.00",
|
|
|
|
|
195: "[$¥-478]#,##0.00",
|
|
|
|
|
196: "[$¥-451]#,##0.00",
|
|
|
|
|
197: "[$¥-480]#,##0.00",
|
|
|
|
|
198: "#,##0.00\\ [$\u058F-42B]",
|
|
|
|
|
199: "[$\u060B-463]#,##0.00",
|
|
|
|
|
200: "[$\u060B-48C]#,##0.00",
|
|
|
|
|
201: "[$\u09F3-845]\\ #,##0.00",
|
|
|
|
|
202: "#,##0.00[$\u17DB-453]",
|
|
|
|
|
203: "[$\u20A1-140A]#,##0.00",
|
|
|
|
|
204: "[$\u20A6-468]\\ #,##0.00",
|
|
|
|
|
205: "[$\u20A6-470]\\ #,##0.00",
|
|
|
|
|
206: "[$\u20A9-412]#,##0.00",
|
|
|
|
|
207: "[$\u20AA-40D]\\ #,##0.00",
|
|
|
|
|
208: "#,##0.00\\ [$\u20AB-42A]",
|
|
|
|
|
209: "#,##0.00\\ [$\u20AC-42D]",
|
|
|
|
|
210: "#,##0.00\\ [$\u20AC-47E]",
|
|
|
|
|
211: "#,##0.00\\ [$\u20AC-403]",
|
|
|
|
|
212: "#,##0.00\\ [$\u20AC-483]",
|
|
|
|
|
213: "[$\u20AC-813]\\ #,##0.00",
|
|
|
|
|
214: "[$\u20AC-413]\\ #,##0.00",
|
|
|
|
|
215: "[$\u20AC-1809]#,##0.00",
|
|
|
|
|
216: "#,##0.00\\ [$\u20AC-425]",
|
|
|
|
|
217: "[$\u20AC-2]\\ #,##0.00",
|
|
|
|
|
218: "#,##0.00\\ [$\u20AC-1]",
|
|
|
|
|
219: "#,##0.00\\ [$\u20AC-40B]",
|
|
|
|
|
220: "#,##0.00\\ [$\u20AC-80C]",
|
|
|
|
|
221: "#,##0.00\\ [$\u20AC-40C]",
|
|
|
|
|
222: "#,##0.00\\ [$\u20AC-140C]",
|
|
|
|
|
223: "#,##0.00\\ [$\u20AC-180C]",
|
|
|
|
|
224: "[$\u20AC-200C]#,##0.00",
|
|
|
|
|
225: "#,##0.00\\ [$\u20AC-456]",
|
|
|
|
|
226: "#,##0.00\\ [$\u20AC-C07]",
|
|
|
|
|
227: "#,##0.00\\ [$\u20AC-407]",
|
|
|
|
|
228: "#,##0.00\\ [$\u20AC-1007]",
|
|
|
|
|
229: "#,##0.00\\ [$\u20AC-408]",
|
|
|
|
|
230: "#,##0.00\\ [$\u20AC-243B]",
|
|
|
|
|
231: "[$\u20AC-83C]#,##0.00",
|
|
|
|
|
232: "[$\u20AC-410]\\ #,##0.00",
|
|
|
|
|
233: "[$\u20AC-476]#,##0.00",
|
|
|
|
|
234: "#,##0.00\\ [$\u20AC-2C1A]",
|
|
|
|
|
235: "[$\u20AC-426]\\ #,##0.00",
|
|
|
|
|
236: "#,##0.00\\ [$\u20AC-427]",
|
|
|
|
|
237: "#,##0.00\\ [$\u20AC-82E]",
|
|
|
|
|
238: "#,##0.00\\ [$\u20AC-46E]",
|
|
|
|
|
239: "[$\u20AC-43A]#,##0.00",
|
|
|
|
|
240: "#,##0.00\\ [$\u20AC-C3B]",
|
|
|
|
|
241: "#,##0.00\\ [$\u20AC-482]",
|
|
|
|
|
242: "#,##0.00\\ [$\u20AC-816]",
|
|
|
|
|
243: "#,##0.00\\ [$\u20AC-301A]",
|
|
|
|
|
244: "#,##0.00\\ [$\u20AC-203B]",
|
|
|
|
|
245: "#,##0.00\\ [$\u20AC-41B]",
|
|
|
|
|
246: "#,##0.00\\ [$\u20AC-424]",
|
|
|
|
|
247: "#,##0.00\\ [$\u20AC-C0A]",
|
|
|
|
|
248: "#,##0.00\\ [$\u20AC-81D]",
|
|
|
|
|
249: "#,##0.00\\ [$\u20AC-484]",
|
|
|
|
|
250: "#,##0.00\\ [$\u20AC-42E]",
|
|
|
|
|
251: "[$\u20AC-462]\\ #,##0.00",
|
|
|
|
|
252: "#,##0.00\\ [$₭-454]",
|
|
|
|
|
253: "#,##0.00\\ [$₮-450]",
|
|
|
|
|
254: "[$\u20AE-C50]#,##0.00",
|
|
|
|
|
255: "[$\u20B1-3409]#,##0.00",
|
|
|
|
|
256: "[$\u20B1-464]#,##0.00",
|
|
|
|
|
257: "#,##0.00[$\u20B4-422]",
|
|
|
|
|
258: "[$\u20B8-43F]#,##0.00",
|
|
|
|
|
259: "[$\u20B9-460]#,##0.00",
|
|
|
|
|
260: "[$\u20B9-4009]\\ #,##0.00",
|
|
|
|
|
261: "[$\u20B9-447]\\ #,##0.00",
|
|
|
|
|
262: "[$\u20B9-439]\\ #,##0.00",
|
|
|
|
|
263: "[$\u20B9-44B]\\ #,##0.00",
|
|
|
|
|
264: "[$\u20B9-860]#,##0.00",
|
|
|
|
|
265: "[$\u20B9-457]\\ #,##0.00",
|
|
|
|
|
266: "[$\u20B9-458]#,##0.00",
|
|
|
|
|
267: "[$\u20B9-44E]\\ #,##0.00",
|
|
|
|
|
268: "[$\u20B9-861]#,##0.00",
|
|
|
|
|
269: "[$\u20B9-448]\\ #,##0.00",
|
|
|
|
|
270: "[$\u20B9-446]\\ #,##0.00",
|
|
|
|
|
271: "[$\u20B9-44F]\\ #,##0.00",
|
|
|
|
|
272: "[$\u20B9-459]#,##0.00",
|
|
|
|
|
273: "[$\u20B9-449]\\ #,##0.00",
|
|
|
|
|
274: "[$\u20B9-820]#,##0.00",
|
|
|
|
|
275: "#,##0.00\\ [$\u20BA-41F]",
|
|
|
|
|
276: "#,##0.00\\ [$\u20BC-42C]",
|
|
|
|
|
277: "#,##0.00\\ [$\u20BC-82C]",
|
|
|
|
|
278: "#,##0.00\\ [$\u20BD-419]",
|
|
|
|
|
279: "#,##0.00[$\u20BD-485]",
|
|
|
|
|
280: "#,##0.00\\ [$\u20BE-437]",
|
|
|
|
|
281: "[$B/.-180A]\\ #,##0.00",
|
|
|
|
|
282: "[$Br-472]#,##0.00",
|
|
|
|
|
283: "[$Br-477]#,##0.00",
|
|
|
|
|
284: "#,##0.00[$Br-473]",
|
|
|
|
|
285: "[$Bs-46B]\\ #,##0.00",
|
|
|
|
|
286: "[$Bs-400A]\\ #,##0.00",
|
|
|
|
|
287: "[$Bs.-200A]\\ #,##0.00",
|
|
|
|
|
288: "[$BWP-832]\\ #,##0.00",
|
|
|
|
|
289: "[$C$-4C0A]#,##0.00",
|
|
|
|
|
290: "[$CA$-85D]#,##0.00",
|
|
|
|
|
291: "[$CA$-47C]#,##0.00",
|
|
|
|
|
292: "[$CA$-45D]#,##0.00",
|
|
|
|
|
293: "[$CFA-340C]#,##0.00",
|
|
|
|
|
294: "[$CFA-280C]#,##0.00",
|
|
|
|
|
295: "#,##0.00\\ [$CFA-867]",
|
|
|
|
|
296: "#,##0.00\\ [$CFA-488]",
|
|
|
|
|
297: "#,##0.00\\ [$CHF-100C]",
|
|
|
|
|
298: "[$CHF-1407]\\ #,##0.00",
|
|
|
|
|
299: "[$CHF-807]\\ #,##0.00",
|
|
|
|
|
300: "[$CHF-810]\\ #,##0.00",
|
|
|
|
|
301: "[$CHF-417]\\ #,##0.00",
|
|
|
|
|
302: "[$CLP-47A]\\ #,##0.00",
|
|
|
|
|
303: "[$CN¥-850]#,##0.00",
|
|
|
|
|
304: "#,##0.00\\ [$DZD-85F]",
|
|
|
|
|
305: "[$FCFA-2C0C]#,##0.00",
|
|
|
|
|
306: "#,##0.00\\ [$Ft-40E]",
|
|
|
|
|
307: "[$G-3C0C]#,##0.00",
|
|
|
|
|
308: "[$Gs.-3C0A]\\ #,##0.00",
|
|
|
|
|
309: "[$GTQ-486]#,##0.00",
|
|
|
|
|
310: "[$HK$-C04]#,##0.00",
|
|
|
|
|
311: "[$HK$-3C09]#,##0.00",
|
|
|
|
|
312: "#,##0.00\\ [$HRK-41A]",
|
|
|
|
|
313: "[$IDR-3809]#,##0.00",
|
|
|
|
|
314: "[$IQD-492]#,##0.00",
|
|
|
|
|
315: "#,##0.00\\ [$ISK-40F]",
|
|
|
|
|
316: "[$K-455]#,##0.00",
|
|
|
|
|
317: "#,##0.00\\ [$K\u010D-405]",
|
|
|
|
|
318: "#,##0.00\\ [$KM-141A]",
|
|
|
|
|
319: "#,##0.00\\ [$KM-101A]",
|
|
|
|
|
320: "#,##0.00\\ [$KM-181A]",
|
|
|
|
|
321: "[$kr-438]\\ #,##0.00",
|
|
|
|
|
322: "[$kr-43B]\\ #,##0.00",
|
|
|
|
|
323: "#,##0.00\\ [$kr-83B]",
|
|
|
|
|
324: "[$kr-414]\\ #,##0.00",
|
|
|
|
|
325: "[$kr-814]\\ #,##0.00",
|
|
|
|
|
326: "#,##0.00\\ [$kr-41D]",
|
|
|
|
|
327: "[$kr.-406]\\ #,##0.00",
|
|
|
|
|
328: "[$kr.-46F]\\ #,##0.00",
|
|
|
|
|
329: "[$Ksh-441]#,##0.00",
|
|
|
|
|
330: "[$L-818]#,##0.00",
|
|
|
|
|
331: "[$L-819]#,##0.00",
|
|
|
|
|
332: "[$L-480A]\\ #,##0.00",
|
|
|
|
|
333: "#,##0.00\\ [$Lek\u00EB-41C]",
|
|
|
|
|
334: "[$MAD-45F]#,##0.00",
|
|
|
|
|
335: "[$MAD-380C]#,##0.00",
|
|
|
|
|
336: "#,##0.00\\ [$MAD-105F]",
|
|
|
|
|
337: "[$MOP$-1404]#,##0.00",
|
|
|
|
|
338: "#,##0.00\\ [$MVR-465]_-",
|
|
|
|
|
339: "#,##0.00[$Nfk-873]",
|
|
|
|
|
340: "[$NGN-466]#,##0.00",
|
|
|
|
|
341: "[$NGN-467]#,##0.00",
|
|
|
|
|
342: "[$NGN-469]#,##0.00",
|
|
|
|
|
343: "[$NGN-471]#,##0.00",
|
|
|
|
|
344: "[$NOK-103B]\\ #,##0.00",
|
|
|
|
|
345: "[$NOK-183B]\\ #,##0.00",
|
|
|
|
|
346: "[$NZ$-481]#,##0.00",
|
|
|
|
|
347: "[$PKR-859]\\ #,##0.00",
|
|
|
|
|
348: "[$PYG-474]#,##0.00",
|
|
|
|
|
349: "[$Q-100A]#,##0.00",
|
|
|
|
|
350: "[$R-436]\\ #,##0.00",
|
|
|
|
|
351: "[$R-1C09]\\ #,##0.00",
|
|
|
|
|
352: "[$R-435]\\ #,##0.00",
|
|
|
|
|
353: "[$R$-416]\\ #,##0.00",
|
|
|
|
|
354: "[$RD$-1C0A]#,##0.00",
|
|
|
|
|
355: "#,##0.00\\ [$RF-487]",
|
|
|
|
|
356: "[$RM-4409]#,##0.00",
|
|
|
|
|
357: "[$RM-43E]#,##0.00",
|
|
|
|
|
358: "#,##0.00\\ [$RON-418]",
|
|
|
|
|
359: "[$Rp-421]#,##0.00",
|
|
|
|
|
360: "[$Rs-420]#,##0.00_-",
|
|
|
|
|
361: "[$Rs.-849]\\ #,##0.00",
|
|
|
|
|
362: "#,##0.00\\ [$RSD-81A]",
|
|
|
|
|
363: "#,##0.00\\ [$RSD-C1A]",
|
|
|
|
|
364: "#,##0.00\\ [$RUB-46D]",
|
|
|
|
|
365: "#,##0.00\\ [$RUB-444]",
|
|
|
|
|
366: "[$S/.-C6B]\\ #,##0.00",
|
|
|
|
|
367: "[$S/.-280A]\\ #,##0.00",
|
|
|
|
|
368: "#,##0.00\\ [$SEK-143B]",
|
|
|
|
|
369: "#,##0.00\\ [$SEK-1C3B]",
|
|
|
|
|
370: "#,##0.00\\ [$so\u02BBm-443]",
|
|
|
|
|
371: "#,##0.00\\ [$so\u02BBm-843]",
|
|
|
|
|
372: "#,##0.00\\ [$SYP-45A]",
|
|
|
|
|
373: "[$THB-41E]#,##0.00",
|
|
|
|
|
374: "#,##0.00[$TMT-442]",
|
|
|
|
|
375: "[$US$-3009]#,##0.00",
|
|
|
|
|
376: "[$ZAR-46C]\\ #,##0.00",
|
|
|
|
|
377: "[$ZAR-430]#,##0.00",
|
|
|
|
|
378: "[$ZAR-431]#,##0.00",
|
|
|
|
|
379: "[$ZAR-432]\\ #,##0.00",
|
|
|
|
|
380: "[$ZAR-433]#,##0.00",
|
|
|
|
|
381: "[$ZAR-434]\\ #,##0.00",
|
|
|
|
|
382: "#,##0.00\\ [$z\u0142-415]",
|
|
|
|
|
383: "#,##0.00\\ [$\u0434\u0435\u043D-42F]",
|
|
|
|
|
384: "#,##0.00\\ [$КМ-201A]",
|
|
|
|
|
385: "#,##0.00\\ [$КМ-1C1A]",
|
|
|
|
|
386: "#,##0.00\\ [$\u043B\u0432.-402]",
|
|
|
|
|
387: "#,##0.00\\ [$р.-423]",
|
|
|
|
|
388: "#,##0.00\\ [$\u0441\u043E\u043C-440]",
|
|
|
|
|
389: "#,##0.00\\ [$\u0441\u043E\u043C-428]",
|
|
|
|
|
390: "[$\u062C.\u0645.-C01]\\ #,##0.00_-",
|
|
|
|
|
391: "[$\u062F.\u0623.-2C01]\\ #,##0.00_-",
|
|
|
|
|
392: "[$\u062F.\u0625.-3801]\\ #,##0.00_-",
|
|
|
|
|
393: "[$\u062F.\u0628.-3C01]\\ #,##0.00_-",
|
|
|
|
|
394: "[$\u062F.\u062A.-1C01]\\ #,##0.00_-",
|
|
|
|
|
395: "[$\u062F.\u062C.-1401]\\ #,##0.00_-",
|
|
|
|
|
396: "[$\u062F.\u0639.-801]\\ #,##0.00_-",
|
|
|
|
|
397: "[$\u062F.\u0643.-3401]\\ #,##0.00_-",
|
|
|
|
|
398: "[$\u062F.\u0644.-1001]#,##0.00_-",
|
|
|
|
|
399: "[$\u062F.\u0645.-1801]\\ #,##0.00_-",
|
|
|
|
|
400: "[$\u0631-846]\\ #,##0.00",
|
|
|
|
|
401: "[$\u0631.\u0633.-401]\\ #,##0.00_-",
|
|
|
|
|
402: "[$\u0631.\u0639.-2001]\\ #,##0.00_-",
|
|
|
|
|
403: "[$\u0631.\u0642.-4001]\\ #,##0.00_-",
|
|
|
|
|
404: "[$\u0631.\u064A.-2401]\\ #,##0.00_-",
|
|
|
|
|
405: "[$\u0631\u06CC\u0627\u0644-429]#,##0.00_-",
|
|
|
|
|
406: "[$\u0644.\u0633.-2801]\\ #,##0.00_-",
|
|
|
|
|
407: "[$\u0644.\u0644.-3001]\\ #,##0.00_-",
|
|
|
|
|
408: "[$\u1265\u122D-45E]#,##0.00",
|
|
|
|
|
409: "[$\u0930\u0942-461]#,##0.00",
|
|
|
|
|
410: "[$\u0DBB\u0DD4.-45B]\\ #,##0.00",
|
|
|
|
|
411: "[$ADP]\\ #,##0.00",
|
|
|
|
|
412: "[$AED]\\ #,##0.00",
|
|
|
|
|
413: "[$AFA]\\ #,##0.00",
|
|
|
|
|
414: "[$AFN]\\ #,##0.00",
|
|
|
|
|
415: "[$ALL]\\ #,##0.00",
|
|
|
|
|
416: "[$AMD]\\ #,##0.00",
|
|
|
|
|
417: "[$ANG]\\ #,##0.00",
|
|
|
|
|
418: "[$AOA]\\ #,##0.00",
|
|
|
|
|
419: "[$ARS]\\ #,##0.00",
|
|
|
|
|
420: "[$ATS]\\ #,##0.00",
|
|
|
|
|
421: "[$AUD]\\ #,##0.00",
|
|
|
|
|
422: "[$AWG]\\ #,##0.00",
|
|
|
|
|
423: "[$AZM]\\ #,##0.00",
|
|
|
|
|
424: "[$AZN]\\ #,##0.00",
|
|
|
|
|
425: "[$BAM]\\ #,##0.00",
|
|
|
|
|
426: "[$BBD]\\ #,##0.00",
|
|
|
|
|
427: "[$BDT]\\ #,##0.00",
|
|
|
|
|
428: "[$BEF]\\ #,##0.00",
|
|
|
|
|
429: "[$BGL]\\ #,##0.00",
|
|
|
|
|
430: "[$BGN]\\ #,##0.00",
|
|
|
|
|
431: "[$BHD]\\ #,##0.00",
|
|
|
|
|
432: "[$BIF]\\ #,##0.00",
|
|
|
|
|
433: "[$BMD]\\ #,##0.00",
|
|
|
|
|
434: "[$BND]\\ #,##0.00",
|
|
|
|
|
435: "[$BOB]\\ #,##0.00",
|
|
|
|
|
436: "[$BOV]\\ #,##0.00",
|
|
|
|
|
437: "[$BRL]\\ #,##0.00",
|
|
|
|
|
438: "[$BSD]\\ #,##0.00",
|
|
|
|
|
439: "[$BTN]\\ #,##0.00",
|
|
|
|
|
440: "[$BWP]\\ #,##0.00",
|
|
|
|
|
441: "[$BYR]\\ #,##0.00",
|
|
|
|
|
442: "[$BZD]\\ #,##0.00",
|
|
|
|
|
443: "[$CAD]\\ #,##0.00",
|
|
|
|
|
444: "[$CDF]\\ #,##0.00",
|
|
|
|
|
445: "[$CHE]\\ #,##0.00",
|
|
|
|
|
446: "[$CHF]\\ #,##0.00",
|
|
|
|
|
447: "[$CHW]\\ #,##0.00",
|
|
|
|
|
448: "[$CLF]\\ #,##0.00",
|
|
|
|
|
449: "[$CLP]\\ #,##0.00",
|
|
|
|
|
450: "[$CNY]\\ #,##0.00",
|
|
|
|
|
451: "[$COP]\\ #,##0.00",
|
|
|
|
|
452: "[$COU]\\ #,##0.00",
|
|
|
|
|
453: "[$CRC]\\ #,##0.00",
|
|
|
|
|
454: "[$CSD]\\ #,##0.00",
|
|
|
|
|
455: "[$CUC]\\ #,##0.00",
|
|
|
|
|
456: "[$CVE]\\ #,##0.00",
|
|
|
|
|
457: "[$CYP]\\ #,##0.00",
|
|
|
|
|
458: "[$CZK]\\ #,##0.00",
|
|
|
|
|
459: "[$DEM]\\ #,##0.00",
|
|
|
|
|
460: "[$DJF]\\ #,##0.00",
|
|
|
|
|
461: "[$DKK]\\ #,##0.00",
|
|
|
|
|
462: "[$DOP]\\ #,##0.00",
|
|
|
|
|
463: "[$DZD]\\ #,##0.00",
|
|
|
|
|
464: "[$ECS]\\ #,##0.00",
|
|
|
|
|
465: "[$ECV]\\ #,##0.00",
|
|
|
|
|
466: "[$EEK]\\ #,##0.00",
|
|
|
|
|
467: "[$EGP]\\ #,##0.00",
|
|
|
|
|
468: "[$ERN]\\ #,##0.00",
|
|
|
|
|
469: "[$ESP]\\ #,##0.00",
|
|
|
|
|
470: "[$ETB]\\ #,##0.00",
|
|
|
|
|
471: "[$EUR]\\ #,##0.00",
|
|
|
|
|
472: "[$FIM]\\ #,##0.00",
|
|
|
|
|
473: "[$FJD]\\ #,##0.00",
|
|
|
|
|
474: "[$FKP]\\ #,##0.00",
|
|
|
|
|
475: "[$FRF]\\ #,##0.00",
|
|
|
|
|
476: "[$GBP]\\ #,##0.00",
|
|
|
|
|
477: "[$GEL]\\ #,##0.00",
|
|
|
|
|
478: "[$GHC]\\ #,##0.00",
|
|
|
|
|
479: "[$GHS]\\ #,##0.00",
|
|
|
|
|
480: "[$GIP]\\ #,##0.00",
|
|
|
|
|
481: "[$GMD]\\ #,##0.00",
|
|
|
|
|
482: "[$GNF]\\ #,##0.00",
|
|
|
|
|
483: "[$GRD]\\ #,##0.00",
|
|
|
|
|
484: "[$GTQ]\\ #,##0.00",
|
|
|
|
|
485: "[$GYD]\\ #,##0.00",
|
|
|
|
|
486: "[$HKD]\\ #,##0.00",
|
|
|
|
|
487: "[$HNL]\\ #,##0.00",
|
|
|
|
|
488: "[$HRK]\\ #,##0.00",
|
|
|
|
|
489: "[$HTG]\\ #,##0.00",
|
|
|
|
|
490: "[$HUF]\\ #,##0.00",
|
|
|
|
|
491: "[$IDR]\\ #,##0.00",
|
|
|
|
|
492: "[$IEP]\\ #,##0.00",
|
|
|
|
|
493: "[$ILS]\\ #,##0.00",
|
|
|
|
|
494: "[$INR]\\ #,##0.00",
|
|
|
|
|
495: "[$IQD]\\ #,##0.00",
|
|
|
|
|
496: "[$IRR]\\ #,##0.00",
|
|
|
|
|
497: "[$ISK]\\ #,##0.00",
|
|
|
|
|
498: "[$ITL]\\ #,##0.00",
|
|
|
|
|
499: "[$JMD]\\ #,##0.00",
|
|
|
|
|
500: "[$JOD]\\ #,##0.00",
|
|
|
|
|
501: "[$JPY]\\ #,##0.00",
|
|
|
|
|
502: "[$KAF]\\ #,##0.00",
|
|
|
|
|
503: "[$KES]\\ #,##0.00",
|
|
|
|
|
504: "[$KGS]\\ #,##0.00",
|
|
|
|
|
505: "[$KHR]\\ #,##0.00",
|
|
|
|
|
506: "[$KMF]\\ #,##0.00",
|
|
|
|
|
507: "[$KPW]\\ #,##0.00",
|
|
|
|
|
508: "[$KRW]\\ #,##0.00",
|
|
|
|
|
509: "[$KWD]\\ #,##0.00",
|
|
|
|
|
510: "[$KYD]\\ #,##0.00",
|
|
|
|
|
511: "[$KZT]\\ #,##0.00",
|
|
|
|
|
512: "[$LAK]\\ #,##0.00",
|
|
|
|
|
513: "[$LBP]\\ #,##0.00",
|
|
|
|
|
514: "[$LKR]\\ #,##0.00",
|
|
|
|
|
515: "[$LRD]\\ #,##0.00",
|
|
|
|
|
516: "[$LSL]\\ #,##0.00",
|
|
|
|
|
517: "[$LTL]\\ #,##0.00",
|
|
|
|
|
518: "[$LUF]\\ #,##0.00",
|
|
|
|
|
519: "[$LVL]\\ #,##0.00",
|
|
|
|
|
520: "[$LYD]\\ #,##0.00",
|
|
|
|
|
521: "[$MAD]\\ #,##0.00",
|
|
|
|
|
522: "[$MDL]\\ #,##0.00",
|
|
|
|
|
523: "[$MGA]\\ #,##0.00",
|
|
|
|
|
524: "[$MGF]\\ #,##0.00",
|
|
|
|
|
525: "[$MKD]\\ #,##0.00",
|
|
|
|
|
526: "[$MMK]\\ #,##0.00",
|
|
|
|
|
527: "[$MNT]\\ #,##0.00",
|
|
|
|
|
528: "[$MOP]\\ #,##0.00",
|
|
|
|
|
529: "[$MRO]\\ #,##0.00",
|
|
|
|
|
530: "[$MTL]\\ #,##0.00",
|
|
|
|
|
531: "[$MUR]\\ #,##0.00",
|
|
|
|
|
532: "[$MVR]\\ #,##0.00",
|
|
|
|
|
533: "[$MWK]\\ #,##0.00",
|
|
|
|
|
534: "[$MXN]\\ #,##0.00",
|
|
|
|
|
535: "[$MXV]\\ #,##0.00",
|
|
|
|
|
536: "[$MYR]\\ #,##0.00",
|
|
|
|
|
537: "[$MZM]\\ #,##0.00",
|
|
|
|
|
538: "[$MZN]\\ #,##0.00",
|
|
|
|
|
539: "[$NAD]\\ #,##0.00",
|
|
|
|
|
540: "[$NGN]\\ #,##0.00",
|
|
|
|
|
541: "[$NIO]\\ #,##0.00",
|
|
|
|
|
542: "[$NLG]\\ #,##0.00",
|
|
|
|
|
543: "[$NOK]\\ #,##0.00",
|
|
|
|
|
544: "[$NPR]\\ #,##0.00",
|
|
|
|
|
545: "[$NTD]\\ #,##0.00",
|
|
|
|
|
546: "[$NZD]\\ #,##0.00",
|
|
|
|
|
547: "[$OMR]\\ #,##0.00",
|
|
|
|
|
548: "[$PAB]\\ #,##0.00",
|
|
|
|
|
549: "[$PEN]\\ #,##0.00",
|
|
|
|
|
550: "[$PGK]\\ #,##0.00",
|
|
|
|
|
551: "[$PHP]\\ #,##0.00",
|
|
|
|
|
552: "[$PKR]\\ #,##0.00",
|
|
|
|
|
553: "[$PLN]\\ #,##0.00",
|
|
|
|
|
554: "[$PTE]\\ #,##0.00",
|
|
|
|
|
555: "[$PYG]\\ #,##0.00",
|
|
|
|
|
556: "[$QAR]\\ #,##0.00",
|
|
|
|
|
557: "[$ROL]\\ #,##0.00",
|
|
|
|
|
558: "[$RON]\\ #,##0.00",
|
|
|
|
|
559: "[$RSD]\\ #,##0.00",
|
|
|
|
|
560: "[$RUB]\\ #,##0.00",
|
|
|
|
|
561: "[$RUR]\\ #,##0.00",
|
|
|
|
|
562: "[$RWF]\\ #,##0.00",
|
|
|
|
|
563: "[$SAR]\\ #,##0.00",
|
|
|
|
|
564: "[$SBD]\\ #,##0.00",
|
|
|
|
|
565: "[$SCR]\\ #,##0.00",
|
|
|
|
|
566: "[$SDD]\\ #,##0.00",
|
|
|
|
|
567: "[$SDG]\\ #,##0.00",
|
|
|
|
|
568: "[$SDP]\\ #,##0.00",
|
|
|
|
|
569: "[$SEK]\\ #,##0.00",
|
|
|
|
|
570: "[$SGD]\\ #,##0.00",
|
|
|
|
|
571: "[$SHP]\\ #,##0.00",
|
|
|
|
|
572: "[$SIT]\\ #,##0.00",
|
|
|
|
|
573: "[$SKK]\\ #,##0.00",
|
|
|
|
|
574: "[$SLL]\\ #,##0.00",
|
|
|
|
|
575: "[$SOS]\\ #,##0.00",
|
|
|
|
|
576: "[$SPL]\\ #,##0.00",
|
|
|
|
|
577: "[$SRD]\\ #,##0.00",
|
|
|
|
|
578: "[$SRG]\\ #,##0.00",
|
|
|
|
|
579: "[$STD]\\ #,##0.00",
|
|
|
|
|
580: "[$SVC]\\ #,##0.00",
|
|
|
|
|
581: "[$SYP]\\ #,##0.00",
|
|
|
|
|
582: "[$SZL]\\ #,##0.00",
|
|
|
|
|
583: "[$THB]\\ #,##0.00",
|
|
|
|
|
584: "[$TJR]\\ #,##0.00",
|
|
|
|
|
585: "[$TJS]\\ #,##0.00",
|
|
|
|
|
586: "[$TMM]\\ #,##0.00",
|
|
|
|
|
587: "[$TMT]\\ #,##0.00",
|
|
|
|
|
588: "[$TND]\\ #,##0.00",
|
|
|
|
|
589: "[$TOP]\\ #,##0.00",
|
|
|
|
|
590: "[$TRL]\\ #,##0.00",
|
|
|
|
|
591: "[$TRY]\\ #,##0.00",
|
|
|
|
|
592: "[$TTD]\\ #,##0.00",
|
|
|
|
|
593: "[$TWD]\\ #,##0.00",
|
|
|
|
|
594: "[$TZS]\\ #,##0.00",
|
|
|
|
|
595: "[$UAH]\\ #,##0.00",
|
|
|
|
|
596: "[$UGX]\\ #,##0.00",
|
|
|
|
|
597: "[$USD]\\ #,##0.00",
|
|
|
|
|
598: "[$USN]\\ #,##0.00",
|
|
|
|
|
599: "[$USS]\\ #,##0.00",
|
|
|
|
|
600: "[$UYI]\\ #,##0.00",
|
|
|
|
|
601: "[$UYU]\\ #,##0.00",
|
|
|
|
|
602: "[$UZS]\\ #,##0.00",
|
|
|
|
|
603: "[$VEB]\\ #,##0.00",
|
|
|
|
|
604: "[$VEF]\\ #,##0.00",
|
|
|
|
|
605: "[$VND]\\ #,##0.00",
|
|
|
|
|
606: "[$VUV]\\ #,##0.00",
|
|
|
|
|
607: "[$WST]\\ #,##0.00",
|
|
|
|
|
608: "[$XAF]\\ #,##0.00",
|
|
|
|
|
609: "[$XAG]\\ #,##0.00",
|
|
|
|
|
610: "[$XAU]\\ #,##0.00",
|
|
|
|
|
611: "[$XB5]\\ #,##0.00",
|
|
|
|
|
612: "[$XBA]\\ #,##0.00",
|
|
|
|
|
613: "[$XBB]\\ #,##0.00",
|
|
|
|
|
614: "[$XBC]\\ #,##0.00",
|
|
|
|
|
615: "[$XBD]\\ #,##0.00",
|
|
|
|
|
616: "[$XCD]\\ #,##0.00",
|
|
|
|
|
617: "[$XDR]\\ #,##0.00",
|
|
|
|
|
618: "[$XFO]\\ #,##0.00",
|
|
|
|
|
619: "[$XFU]\\ #,##0.00",
|
|
|
|
|
620: "[$XOF]\\ #,##0.00",
|
|
|
|
|
621: "[$XPD]\\ #,##0.00",
|
|
|
|
|
622: "[$XPF]\\ #,##0.00",
|
|
|
|
|
623: "[$XPT]\\ #,##0.00",
|
|
|
|
|
624: "[$XTS]\\ #,##0.00",
|
|
|
|
|
625: "[$XXX]\\ #,##0.00",
|
|
|
|
|
626: "[$YER]\\ #,##0.00",
|
|
|
|
|
627: "[$YUM]\\ #,##0.00",
|
|
|
|
|
628: "[$ZAR]\\ #,##0.00",
|
|
|
|
|
629: "[$ZMK]\\ #,##0.00",
|
|
|
|
|
630: "[$ZMW]\\ #,##0.00",
|
|
|
|
|
631: "[$ZWD]\\ #,##0.00",
|
|
|
|
|
632: "[$ZWL]\\ #,##0.00",
|
|
|
|
|
633: "[$ZWN]\\ #,##0.00",
|
|
|
|
|
634: "[$ZWR]\\ #,##0.00",
|
|
|
|
|
}
|
2022-02-17 00:09:11 +08:00
|
|
|
|
// supportedTokenTypes list the supported number format token types currently.
|
2022-02-14 00:05:47 +08:00
|
|
|
|
supportedTokenTypes = []string{
|
2023-05-04 10:52:26 +08:00
|
|
|
|
nfp.TokenSubTypeCurrencyString,
|
2022-03-19 00:05:47 +08:00
|
|
|
|
nfp.TokenSubTypeLanguageInfo,
|
|
|
|
|
nfp.TokenTypeColor,
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nfp.TokenTypeCurrencyLanguage,
|
|
|
|
|
nfp.TokenTypeDateTimes,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypeDecimalPoint,
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nfp.TokenTypeElapsedDateTimes,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypeExponential,
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nfp.TokenTypeGeneral,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypeHashPlaceHolder,
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nfp.TokenTypeLiteral,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypePercent,
|
2023-05-04 10:52:26 +08:00
|
|
|
|
nfp.TokenTypeSwitchArgument,
|
2022-02-25 22:24:08 +08:00
|
|
|
|
nfp.TokenTypeTextPlaceHolder,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypeThousandsSeparator,
|
2022-03-19 00:05:47 +08:00
|
|
|
|
nfp.TokenTypeZeroPlaceHolder,
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// supportedNumberTokenTypes list the supported number token types.
|
|
|
|
|
supportedNumberTokenTypes = []string{
|
2023-05-04 10:52:26 +08:00
|
|
|
|
nfp.TokenTypeExponential,
|
2023-04-30 11:10:51 +08:00
|
|
|
|
nfp.TokenTypeHashPlaceHolder,
|
|
|
|
|
nfp.TokenTypePercent,
|
|
|
|
|
nfp.TokenTypeZeroPlaceHolder,
|
|
|
|
|
}
|
|
|
|
|
// supportedDateTimeTokenTypes list the supported date and time token types.
|
|
|
|
|
supportedDateTimeTokenTypes = []string{
|
|
|
|
|
nfp.TokenTypeDateTimes,
|
|
|
|
|
nfp.TokenTypeElapsedDateTimes,
|
|
|
|
|
}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// supportedLanguageInfo directly maps the supported language ID and tags.
|
|
|
|
|
supportedLanguageInfo = map[string]languageInfo{
|
|
|
|
|
"36": {tags: []string{"af"}, localMonth: localMonthsNameAfrikaans, apFmt: apFmtAfrikaans},
|
|
|
|
|
"445": {tags: []string{"bn-IN"}, localMonth: localMonthsNameBangla, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"4": {tags: []string{"zh-Hans"}, localMonth: localMonthsNameChinese1, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"7804": {tags: []string{"zh"}, localMonth: localMonthsNameChinese1, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"804": {tags: []string{"zh-CN"}, localMonth: localMonthsNameChinese1, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"1004": {tags: []string{"zh-SG"}, localMonth: localMonthsNameChinese2, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"7C04": {tags: []string{"zh-Hant"}, localMonth: localMonthsNameChinese3, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"C04": {tags: []string{"zh-HK"}, localMonth: localMonthsNameChinese2, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"1404": {tags: []string{"zh-MO"}, localMonth: localMonthsNameChinese3, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"404": {tags: []string{"zh-TW"}, localMonth: localMonthsNameChinese3, apFmt: nfp.AmPm[2]},
|
|
|
|
|
"9": {tags: []string{"en"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"1000": {tags: []string{
|
|
|
|
|
"aa", "aa-DJ", "aa-ER", "aa-ER", "aa-NA", "agq", "agq-CM", "ak", "ak-GH", "sq-ML",
|
|
|
|
|
"gsw-LI", "gsw-CH", "ar-TD", "ar-KM", "ar-DJ", "ar-ER", "ar-IL", "ar-MR", "ar-PS",
|
|
|
|
|
"ar-SO", "ar-SS", "ar-SD", "ar-001", "ast", "ast-ES", "asa", "asa-TZ", "ksf", "ksf-CM",
|
|
|
|
|
"bm", "bm-Latn-ML", "bas", "bas-CM", "bem", "bem-ZM", "bez", "bez-TZ", "byn", "byn-ER",
|
|
|
|
|
"brx", "brx-IN", "ca-AD", "ca-FR", "ca-IT", "ceb", "ceb-Latn", "ceb-Latn-PH", "tzm-Latn-MA",
|
|
|
|
|
"ccp", "ccp-Cakm", "ccp-Cakm-BD", "ccp-Cakm-IN", "ce-RU", "cgg", "cgg-UG", "cu-RU", "swc",
|
|
|
|
|
"swc-CD", "kw", "ke-GB", "da-GL", "dua", "dua-CM", "nl-AW", "nl-BQ", "nl-CW", "nl-SX",
|
|
|
|
|
"nl-SR", "dz", "ebu", "ebu-KE", "en-AS", "en-AI", "en-AG", "en-AT", "en-BS", "en-BB",
|
|
|
|
|
"en-BE", "en-BM", "en-BW", "en-IO", "en-VG", "en-BI", "en-CM", "en-KY", "en-CX", "en-CC",
|
|
|
|
|
"en-CK", "en-CY", "en-DK", "en-DM", "en-ER", "en-150", "en-FK", "en-FI", "en-FJ", "en-GM",
|
|
|
|
|
"en-DE", "en-GH", "en-GI", "en-GD", "en-GU", "en-GG", "en-GY", "en-IM", "en-IL", "en-JE",
|
|
|
|
|
"en-KE", "en-KI", "en-LS", "en-LR", "en-MO", "en-MG", "en-MW", "en-MT", "en-MH", "en-MU",
|
|
|
|
|
"en-FM", "en-MS", "en-NA", "en-NR", "en-NL", "en-NG", "en-NU", "en-NF", "en-MP", "en-PK",
|
|
|
|
|
"en-PW", "en-PG", "en-PN", "en-PR", "en-RW", "en-KN", "en-LC", "en-VC", "en-WS", "en-SC",
|
|
|
|
|
"en-SL", "en-SX", "en-SI", "en-SB", "en-SS", "en-SH", "en-SD", "en-SZ", "en-SE", "en-CH",
|
|
|
|
|
"en-TZ", "en-TK", "en-TO", "en-TC", "en-TV", "en-UG", "en-UM", "en-VI", "en-VU", "en-001",
|
|
|
|
|
"en-ZM", "eo", "eo-001", "ee", "ee-GH", "ee-TG", "ewo", "ewo-CM", "fo-DK", "fr-DZ",
|
|
|
|
|
"fr-BJ", "fr-BF", "fr-BI", "fr-CF", "fr-TD", "fr-KM", "fr-CG", "fr-DJ", "fr-GQ", "fr-GF",
|
|
|
|
|
"fr-PF", "fr-GA", "fr-GP", "fr-GN", "fr-MG", "fr-MQ", "fr-MR", "fr-MU", "fr-YT", "fr-NC",
|
|
|
|
|
"fr-NE", "fr-RW", "fr-BL", "fr-MF", "fr-PM", "fr-SC", "fr-SY", "fr-TG", "fr-TN", "fr-VU",
|
|
|
|
|
"fr-WF", "fur", "fur-IT", "ff-Latn-BF", "ff-CM", "ff-Latn-CM", "ff-Latn-GM", "ff-Latn-GH",
|
|
|
|
|
"ff-GN", "ff-Latn-GN", "ff-Latn-GW", "ff-Latn-LR", "ff-MR", "ff-Latn-MR", "ff-Latn-NE",
|
|
|
|
|
"ff-Latn-SL", "lg", "lg-UG", "de-BE", "de-IT", "el-CY", "guz", "guz-KE", "ha-Latn-GH",
|
|
|
|
|
"ha-Latn-NG", "ia-FR", "ia-001", "it-SM", "it-VA", "jv", "jv-Latn", "jv-Latn-ID", "dyo",
|
|
|
|
|
"dyo-SN", "kea", "kea-CV", "kab", "kab-DZ", "kkj", "kkj-CM", "kln", "kln-KE", "kam",
|
|
|
|
|
"kam-KE", "ks-Arab-IN", "ki", "ki-KE", "sw-TZ", "sw-UG", "ko-KP", "khq", "khq-ML", "ses",
|
|
|
|
|
"ses-ML", "nmg", "nmq-CM", "ku-Arab-IR", "lkt", "lkt-US", "lag", "lag-TZ", "ln", "ln-AO",
|
|
|
|
|
"ln-CF", "ln-CD", "nds", "nds-DE", "nds-NL", "lu", "lu-CD", "luo", "luo", "luo-KE", "luy",
|
|
|
|
|
"luy-KE", "jmc", "jmc-TZ", "mgh", "mgh-MZ", "kde", "kde-TZ", "mg", "mg-MG", "gv", "gv-IM",
|
|
|
|
|
"mas", "mas-KE", "mas-TZ", "mas-IR", "mer", "mer-KE", "mgo", "mgo-CM", "mfe", "mfe-MU",
|
|
|
|
|
"mua", "mua-CM", "nqo", "nqo-GN", "nqa", "naq-NA", "nnh", "nnh-CM", "jgo", "jgo-CM",
|
|
|
|
|
"lrc-IQ", "lrc-IR", "nd", "nd-ZW", "nb-SJ", "nus", "nus-SD", "nus-SS", "nyn", "nyn-UG",
|
|
|
|
|
"om-KE", "os", "os-GE", "os-RU", "ps-PK", "fa-AF", "pt-AO", "pt-CV", "pt-GQ", "pt-GW",
|
|
|
|
|
"pt-LU", "pt-MO", "pt-MZ", "pt-ST", "pt-CH", "pt-TL", "prg-001", "ksh", "ksh-DE", "rof",
|
|
|
|
|
"rof-TZ", "rn", "rn-BI", "ru-BY", "ru-KZ", "ru-KG", "ru-UA", "rwk", "rwk-TZ", "ssy",
|
|
|
|
|
"ssy-ER", "saq", "saq-KE", "sg", "sq-CF", "sbp", "sbp-TZ", "seh", "seh-MZ", "ksb", "ksb-TZ",
|
|
|
|
|
"sn", "sn-Latn", "sn-Latn-ZW", "xog", "xog-UG", "so-DJ", "so-ET", "so-KE", "nr", "nr-ZA",
|
|
|
|
|
"st-LS", "es-BZ", "es-BR", "es-PH", "zgh", "zgh-Tfng-MA", "zgh-Tfng", "ss", "ss-ZA",
|
|
|
|
|
"ss-SZ", "sv-AX", "shi", "shi-Tfng", "shi-Tfng-MA", "shi-Latn", "shi-Latn-MA", "dav",
|
|
|
|
|
"dav-KE", "ta-MY", "ta-SG", "twq", "twq-NE", "teo", "teo-KE", "teo-UG", "bo-IN", "tig",
|
|
|
|
|
"tig-ER", "to", "to-TO", "tr-CY", "uz-Arab", "us-Arab-AF", "vai", "vai-Vaii",
|
|
|
|
|
"vai-Vaii-LR", "vai-Latn-LR", "vai-Latn", "vo", "vo-001", "vun", "vun-TZ", "wae",
|
|
|
|
|
"wae-CH", "wal", "wae-ET", "yav", "yav-CM", "yo-BJ", "dje", "dje-NE",
|
|
|
|
|
}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"C09": {tags: []string{"en-AU"}, localMonth: localMonthsNameEnglish, apFmt: strings.ToLower(nfp.AmPm[0])},
|
|
|
|
|
"2829": {tags: []string{"en-BZ"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"1009": {tags: []string{"en-CA"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"2409": {tags: []string{"en-029"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"3C09": {tags: []string{"en-HK"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"4009": {tags: []string{"en-IN"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"1809": {tags: []string{"en-IE"}, localMonth: localMonthsNameEnglish, apFmt: strings.ToLower(nfp.AmPm[0])},
|
|
|
|
|
"2009": {tags: []string{"en-JM"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"4409": {tags: []string{"en-MY"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"1409": {tags: []string{"en-NZ"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"3409": {tags: []string{"en-PH"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"4809": {tags: []string{"en-SG"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"1C09": {tags: []string{"en-ZA"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"2C09": {tags: []string{"en-TT"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"4C09": {tags: []string{"en-AE"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"809": {tags: []string{"en-GB"}, localMonth: localMonthsNameEnglish, apFmt: strings.ToLower(nfp.AmPm[0])},
|
|
|
|
|
"409": {tags: []string{"en-US"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"3009": {tags: []string{"en-ZW"}, localMonth: localMonthsNameEnglish, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"C": {tags: []string{"fr"}, localMonth: localMonthsNameFrench, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"7": {tags: []string{"de"}, localMonth: localMonthsNameGerman, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"C07": {tags: []string{"de-AT"}, localMonth: localMonthsNameAustria, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"407": {tags: []string{"de-DE"}, localMonth: localMonthsNameGerman, apFmt: nfp.AmPm[0]},
|
2022-02-22 08:22:18 +08:00
|
|
|
|
"3C": {tags: []string{"ga"}, localMonth: localMonthsNameIrish, apFmt: apFmtIrish},
|
|
|
|
|
"83C": {tags: []string{"ga-IE"}, localMonth: localMonthsNameIrish, apFmt: apFmtIrish},
|
2022-02-14 00:05:47 +08:00
|
|
|
|
"10": {tags: []string{"it"}, localMonth: localMonthsNameItalian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"11": {tags: []string{"ja"}, localMonth: localMonthsNameChinese3, apFmt: apFmtJapanese},
|
|
|
|
|
"411": {tags: []string{"ja-JP"}, localMonth: localMonthsNameChinese3, apFmt: apFmtJapanese},
|
|
|
|
|
"12": {tags: []string{"ko"}, localMonth: localMonthsNameKorean, apFmt: apFmtKorean},
|
|
|
|
|
"412": {tags: []string{"ko-KR"}, localMonth: localMonthsNameKorean, apFmt: apFmtKorean},
|
2022-02-25 22:24:08 +08:00
|
|
|
|
"7C50": {tags: []string{"mn-Mong"}, localMonth: localMonthsNameTraditionalMongolian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"850": {tags: []string{"mn-Mong-CN"}, localMonth: localMonthsNameTraditionalMongolian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"C50": {tags: []string{"mn-Mong-MN"}, localMonth: localMonthsNameTraditionalMongolian, apFmt: nfp.AmPm[0]},
|
2022-02-22 08:22:18 +08:00
|
|
|
|
"19": {tags: []string{"ru"}, localMonth: localMonthsNameRussian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"819": {tags: []string{"ru-MD"}, localMonth: localMonthsNameRussian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"419": {tags: []string{"ru-RU"}, localMonth: localMonthsNameRussian, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"A": {tags: []string{"es"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"2C0A": {tags: []string{"es-AR"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"200A": {tags: []string{"es-VE"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"400A": {tags: []string{"es-BO"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"340A": {tags: []string{"es-CL"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"240A": {tags: []string{"es-CO"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"140A": {tags: []string{"es-CR"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"5C0A": {tags: []string{"es-CU"}, localMonth: localMonthsNameSpanish, apFmt: apFmtCuba},
|
|
|
|
|
"1C0A": {tags: []string{"es-DO"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"300A": {tags: []string{"es-EC"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"440A": {tags: []string{"es-SV"}, localMonth: localMonthsNameSpanish, apFmt: apFmtSpanish},
|
|
|
|
|
"1E": {tags: []string{"th"}, localMonth: localMonthsNameThai, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"41E": {tags: []string{"th-TH"}, localMonth: localMonthsNameThai, apFmt: nfp.AmPm[0]},
|
2022-02-25 22:24:08 +08:00
|
|
|
|
"51": {tags: []string{"bo"}, localMonth: localMonthsNameTibetan, apFmt: apFmtTibetan},
|
|
|
|
|
"451": {tags: []string{"bo-CN"}, localMonth: localMonthsNameTibetan, apFmt: apFmtTibetan},
|
2022-02-22 08:22:18 +08:00
|
|
|
|
"1F": {tags: []string{"tr"}, localMonth: localMonthsNameTurkish, apFmt: apFmtTurkish},
|
|
|
|
|
"41F": {tags: []string{"tr-TR"}, localMonth: localMonthsNameTurkish, apFmt: apFmtTurkish},
|
|
|
|
|
"52": {tags: []string{"cy"}, localMonth: localMonthsNameWelsh, apFmt: apFmtWelsh},
|
|
|
|
|
"452": {tags: []string{"cy-GB"}, localMonth: localMonthsNameWelsh, apFmt: apFmtWelsh},
|
2022-02-23 22:42:07 +08:00
|
|
|
|
"2A": {tags: []string{"vi"}, localMonth: localMonthsNameVietnamese, apFmt: apFmtVietnamese},
|
|
|
|
|
"42A": {tags: []string{"vi-VN"}, localMonth: localMonthsNameVietnamese, apFmt: apFmtVietnamese},
|
|
|
|
|
"88": {tags: []string{"wo"}, localMonth: localMonthsNameWolof, apFmt: apFmtWolof},
|
|
|
|
|
"488": {tags: []string{"wo-SN"}, localMonth: localMonthsNameWolof, apFmt: apFmtWolof},
|
|
|
|
|
"34": {tags: []string{"xh"}, localMonth: localMonthsNameXhosa, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"434": {tags: []string{"xh-ZA"}, localMonth: localMonthsNameXhosa, apFmt: nfp.AmPm[0]},
|
2022-02-22 08:22:18 +08:00
|
|
|
|
"78": {tags: []string{"ii"}, localMonth: localMonthsNameYi, apFmt: apFmtYi},
|
|
|
|
|
"478": {tags: []string{"ii-CN"}, localMonth: localMonthsNameYi, apFmt: apFmtYi},
|
|
|
|
|
"35": {tags: []string{"zu"}, localMonth: localMonthsNameZulu, apFmt: nfp.AmPm[0]},
|
|
|
|
|
"435": {tags: []string{"zu-ZA"}, localMonth: localMonthsNameZulu, apFmt: nfp.AmPm[0]},
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
// monthNamesBangla list the month names in the Bangla.
|
|
|
|
|
monthNamesBangla = []string{
|
|
|
|
|
"\u099C\u09BE\u09A8\u09C1\u09AF\u09BC\u09BE\u09B0\u09C0",
|
|
|
|
|
"\u09AB\u09C7\u09AC\u09CD\u09B0\u09C1\u09AF\u09BC\u09BE\u09B0\u09C0",
|
|
|
|
|
"\u09AE\u09BE\u09B0\u09CD\u099A",
|
|
|
|
|
"\u098F\u09AA\u09CD\u09B0\u09BF\u09B2",
|
|
|
|
|
"\u09AE\u09C7",
|
|
|
|
|
"\u099C\u09C1\u09A8",
|
|
|
|
|
"\u099C\u09C1\u09B2\u09BE\u0987",
|
|
|
|
|
"\u0986\u0997\u09B8\u09CD\u099F",
|
|
|
|
|
"\u09B8\u09C7\u09AA\u09CD\u099F\u09C7\u09AE\u09CD\u09AC\u09B0",
|
|
|
|
|
"\u0985\u0995\u09CD\u099F\u09CB\u09AC\u09B0",
|
|
|
|
|
"\u09A8\u09AD\u09C7\u09AE\u09CD\u09AC\u09B0",
|
|
|
|
|
"\u09A1\u09BF\u09B8\u09C7\u09AE\u09CD\u09AC\u09B0",
|
|
|
|
|
}
|
|
|
|
|
// monthNamesAfrikaans list the month names in the Afrikaans.
|
|
|
|
|
monthNamesAfrikaans = []string{"Januarie", "Februarie", "Maart", "April", "Mei", "Junie", "Julie", "Augustus", "September", "Oktober", "November", "Desember"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesAfrikaansAbbr lists the month name abbreviations in Afrikaans
|
|
|
|
|
monthNamesAfrikaansAbbr = []string{"Jan.", "Feb.", "Maa.", "Apr.", "Mei", "Jun.", "Jul.", "Aug.", "Sep.", "Okt.", "Nov.", "Des."}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// monthNamesChinese list the month names in the Chinese.
|
|
|
|
|
monthNamesChinese = []string{"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesChineseAbbr1 list the month number and character abbreviation in Chinese
|
|
|
|
|
monthNamesChineseAbbrPlus = []string{"0月", "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月"}
|
|
|
|
|
// monthNamesChinesePlus list the month names in Chinese plus the character 月
|
|
|
|
|
monthNamesChinesePlus = []string{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"}
|
|
|
|
|
// monthNamesKoreanAbbrPlus lists out the month number plus 월 for the Korean language
|
|
|
|
|
monthNamesKoreanAbbrPlus = []string{"0월", "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월"}
|
|
|
|
|
// monthNamesTradMongolian lists the month number for use with traditional Mongolian
|
|
|
|
|
monthNamesTradMongolian = []string{"M01", "M02", "M03", "M04", "M05", "M06", "M07", "M08", "M09", "M10", "M11", "M12"}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// monthNamesFrench list the month names in the French.
|
|
|
|
|
monthNamesFrench = []string{"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesFrenchAbbr lists the month name abbreviations in French
|
|
|
|
|
monthNamesFrenchAbbr = []string{"janv.", "févr.", "mars", "avri.", "mai", "juin", "juil.", "août", "sept.", "octo.", "nove.", "déce."}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// monthNamesGerman list the month names in the German.
|
|
|
|
|
monthNamesGerman = []string{"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesGermanAbbr list the month abbreviations in German
|
|
|
|
|
monthNamesGermanAbbr = []string{"Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// monthNamesAustria list the month names in the Austria.
|
|
|
|
|
monthNamesAustria = []string{"Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesAustriaAbbr list the month name abbreviations in Austrian
|
|
|
|
|
monthNamesAustriaAbbr = []string{"Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesIrish list the month names in the Irish.
|
|
|
|
|
monthNamesIrish = []string{"Eanáir", "Feabhra", "Márta", "Aibreán", "Bealtaine", "Meitheamh", "Iúil", "Lúnasa", "Meán Fómhair", "Deireadh Fómhair", "Samhain", "Nollaig"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesIrishAbbr lists the month abbreviations in Irish
|
|
|
|
|
monthNamesIrishAbbr = []string{"Ean", "Feabh", "Márta", "Aib", "Beal", "Meith", "Iúil", "Lún", "MFómh", "DFómh", "Samh", "Noll"}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// monthNamesItalian list the month names in the Italian.
|
|
|
|
|
monthNamesItalian = []string{"gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesItalianAbbr list the month name abbreviations in Italian
|
|
|
|
|
monthNamesItalianAbbr = []string{"gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic"}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesRussian list the month names in the Russian.
|
|
|
|
|
monthNamesRussian = []string{"январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesRussianAbbr list the month abbreviations for Russian.
|
|
|
|
|
monthNamesRussianAbbr = []string{"янв.", "фев.", "март", "апр.", "май", "июнь", "июль", "авг.", "сен.", "окт.", "ноя.", "дек."}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesSpanish list the month names in the Spanish.
|
|
|
|
|
monthNamesSpanish = []string{"enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesSpanishAbbr list the month abbreviations in Spanish
|
|
|
|
|
monthNamesSpanishAbbr = []string{"ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesThai list the month names in the Thai.
|
|
|
|
|
monthNamesThai = []string{
|
|
|
|
|
"\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c",
|
|
|
|
|
"\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19",
|
|
|
|
|
"\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19",
|
|
|
|
|
"\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19",
|
|
|
|
|
"\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21",
|
|
|
|
|
"\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19",
|
|
|
|
|
"\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21",
|
|
|
|
|
}
|
2022-02-25 22:24:08 +08:00
|
|
|
|
// monthNamesTibetan list the month names in the Tibetan.
|
|
|
|
|
monthNamesTibetan = []string{
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f44\u0f0b\u0f54\u0f7c\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f42\u0f66\u0f74\u0f58\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f5e\u0f72\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f63\u0f94\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0fb2\u0f74\u0f42\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f51\u0f74\u0f53\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f51\u0f42\u0f74\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f66\u0fa4\u0fb1\u0f72\u0f0b\u0f5f\u0fb3\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f54\u0f0d",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f45\u0f72\u0f42\u0f0b\u0f54\u0f0b",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f56\u0f0b\u0f56\u0f45\u0f74\u0f0b\u0f42\u0f49\u0f72\u0f66\u0f0b\u0f54\u0f0b",
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesTibetanAbbr lists the month name abbreviations in Tibetan
|
|
|
|
|
monthNamesTibetanAbbr = []string{
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f21",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f22",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f23",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f24",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f25",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f26",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f27",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f28",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f29",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f21\u0f20",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f21\u0f21",
|
|
|
|
|
"\u0f5f\u0fb3\u0f0b\u0f21\u0f22",
|
|
|
|
|
}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesTurkish list the month names in the Turkish.
|
|
|
|
|
monthNamesTurkish = []string{"Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesTurkishAbbr lists the month name abbreviations in Turkish, this prevents string concatenation
|
|
|
|
|
monthNamesTurkishAbbr = []string{"Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara"}
|
|
|
|
|
// monthNamesVietnamese list the month name used for Vietnamese
|
|
|
|
|
monthNamesVietnamese = []string{"Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"}
|
|
|
|
|
// monthNamesVietnameseAbbr3 list the mid-form abbreviation for Vietnamese months
|
|
|
|
|
monthNamesVietnameseAbbr3 = []string{"Thg 1", "Thg 2", "Thg 3", "Thg 4", "Thg 5", "Thg 6", "Thg 7", "Thg 8", "Thg 9", "Thg 10", "Thg 11", "Thg 12"}
|
|
|
|
|
// monthNamesVietnameseAbbr5 list the short-form abbreviation for Vietnamese months
|
|
|
|
|
monthNamesVietnameseAbbr5 = []string{"T 1", "T 2", "T 3", "T 4", "T 5", "T 6", "T 7", "T 8", "T 9", "T 10", "T 11", "T 12"}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesWelsh list the month names in the Welsh.
|
|
|
|
|
monthNamesWelsh = []string{"Ionawr", "Chwefror", "Mawrth", "Ebrill", "Mai", "Mehefin", "Gorffennaf", "Awst", "Medi", "Hydref", "Tachwedd", "Rhagfyr"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesWelshAbbr lists the month name abbreviations in Welsh, this prevents string concatenation
|
|
|
|
|
monthNamesWelshAbbr = []string{"Ion", "Chwef", "Maw", "Ebr", "Mai", "Meh", "Gorff", "Awst", "Medi", "Hyd", "Tach", "Rhag"}
|
2022-02-23 22:42:07 +08:00
|
|
|
|
// monthNamesWolof list the month names in the Wolof.
|
|
|
|
|
monthNamesWolof = []string{"Samwiye", "Fewriye", "Maars", "Awril", "Me", "Suwe", "Sullet", "Ut", "Septàmbar", "Oktoobar", "Noowàmbar", "Desàmbar"}
|
2023-01-25 12:22:28 +08:00
|
|
|
|
// monthNamesWolofAbbr list the month name abbreviations in Wolof, this prevents string concatenation
|
|
|
|
|
monthNamesWolofAbbr = []string{"Sam.", "Few.", "Maa", "Awr.", "Me", "Suw", "Sul.", "Ut", "Sept.", "Okt.", "Now.", "Des."}
|
2022-02-23 22:42:07 +08:00
|
|
|
|
// monthNamesXhosa list the month names in the Xhosa.
|
2023-01-25 12:22:28 +08:00
|
|
|
|
monthNamesXhosa = []string{"uJanuwari", "uFebuwari", "uMatshi", "uAprili", "uMeyi", "uJuni", "uJulayi", "uAgasti", "uSeptemba", "uOktobha", "uNovemba", "uDisemba"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesXhosaAbbr list the month abbreviations in the Xhosa, this prevents string concatenation
|
2023-01-25 12:22:28 +08:00
|
|
|
|
monthNamesXhosaAbbr = []string{"uJan.", "uFeb.", "uMat.", "uEpr.", "uMey.", "uJun.", "uJul.", "uAg.", "uSep.", "uOkt.", "uNov.", "uDis."}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesYi list the month names in the Yi.
|
|
|
|
|
monthNamesYi = []string{"\ua2cd", "\ua44d", "\ua315", "\ua1d6", "\ua26c", "\ua0d8", "\ua3c3", "\ua246", "\ua22c", "\ua2b0", "\ua2b0\ua2aa", "\ua2b0\ua44b"}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
// monthNamesYiSuffix lists the month names in Yi with the "\ua1aa" suffix
|
|
|
|
|
monthNamesYiSuffix = []string{"\ua2cd\ua1aa", "\ua44d\ua1aa", "\ua315\ua1aa", "\ua1d6\ua1aa", "\ua26c\ua1aa", "\ua0d8\ua1aa", "\ua3c3\ua1aa", "\ua246\ua1aa", "\ua22c\ua1aa", "\ua2b0\ua1aa", "\ua2b0\ua2aa\ua1aa", "\ua2b0\ua44b\ua1aa"}
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// monthNamesZulu list the month names in the Zulu.
|
|
|
|
|
monthNamesZulu = []string{"Januwari", "Febhuwari", "Mashi", "Ephreli", "Meyi", "Juni", "Julayi", "Agasti", "Septemba", "Okthoba", "Novemba", "Disemba"}
|
2023-02-07 00:08:11 +08:00
|
|
|
|
// monthNamesZuluAbbr list the month name abbreviations in Zulu
|
2023-01-26 10:35:13 +08:00
|
|
|
|
monthNamesZuluAbbr = []string{"Jan", "Feb", "Mas", "Eph", "Mey", "Jun", "Jul", "Agas", "Sep", "Okt", "Nov", "Dis"}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// apFmtAfrikaans defined the AM/PM name in the Afrikaans.
|
|
|
|
|
apFmtAfrikaans = "vm./nm."
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// apFmtCuba defined the AM/PM name in the Cuba.
|
|
|
|
|
apFmtCuba = "a.m./p.m."
|
|
|
|
|
// apFmtIrish defined the AM/PM name in the Irish.
|
|
|
|
|
apFmtIrish = "r.n./i.n."
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// apFmtJapanese defined the AM/PM name in the Japanese.
|
|
|
|
|
apFmtJapanese = "午前/午後"
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// apFmtKorean defined the AM/PM name in the Korean.
|
2022-02-14 00:05:47 +08:00
|
|
|
|
apFmtKorean = "오전/오후"
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// apFmtSpanish defined the AM/PM name in the Spanish.
|
|
|
|
|
apFmtSpanish = "a. m./p. m."
|
2022-02-25 22:24:08 +08:00
|
|
|
|
// apFmtTibetan defined the AM/PM name in the Tibetan.
|
|
|
|
|
apFmtTibetan = "\u0f66\u0f94\u0f0b\u0f51\u0fb2\u0f7c\u0f0b/\u0f55\u0fb1\u0f72\u0f0b\u0f51\u0fb2\u0f7c\u0f0b"
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// apFmtTurkish defined the AM/PM name in the Turkish.
|
|
|
|
|
apFmtTurkish = "\u00F6\u00F6/\u00F6\u0053"
|
2022-02-23 22:42:07 +08:00
|
|
|
|
// apFmtVietnamese defined the AM/PM name in the Vietnamese.
|
|
|
|
|
apFmtVietnamese = "SA/CH"
|
|
|
|
|
// apFmtWolof defined the AM/PM name in the Wolof.
|
|
|
|
|
apFmtWolof = "Sub/Ngo"
|
|
|
|
|
// apFmtYi defined the AM/PM name in the Yi.
|
2022-02-22 08:22:18 +08:00
|
|
|
|
apFmtYi = "\ua3b8\ua111/\ua06f\ua2d2"
|
|
|
|
|
// apFmtWelsh defined the AM/PM name in the Welsh.
|
|
|
|
|
apFmtWelsh = "yb/yh"
|
2023-05-04 10:52:26 +08:00
|
|
|
|
// switchArgumentFunc defined the switch argument printer function
|
|
|
|
|
switchArgumentFunc = map[string]func(s string) string{
|
|
|
|
|
"[DBNum1]": func(s string) string {
|
|
|
|
|
r := strings.NewReplacer(
|
|
|
|
|
"0", "\u25cb", "1", "\u4e00", "2", "\u4e8c", "3", "\u4e09", "4", "\u56db",
|
|
|
|
|
"5", "\u4e94", "6", "\u516d", "7", "\u4e03", "8", "\u516b", "9", "\u4e5d",
|
|
|
|
|
)
|
|
|
|
|
return r.Replace(s)
|
|
|
|
|
},
|
|
|
|
|
"[DBNum2]": func(s string) string {
|
|
|
|
|
r := strings.NewReplacer(
|
|
|
|
|
"0", "\u96f6", "1", "\u58f9", "2", "\u8d30", "3", "\u53c1", "4", "\u8086",
|
|
|
|
|
"5", "\u4f0d", "6", "\u9646", "7", "\u67d2", "8", "\u634c", "9", "\u7396",
|
|
|
|
|
)
|
|
|
|
|
return r.Replace(s)
|
|
|
|
|
},
|
|
|
|
|
"[DBNum3]": func(s string) string {
|
|
|
|
|
r := strings.NewReplacer(
|
|
|
|
|
"0", "\uff10", "1", "\uff11", "2", "\uff12", "3", "\uff13", "4", "\uff14",
|
|
|
|
|
"5", "\uff15", "6", "\uff16", "7", "\uff17", "8", "\uff18", "9", "\uff19",
|
|
|
|
|
)
|
|
|
|
|
return r.Replace(s)
|
|
|
|
|
},
|
|
|
|
|
}
|
2022-02-14 00:05:47 +08:00
|
|
|
|
)
|
|
|
|
|
|
2023-05-11 09:08:38 +08:00
|
|
|
|
// applyBuiltInNumFmt provides a function to returns a value after formatted
|
|
|
|
|
// with built-in number format code, or specified sort date format code.
|
|
|
|
|
func (f *File) applyBuiltInNumFmt(c *xlsxC, fmtCode string, numFmtID int, date1904 bool, cellType CellType) string {
|
2023-06-08 09:50:38 +08:00
|
|
|
|
if f.options != nil && f.options.ShortDatePattern != "" {
|
|
|
|
|
if numFmtID == 14 {
|
|
|
|
|
fmtCode = f.options.ShortDatePattern
|
|
|
|
|
}
|
|
|
|
|
if numFmtID == 22 {
|
|
|
|
|
fmtCode = fmt.Sprintf("%s hh:mm", f.options.ShortDatePattern)
|
|
|
|
|
}
|
2023-05-11 09:08:38 +08:00
|
|
|
|
}
|
|
|
|
|
return format(c.V, fmtCode, date1904, cellType, f.options)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// langNumFmtFuncEnUS returns number format code by given date and time pattern
|
|
|
|
|
// for country code en-us.
|
|
|
|
|
func (f *File) langNumFmtFuncEnUS(numFmtID int) string {
|
|
|
|
|
shortDatePattern, longTimePattern := "M/d/yy", "h:mm:ss"
|
|
|
|
|
if f.options.ShortDatePattern != "" {
|
|
|
|
|
shortDatePattern = f.options.ShortDatePattern
|
|
|
|
|
}
|
|
|
|
|
if f.options.LongTimePattern != "" {
|
|
|
|
|
longTimePattern = f.options.LongTimePattern
|
|
|
|
|
}
|
|
|
|
|
if 32 <= numFmtID && numFmtID <= 35 {
|
|
|
|
|
return longTimePattern
|
|
|
|
|
}
|
|
|
|
|
if (27 <= numFmtID && numFmtID <= 31) || (50 <= numFmtID && numFmtID <= 58) {
|
|
|
|
|
return shortDatePattern
|
|
|
|
|
}
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// checkDateTimePattern check and validate date and time options field value.
|
|
|
|
|
func (f *File) checkDateTimePattern() error {
|
|
|
|
|
for _, pattern := range []string{f.options.LongDatePattern, f.options.LongTimePattern, f.options.ShortDatePattern} {
|
|
|
|
|
p := nfp.NumberFormatParser()
|
|
|
|
|
for _, section := range p.Parse(pattern) {
|
|
|
|
|
for _, token := range section.Items {
|
2023-05-27 00:22:35 +08:00
|
|
|
|
if inStrSlice(supportedTokenTypes, token.TType, false) == -1 || inStrSlice(supportedNumberTokenTypes, token.TType, false) != -1 {
|
2023-05-11 09:08:38 +08:00
|
|
|
|
return ErrUnsupportedNumberFormat
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// langNumFmtFuncZhCN returns number format code by given date and time pattern
|
|
|
|
|
// for country code zh-cn.
|
|
|
|
|
func (f *File) langNumFmtFuncZhCN(numFmtID int) string {
|
|
|
|
|
if numFmtID == 30 && f.options.ShortDatePattern != "" {
|
|
|
|
|
return f.options.ShortDatePattern
|
|
|
|
|
}
|
|
|
|
|
if (32 <= numFmtID && numFmtID <= 33) && f.options.LongTimePattern != "" {
|
|
|
|
|
return f.options.LongTimePattern
|
|
|
|
|
}
|
|
|
|
|
return langNumFmt["zh-cn"][numFmtID]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getBuiltInNumFmtCode convert number format index to number format code with
|
|
|
|
|
// specified locale and language.
|
|
|
|
|
func (f *File) getBuiltInNumFmtCode(numFmtID int) (string, bool) {
|
|
|
|
|
if fmtCode, ok := builtInNumFmt[numFmtID]; ok {
|
|
|
|
|
return fmtCode, true
|
|
|
|
|
}
|
|
|
|
|
if (27 <= numFmtID && numFmtID <= 36) || (50 <= numFmtID && numFmtID <= 81) {
|
|
|
|
|
if f.options.CultureInfo == CultureNameEnUS {
|
|
|
|
|
return f.langNumFmtFuncEnUS(numFmtID), true
|
|
|
|
|
}
|
|
|
|
|
if f.options.CultureInfo == CultureNameZhCN {
|
|
|
|
|
return f.langNumFmtFuncZhCN(numFmtID), true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-13 00:06:30 +08:00
|
|
|
|
// prepareNumberic split the number into two before and after parts by a
|
|
|
|
|
// decimal point.
|
|
|
|
|
func (nf *numberFormat) prepareNumberic(value string) {
|
2023-04-19 00:05:59 +08:00
|
|
|
|
if nf.cellType != CellTypeNumber && nf.cellType != CellTypeDate {
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-09-28 00:04:17 +08:00
|
|
|
|
if nf.isNumeric, _, _ = isNumeric(value); !nf.isNumeric {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// format provides a function to return a string parse by number format
|
|
|
|
|
// expression. If the given number format is not supported, this will return
|
|
|
|
|
// the original cell value.
|
2023-05-06 20:34:18 +08:00
|
|
|
|
func format(value, numFmt string, date1904 bool, cellType CellType, opts *Options) string {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
p := nfp.NumberFormatParser()
|
2023-05-06 20:34:18 +08:00
|
|
|
|
nf := numberFormat{opts: opts, section: p.Parse(numFmt), value: value, date1904: date1904, cellType: cellType}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
nf.number, nf.valueSectionType = nf.getValueSectionType(value)
|
|
|
|
|
nf.prepareNumberic(value)
|
|
|
|
|
for i, section := range nf.section {
|
|
|
|
|
nf.sectionIdx = i
|
|
|
|
|
if section.Type != nf.valueSectionType {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2022-04-04 00:21:33 +08:00
|
|
|
|
if nf.isNumeric {
|
2022-02-18 00:02:39 +08:00
|
|
|
|
switch section.Type {
|
|
|
|
|
case nfp.TokenSectionPositive:
|
|
|
|
|
return nf.positiveHandler()
|
|
|
|
|
case nfp.TokenSectionNegative:
|
|
|
|
|
return nf.negativeHandler()
|
|
|
|
|
default:
|
|
|
|
|
return nf.zeroHandler()
|
|
|
|
|
}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2022-02-18 00:02:39 +08:00
|
|
|
|
return nf.textHandler()
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
return value
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// getNumberPartLen returns the length of integer and fraction parts for the
|
|
|
|
|
// numeric.
|
|
|
|
|
func getNumberPartLen(n float64) (int, int) {
|
|
|
|
|
parts := strings.Split(strconv.FormatFloat(math.Abs(n), 'f', -1, 64), ".")
|
|
|
|
|
if len(parts) == 2 {
|
|
|
|
|
return len(parts[0]), len(parts[1])
|
|
|
|
|
}
|
|
|
|
|
return len(parts[0]), 0
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 00:14:44 +08:00
|
|
|
|
// getNumberFmtConf generate the number format padding and placeholder
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// configurations.
|
|
|
|
|
func (nf *numberFormat) getNumberFmtConf() {
|
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if token.TType == nfp.TokenTypeHashPlaceHolder {
|
|
|
|
|
if nf.usePointer {
|
|
|
|
|
nf.fracHolder += len(token.TValue)
|
|
|
|
|
} else {
|
|
|
|
|
nf.intHolder += len(token.TValue)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeExponential {
|
|
|
|
|
nf.useScientificNotation = true
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeThousandsSeparator {
|
|
|
|
|
nf.useCommaSep = true
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypePercent {
|
|
|
|
|
nf.percent += len(token.TValue)
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeDecimalPoint {
|
|
|
|
|
nf.usePointer = true
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeSwitchArgument {
|
|
|
|
|
nf.switchArgument = token.TValue
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeZeroPlaceHolder {
|
|
|
|
|
if nf.usePointer {
|
|
|
|
|
if nf.useScientificNotation {
|
|
|
|
|
nf.expBaseLen += len(token.TValue)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
nf.fracPadding += len(token.TValue)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
nf.intPadding += len(token.TValue)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// printNumberLiteral apply literal tokens for the pre-formatted text.
|
|
|
|
|
func (nf *numberFormat) printNumberLiteral(text string) string {
|
|
|
|
|
var result string
|
2023-05-04 10:52:26 +08:00
|
|
|
|
var useLiteral, useZeroPlaceHolder bool
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if nf.usePositive {
|
|
|
|
|
result += "-"
|
|
|
|
|
}
|
2023-05-30 00:14:44 +08:00
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeCurrencyLanguage {
|
2023-06-18 00:12:50 +08:00
|
|
|
|
if changeNumFmtCode, err := nf.currencyLanguageHandler(token); err != nil || changeNumFmtCode {
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
result += nf.currencyString
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeLiteral {
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if useZeroPlaceHolder {
|
|
|
|
|
useLiteral = true
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
result += token.TValue
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeZeroPlaceHolder {
|
|
|
|
|
if useLiteral && useZeroPlaceHolder {
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
if !useZeroPlaceHolder {
|
|
|
|
|
useZeroPlaceHolder = true
|
|
|
|
|
result += text
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.printSwitchArgument(result)
|
2023-04-30 11:10:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// printCommaSep format number with thousands separator.
|
|
|
|
|
func printCommaSep(text string) string {
|
|
|
|
|
var (
|
|
|
|
|
target strings.Builder
|
|
|
|
|
subStr = strings.Split(text, ".")
|
|
|
|
|
length = len(subStr[0])
|
|
|
|
|
)
|
|
|
|
|
for i := 0; i < length; i++ {
|
|
|
|
|
if i > 0 && (length-i)%3 == 0 {
|
|
|
|
|
target.WriteString(",")
|
|
|
|
|
}
|
2023-05-22 09:24:28 +08:00
|
|
|
|
target.WriteByte(text[i])
|
2023-04-30 11:10:51 +08:00
|
|
|
|
}
|
|
|
|
|
if len(subStr) == 2 {
|
|
|
|
|
target.WriteString(".")
|
|
|
|
|
target.WriteString(subStr[1])
|
|
|
|
|
}
|
|
|
|
|
return target.String()
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-04 10:52:26 +08:00
|
|
|
|
// printSwitchArgument format number with switch argument.
|
|
|
|
|
func (nf *numberFormat) printSwitchArgument(text string) string {
|
|
|
|
|
if nf.switchArgument == "" {
|
|
|
|
|
return text
|
|
|
|
|
}
|
|
|
|
|
if fn, ok := switchArgumentFunc[nf.switchArgument]; ok {
|
|
|
|
|
return fn(text)
|
|
|
|
|
}
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// printBigNumber format number which precision great than 15 with fraction
|
|
|
|
|
// zero padding and percentage symbol.
|
|
|
|
|
func (nf *numberFormat) printBigNumber(decimal float64, fracLen int) string {
|
|
|
|
|
var exp float64
|
|
|
|
|
if nf.percent > 0 {
|
|
|
|
|
exp = 1
|
|
|
|
|
}
|
|
|
|
|
result := strings.TrimLeft(strconv.FormatFloat(decimal*math.Pow(100, exp), 'f', -1, 64), "-")
|
|
|
|
|
if nf.useCommaSep {
|
|
|
|
|
result = printCommaSep(result)
|
|
|
|
|
}
|
|
|
|
|
if fracLen > 0 {
|
|
|
|
|
if parts := strings.Split(result, "."); len(parts) == 2 {
|
|
|
|
|
fracPartLen := len(parts[1])
|
|
|
|
|
if fracPartLen < fracLen {
|
|
|
|
|
result = fmt.Sprintf("%s%s", result, strings.Repeat("0", fracLen-fracPartLen))
|
|
|
|
|
}
|
|
|
|
|
if fracPartLen > fracLen {
|
|
|
|
|
result = fmt.Sprintf("%s.%s", parts[0], parts[1][:fracLen])
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
result = fmt.Sprintf("%s.%s", result, strings.Repeat("0", fracLen))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if nf.percent > 0 {
|
|
|
|
|
return fmt.Sprintf("%s%%", result)
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// numberHandler handling number format expression for positive and negative
|
|
|
|
|
// numeric.
|
|
|
|
|
func (nf *numberFormat) numberHandler() string {
|
|
|
|
|
var (
|
|
|
|
|
num = nf.number
|
|
|
|
|
intPart, fracPart = getNumberPartLen(nf.number)
|
|
|
|
|
intLen, fracLen int
|
|
|
|
|
result string
|
|
|
|
|
)
|
|
|
|
|
nf.getNumberFmtConf()
|
|
|
|
|
if intLen = intPart; nf.intPadding > intPart {
|
|
|
|
|
intLen = nf.intPadding
|
|
|
|
|
}
|
|
|
|
|
if fracLen = fracPart; fracPart > nf.fracHolder+nf.fracPadding {
|
|
|
|
|
fracLen = nf.fracHolder + nf.fracPadding
|
|
|
|
|
}
|
|
|
|
|
if nf.fracPadding > fracPart {
|
|
|
|
|
fracLen = nf.fracPadding
|
|
|
|
|
}
|
|
|
|
|
if isNum, precision, decimal := isNumeric(nf.value); isNum {
|
|
|
|
|
if precision > 15 && intLen+fracLen > 15 {
|
|
|
|
|
return nf.printNumberLiteral(nf.printBigNumber(decimal, fracLen))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
paddingLen := intLen + fracLen
|
|
|
|
|
if fracLen > 0 {
|
|
|
|
|
paddingLen++
|
|
|
|
|
}
|
|
|
|
|
flag := "f"
|
|
|
|
|
if nf.useScientificNotation {
|
|
|
|
|
if nf.expBaseLen != 2 {
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
flag = "E"
|
|
|
|
|
}
|
|
|
|
|
fmtCode := fmt.Sprintf("%%0%d.%d%s%s", paddingLen, fracLen, flag, strings.Repeat("%%", nf.percent))
|
|
|
|
|
if nf.percent > 0 {
|
|
|
|
|
num *= math.Pow(100, float64(nf.percent))
|
|
|
|
|
}
|
|
|
|
|
if result = fmt.Sprintf(fmtCode, math.Abs(num)); nf.useCommaSep {
|
|
|
|
|
result = printCommaSep(result)
|
|
|
|
|
}
|
|
|
|
|
return nf.printNumberLiteral(result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dateTimeHandler handling data and time number format expression for a
|
|
|
|
|
// positive numeric.
|
2023-05-04 10:52:26 +08:00
|
|
|
|
func (nf *numberFormat) dateTimeHandler() string {
|
2022-04-30 09:54:11 +08:00
|
|
|
|
nf.t, nf.hours, nf.seconds = timeFromExcelTime(nf.number, nf.date1904), false, false
|
2022-02-13 00:06:30 +08:00
|
|
|
|
for i, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if token.TType == nfp.TokenTypeCurrencyLanguage {
|
2023-06-18 00:12:50 +08:00
|
|
|
|
if changeNumFmtCode, err := nf.currencyLanguageHandler(token); err != nil || changeNumFmtCode {
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.value
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
nf.result += nf.currencyString
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeDateTimes {
|
|
|
|
|
nf.dateTimesHandler(i, token)
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeElapsedDateTimes {
|
|
|
|
|
nf.elapsedDateTimesHandler(token)
|
|
|
|
|
}
|
|
|
|
|
if token.TType == nfp.TokenTypeLiteral {
|
|
|
|
|
nf.result += token.TValue
|
|
|
|
|
continue
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeDecimalPoint {
|
|
|
|
|
nf.result += "."
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeSwitchArgument {
|
|
|
|
|
nf.switchArgument = token.TValue
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeZeroPlaceHolder {
|
|
|
|
|
zeroHolderLen := len(token.TValue)
|
|
|
|
|
if zeroHolderLen > 3 {
|
|
|
|
|
zeroHolderLen = 3
|
2022-03-19 00:05:47 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
nf.result += fmt.Sprintf("%03d", nf.t.Nanosecond()/1e6)[:zeroHolderLen]
|
2022-03-19 00:05:47 +08:00
|
|
|
|
}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.printSwitchArgument(nf.result)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// positiveHandler will be handling positive selection for a number format
|
|
|
|
|
// expression.
|
|
|
|
|
func (nf *numberFormat) positiveHandler() string {
|
|
|
|
|
var fmtNum bool
|
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if inStrSlice(supportedTokenTypes, token.TType, true) == -1 || token.TType == nfp.TokenTypeGeneral {
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
if inStrSlice(supportedNumberTokenTypes, token.TType, true) != -1 {
|
|
|
|
|
fmtNum = true
|
|
|
|
|
}
|
|
|
|
|
if inStrSlice(supportedDateTimeTokenTypes, token.TType, true) != -1 {
|
|
|
|
|
if fmtNum || nf.number < 0 {
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
var useDateTimeTokens bool
|
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if inStrSlice(supportedDateTimeTokenTypes, token.TType, false) != -1 {
|
|
|
|
|
if useDateTimeTokens && nf.useMillisecond {
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
useDateTimeTokens = true
|
|
|
|
|
}
|
|
|
|
|
if inStrSlice(supportedNumberTokenTypes, token.TType, false) != -1 {
|
|
|
|
|
if token.TType == nfp.TokenTypeZeroPlaceHolder {
|
|
|
|
|
nf.useMillisecond = true
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
return nf.value
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
return nf.dateTimeHandler()
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.numberHandler()
|
2023-04-30 11:10:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// currencyLanguageHandler will be handling currency and language types tokens
|
|
|
|
|
// for a number format expression.
|
2023-06-18 00:12:50 +08:00
|
|
|
|
func (nf *numberFormat) currencyLanguageHandler(token nfp.Token) (bool, error) {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
for _, part := range token.Parts {
|
|
|
|
|
if inStrSlice(supportedTokenTypes, part.Token.TType, true) == -1 {
|
2023-06-18 00:12:50 +08:00
|
|
|
|
return false, ErrUnsupportedNumberFormat
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if part.Token.TType == nfp.TokenSubTypeLanguageInfo {
|
2023-05-06 20:34:18 +08:00
|
|
|
|
if strings.EqualFold(part.Token.TValue, "F800") { // [$-x-sysdate]
|
2023-05-11 09:08:38 +08:00
|
|
|
|
if nf.opts != nil && nf.opts.LongDatePattern != "" {
|
|
|
|
|
nf.value = format(nf.value, nf.opts.LongDatePattern, nf.date1904, nf.cellType, nf.opts)
|
2023-06-18 00:12:50 +08:00
|
|
|
|
return true, nil
|
2023-05-06 20:34:18 +08:00
|
|
|
|
}
|
|
|
|
|
part.Token.TValue = "409"
|
|
|
|
|
}
|
|
|
|
|
if strings.EqualFold(part.Token.TValue, "F400") { // [$-x-systime]
|
2023-05-11 09:08:38 +08:00
|
|
|
|
if nf.opts != nil && nf.opts.LongTimePattern != "" {
|
|
|
|
|
nf.value = format(nf.value, nf.opts.LongTimePattern, nf.date1904, nf.cellType, nf.opts)
|
2023-06-18 00:12:50 +08:00
|
|
|
|
return true, nil
|
2023-05-06 20:34:18 +08:00
|
|
|
|
}
|
|
|
|
|
part.Token.TValue = "409"
|
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if _, ok := supportedLanguageInfo[strings.ToUpper(part.Token.TValue)]; !ok {
|
2023-06-18 00:12:50 +08:00
|
|
|
|
return false, ErrUnsupportedNumberFormat
|
2023-05-04 10:52:26 +08:00
|
|
|
|
}
|
|
|
|
|
nf.localCode = strings.ToUpper(part.Token.TValue)
|
|
|
|
|
}
|
|
|
|
|
if part.Token.TType == nfp.TokenSubTypeCurrencyString {
|
|
|
|
|
nf.currencyString = part.Token.TValue
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-18 00:12:50 +08:00
|
|
|
|
return false, nil
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// localAmPm return AM/PM name by supported language ID.
|
|
|
|
|
func (nf *numberFormat) localAmPm(ap string) string {
|
|
|
|
|
if languageInfo, ok := supportedLanguageInfo[nf.localCode]; ok {
|
|
|
|
|
return languageInfo.apFmt
|
|
|
|
|
}
|
|
|
|
|
return ap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameEnglish returns the English name of the month.
|
|
|
|
|
func localMonthsNameEnglish(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
|
|
|
|
return t.Month().String()[:3]
|
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return t.Month().String()
|
|
|
|
|
}
|
|
|
|
|
return t.Month().String()[:1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameAfrikaans returns the Afrikaans name of the month.
|
|
|
|
|
func localMonthsNameAfrikaans(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesAfrikaansAbbr[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesAfrikaans[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesAfrikaansAbbr[int(t.Month())-1][:1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameAustria returns the Austria name of the month.
|
|
|
|
|
func localMonthsNameAustria(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesAustriaAbbr[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesAustria[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesAustriaAbbr[int(t.Month())-1][:1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameBangla returns the German name of the month.
|
|
|
|
|
func localMonthsNameBangla(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 || abbr == 4 {
|
|
|
|
|
return monthNamesBangla[int(t.Month())-1]
|
|
|
|
|
}
|
|
|
|
|
return string([]rune(monthNamesBangla[int(t.Month())-1])[:1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameFrench returns the French name of the month.
|
|
|
|
|
func localMonthsNameFrench(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
|
|
|
|
month := monthNamesFrench[int(t.Month())-1]
|
|
|
|
|
if len([]rune(month)) <= 4 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesFrench[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesFrenchAbbr[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesFrench[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesFrenchAbbr[int(t.Month())-1][:1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// localMonthsNameIrish returns the Irish name of the month.
|
|
|
|
|
func localMonthsNameIrish(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesIrishAbbr[(t.Month() - 1)]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
2022-03-24 00:19:30 +08:00
|
|
|
|
return monthNamesIrish[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesIrishAbbr[int(t.Month())-1][:1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// localMonthsNameItalian returns the Italian name of the month.
|
|
|
|
|
func localMonthsNameItalian(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesItalianAbbr[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesItalian[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesItalianAbbr[int(t.Month())-1][:1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameGerman returns the German name of the month.
|
|
|
|
|
func localMonthsNameGerman(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesGermanAbbr[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesGerman[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesGermanAbbr[int(t.Month())-1][:1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameChinese1 returns the Chinese name of the month.
|
|
|
|
|
func localMonthsNameChinese1(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesChineseAbbrPlus[t.Month()]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesChinesePlus[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
return monthNamesChinese[int(t.Month())-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameChinese2 returns the Chinese name of the month.
|
|
|
|
|
func localMonthsNameChinese2(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 || abbr == 4 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesChinesePlus[int(t.Month())-1]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
return monthNamesChinese[int(t.Month())-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameChinese3 returns the Chinese name of the month.
|
|
|
|
|
func localMonthsNameChinese3(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 || abbr == 4 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesChineseAbbrPlus[t.Month()]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
return strconv.Itoa(int(t.Month()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameKorean returns the Korean name of the month.
|
|
|
|
|
func localMonthsNameKorean(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 || abbr == 4 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesKoreanAbbrPlus[t.Month()]
|
2022-02-14 00:05:47 +08:00
|
|
|
|
}
|
|
|
|
|
return strconv.Itoa(int(t.Month()))
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-30 11:10:51 +08:00
|
|
|
|
// localMonthsNameTraditionalMongolian returns the Traditional Mongolian name of
|
|
|
|
|
// the month.
|
2022-02-25 22:24:08 +08:00
|
|
|
|
func localMonthsNameTraditionalMongolian(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 5 {
|
|
|
|
|
return "M"
|
|
|
|
|
}
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesTradMongolian[t.Month()-1]
|
2022-02-25 22:24:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// localMonthsNameRussian returns the Russian name of the month.
|
|
|
|
|
func localMonthsNameRussian(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
|
|
|
|
month := monthNamesRussian[int(t.Month())-1]
|
|
|
|
|
if len([]rune(month)) <= 4 {
|
|
|
|
|
return month
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesRussianAbbr[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
2022-03-24 00:19:30 +08:00
|
|
|
|
return monthNamesRussian[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
return string([]rune(monthNamesRussian[int(t.Month())-1])[:1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameSpanish returns the Spanish name of the month.
|
|
|
|
|
func localMonthsNameSpanish(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesSpanishAbbr[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesSpanish[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesSpanishAbbr[int(t.Month())-1][:1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameThai returns the Thai name of the month.
|
|
|
|
|
func localMonthsNameThai(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
|
|
|
|
r := []rune(monthNamesThai[int(t.Month())-1])
|
|
|
|
|
return string(r[:1]) + "." + string(r[len(r)-2:len(r)-1]) + "."
|
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
2022-03-24 00:19:30 +08:00
|
|
|
|
return monthNamesThai[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
return string([]rune(monthNamesThai[int(t.Month())-1])[:1])
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-25 22:24:08 +08:00
|
|
|
|
// localMonthsNameTibetan returns the Tibetan name of the month.
|
|
|
|
|
func localMonthsNameTibetan(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesTibetanAbbr[int(t.Month())-1]
|
2022-02-25 22:24:08 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 5 {
|
|
|
|
|
if t.Month() == 10 {
|
|
|
|
|
return "\u0f66"
|
|
|
|
|
}
|
|
|
|
|
return "\u0f5f"
|
|
|
|
|
}
|
2022-03-24 00:19:30 +08:00
|
|
|
|
return monthNamesTibetan[int(t.Month())-1]
|
2022-02-25 22:24:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// localMonthsNameTurkish returns the Turkish name of the month.
|
|
|
|
|
func localMonthsNameTurkish(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesTurkishAbbr[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesTurkish[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return string([]rune(monthNamesTurkishAbbr[int(t.Month())-1])[:1])
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameWelsh returns the Welsh name of the month.
|
|
|
|
|
func localMonthsNameWelsh(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesWelshAbbr[int(t.Month())-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesWelsh[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesWelshAbbr[int(t.Month())-1][:1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-23 22:42:07 +08:00
|
|
|
|
// localMonthsNameVietnamese returns the Vietnamese name of the month.
|
|
|
|
|
func localMonthsNameVietnamese(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesVietnameseAbbr3[t.Month()-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 5 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesVietnameseAbbr5[t.Month()-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesVietnamese[t.Month()-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameWolof returns the Wolof name of the month.
|
|
|
|
|
func localMonthsNameWolof(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-25 12:22:28 +08:00
|
|
|
|
return monthNamesWolofAbbr[int(t.Month())-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesWolof[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-25 12:22:28 +08:00
|
|
|
|
return monthNamesWolof[int(t.Month())-1][:1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameXhosa returns the Xhosa name of the month.
|
|
|
|
|
func localMonthsNameXhosa(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-01-25 12:22:28 +08:00
|
|
|
|
return monthNamesXhosaAbbr[int(t.Month())-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
2023-01-25 12:22:28 +08:00
|
|
|
|
return monthNamesXhosa[int(t.Month())-1]
|
2022-02-23 22:42:07 +08:00
|
|
|
|
}
|
|
|
|
|
return "u"
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-22 08:22:18 +08:00
|
|
|
|
// localMonthsNameYi returns the Yi name of the month.
|
|
|
|
|
func localMonthsNameYi(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 || abbr == 4 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesYiSuffix[t.Month()-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
return string([]rune(monthNamesYi[int(t.Month())-1])[:1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// localMonthsNameZulu returns the Zulu name of the month.
|
|
|
|
|
func localMonthsNameZulu(t time.Time, abbr int) string {
|
|
|
|
|
if abbr == 3 {
|
2023-05-30 00:14:44 +08:00
|
|
|
|
return monthNamesZuluAbbr[t.Month()-1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
if abbr == 4 {
|
|
|
|
|
return monthNamesZulu[int(t.Month())-1]
|
|
|
|
|
}
|
2023-01-26 10:35:13 +08:00
|
|
|
|
return monthNamesZuluAbbr[int(t.Month())-1][:1]
|
2022-02-22 08:22:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-14 00:05:47 +08:00
|
|
|
|
// localMonthName return months name by supported language ID.
|
|
|
|
|
func (nf *numberFormat) localMonthsName(abbr int) string {
|
|
|
|
|
if languageInfo, ok := supportedLanguageInfo[nf.localCode]; ok {
|
|
|
|
|
return languageInfo.localMonth(nf.t, abbr)
|
|
|
|
|
}
|
|
|
|
|
return localMonthsNameEnglish(nf.t, abbr)
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-13 00:06:30 +08:00
|
|
|
|
// dateTimesHandler will be handling date and times types tokens for a number
|
|
|
|
|
// format expression.
|
|
|
|
|
func (nf *numberFormat) dateTimesHandler(i int, token nfp.Token) {
|
|
|
|
|
if idx := inStrSlice(nfp.AmPm, strings.ToUpper(token.TValue), false); idx != -1 {
|
|
|
|
|
if nf.ap == "" {
|
|
|
|
|
nextHours := nf.hoursNext(i)
|
2022-02-14 00:05:47 +08:00
|
|
|
|
aps := strings.Split(nf.localAmPm(token.TValue), "/")
|
2022-02-13 00:06:30 +08:00
|
|
|
|
nf.ap = aps[0]
|
2022-09-03 20:16:35 +08:00
|
|
|
|
if nextHours >= 12 {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
nf.ap = aps[1]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nf.result += nf.ap
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "M") {
|
|
|
|
|
l := len(token.TValue)
|
|
|
|
|
if l == 1 && !nf.hours && !nf.secondsNext(i) {
|
|
|
|
|
nf.result += strconv.Itoa(int(nf.t.Month()))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if l == 2 && !nf.hours && !nf.secondsNext(i) {
|
|
|
|
|
nf.result += fmt.Sprintf("%02d", int(nf.t.Month()))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if l == 3 {
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nf.result += nf.localMonthsName(3)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if l == 4 || l > 5 {
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nf.result += nf.localMonthsName(4)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if l == 5 {
|
2022-02-14 00:05:47 +08:00
|
|
|
|
nf.result += nf.localMonthsName(5)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-30 00:14:44 +08:00
|
|
|
|
nf.yearsHandler(token)
|
|
|
|
|
nf.daysHandler(token)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
nf.hoursHandler(i, token)
|
|
|
|
|
nf.minutesHandler(token)
|
|
|
|
|
nf.secondsHandler(token)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// yearsHandler will be handling years in the date and times types tokens for a
|
|
|
|
|
// number format expression.
|
2023-05-30 00:14:44 +08:00
|
|
|
|
func (nf *numberFormat) yearsHandler(token nfp.Token) {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
years := strings.Contains(strings.ToUpper(token.TValue), "Y")
|
|
|
|
|
if years && len(token.TValue) <= 2 {
|
|
|
|
|
nf.result += strconv.Itoa(nf.t.Year())[2:]
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if years && len(token.TValue) > 2 {
|
|
|
|
|
nf.result += strconv.Itoa(nf.t.Year())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// daysHandler will be handling days in the date and times types tokens for a
|
|
|
|
|
// number format expression.
|
2023-05-30 00:14:44 +08:00
|
|
|
|
func (nf *numberFormat) daysHandler(token nfp.Token) {
|
2022-02-13 00:06:30 +08:00
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "D") {
|
|
|
|
|
switch len(token.TValue) {
|
|
|
|
|
case 1:
|
|
|
|
|
nf.result += strconv.Itoa(nf.t.Day())
|
|
|
|
|
return
|
|
|
|
|
case 2:
|
|
|
|
|
nf.result += fmt.Sprintf("%02d", nf.t.Day())
|
|
|
|
|
return
|
|
|
|
|
case 3:
|
|
|
|
|
nf.result += nf.t.Weekday().String()[:3]
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
nf.result += nf.t.Weekday().String()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// hoursHandler will be handling hours in the date and times types tokens for a
|
|
|
|
|
// number format expression.
|
|
|
|
|
func (nf *numberFormat) hoursHandler(i int, token nfp.Token) {
|
|
|
|
|
nf.hours = strings.Contains(strings.ToUpper(token.TValue), "H")
|
|
|
|
|
if nf.hours {
|
|
|
|
|
h := nf.t.Hour()
|
|
|
|
|
ap, ok := nf.apNext(i)
|
|
|
|
|
if ok {
|
|
|
|
|
nf.ap = ap[0]
|
2022-09-03 20:16:35 +08:00
|
|
|
|
if h >= 12 {
|
|
|
|
|
nf.ap = ap[1]
|
|
|
|
|
}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
if h > 12 {
|
|
|
|
|
h -= 12
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-11 09:08:38 +08:00
|
|
|
|
if nf.ap != "" {
|
|
|
|
|
if nf.hoursNext(i) == -1 && h > 12 {
|
|
|
|
|
h -= 12
|
|
|
|
|
}
|
|
|
|
|
if h == 0 {
|
|
|
|
|
h = 12
|
|
|
|
|
}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
switch len(token.TValue) {
|
|
|
|
|
case 1:
|
|
|
|
|
nf.result += strconv.Itoa(h)
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
nf.result += fmt.Sprintf("%02d", h)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// minutesHandler will be handling minutes in the date and times types tokens
|
|
|
|
|
// for a number format expression.
|
|
|
|
|
func (nf *numberFormat) minutesHandler(token nfp.Token) {
|
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "M") {
|
|
|
|
|
nf.hours = false
|
|
|
|
|
switch len(token.TValue) {
|
|
|
|
|
case 1:
|
|
|
|
|
nf.result += strconv.Itoa(nf.t.Minute())
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
nf.result += fmt.Sprintf("%02d", nf.t.Minute())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// secondsHandler will be handling seconds in the date and times types tokens
|
|
|
|
|
// for a number format expression.
|
|
|
|
|
func (nf *numberFormat) secondsHandler(token nfp.Token) {
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if nf.seconds = strings.Contains(strings.ToUpper(token.TValue), "S"); !nf.seconds {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !nf.useMillisecond {
|
|
|
|
|
nf.t = nf.t.Add(time.Duration(math.Round(float64(nf.t.Nanosecond())/1e9)) * time.Second)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
if len(token.TValue) == 1 {
|
|
|
|
|
nf.result += strconv.Itoa(nf.t.Second())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
nf.result += fmt.Sprintf("%02d", nf.t.Second())
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// elapsedDateTimesHandler will be handling elapsed date and times types tokens
|
|
|
|
|
// for a number format expression.
|
|
|
|
|
func (nf *numberFormat) elapsedDateTimesHandler(token nfp.Token) {
|
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "H") {
|
2023-07-27 00:03:15 +08:00
|
|
|
|
nf.result += fmt.Sprintf("%.f", math.Floor(nf.t.Sub(excel1900Epoc).Hours()))
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "M") {
|
2023-07-27 00:03:15 +08:00
|
|
|
|
nf.result += fmt.Sprintf("%.f", math.Floor(nf.t.Sub(excel1900Epoc).Minutes()))
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if strings.Contains(strings.ToUpper(token.TValue), "S") {
|
2023-07-27 00:03:15 +08:00
|
|
|
|
nf.result += fmt.Sprintf("%.f", math.Floor(nf.t.Sub(excel1900Epoc).Seconds()))
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// hoursNext detects if a token of type hours exists after a given tokens list.
|
|
|
|
|
func (nf *numberFormat) hoursNext(i int) int {
|
|
|
|
|
tokens := nf.section[nf.sectionIdx].Items
|
|
|
|
|
for idx := i + 1; idx < len(tokens); idx++ {
|
|
|
|
|
if tokens[idx].TType == nfp.TokenTypeDateTimes {
|
|
|
|
|
if strings.Contains(strings.ToUpper(tokens[idx].TValue), "H") {
|
|
|
|
|
t := timeFromExcelTime(nf.number, false)
|
|
|
|
|
return t.Hour()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// apNext detects if a token of type AM/PM exists after a given tokens list.
|
|
|
|
|
func (nf *numberFormat) apNext(i int) ([]string, bool) {
|
|
|
|
|
tokens := nf.section[nf.sectionIdx].Items
|
|
|
|
|
for idx := i + 1; idx < len(tokens); idx++ {
|
|
|
|
|
if tokens[idx].TType == nfp.TokenTypeDateTimes {
|
|
|
|
|
if strings.Contains(strings.ToUpper(tokens[idx].TValue), "H") {
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|
if i := inStrSlice(nfp.AmPm, tokens[idx].TValue, false); i != -1 {
|
2022-02-14 00:05:47 +08:00
|
|
|
|
return strings.Split(nf.localAmPm(tokens[idx].TValue), "/"), true
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// secondsNext detects if a token of type seconds exists after a given tokens
|
|
|
|
|
// list.
|
|
|
|
|
func (nf *numberFormat) secondsNext(i int) bool {
|
|
|
|
|
tokens := nf.section[nf.sectionIdx].Items
|
|
|
|
|
for idx := i + 1; idx < len(tokens); idx++ {
|
|
|
|
|
if tokens[idx].TType == nfp.TokenTypeDateTimes {
|
|
|
|
|
return strings.Contains(strings.ToUpper(tokens[idx].TValue), "S")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// negativeHandler will be handling negative selection for a number format
|
|
|
|
|
// expression.
|
2022-03-19 00:05:47 +08:00
|
|
|
|
func (nf *numberFormat) negativeHandler() (result string) {
|
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if inStrSlice(supportedTokenTypes, token.TType, true) == -1 || token.TType == nfp.TokenTypeGeneral {
|
2023-04-30 11:10:51 +08:00
|
|
|
|
return nf.value
|
2022-03-19 00:05:47 +08:00
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
if inStrSlice(supportedDateTimeTokenTypes, token.TType, true) != -1 {
|
|
|
|
|
return nf.value
|
2022-03-19 00:05:47 +08:00
|
|
|
|
}
|
2023-04-30 11:10:51 +08:00
|
|
|
|
}
|
2023-05-04 10:52:26 +08:00
|
|
|
|
return nf.numberHandler()
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// zeroHandler will be handling zero selection for a number format expression.
|
|
|
|
|
func (nf *numberFormat) zeroHandler() string {
|
2022-02-18 00:02:39 +08:00
|
|
|
|
return nf.value
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// textHandler will be handling text selection for a number format expression.
|
2022-02-25 22:24:08 +08:00
|
|
|
|
func (nf *numberFormat) textHandler() (result string) {
|
|
|
|
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
|
|
|
|
if token.TType == nfp.TokenTypeLiteral {
|
|
|
|
|
result += token.TValue
|
|
|
|
|
}
|
2023-04-26 00:04:47 +08:00
|
|
|
|
if token.TType == nfp.TokenTypeTextPlaceHolder || token.TType == nfp.TokenTypeZeroPlaceHolder {
|
2022-02-25 22:24:08 +08:00
|
|
|
|
result += nf.value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getValueSectionType returns its applicable number format expression section
|
|
|
|
|
// based on the given value.
|
|
|
|
|
func (nf *numberFormat) getValueSectionType(value string) (float64, string) {
|
2023-04-26 00:04:47 +08:00
|
|
|
|
if nf.cellType != CellTypeNumber && nf.cellType != CellTypeDate {
|
|
|
|
|
return 0, nfp.TokenSectionText
|
|
|
|
|
}
|
2022-09-28 00:04:17 +08:00
|
|
|
|
isNum, _, _ := isNumeric(value)
|
2022-05-02 12:30:18 +08:00
|
|
|
|
if !isNum {
|
|
|
|
|
return 0, nfp.TokenSectionText
|
2022-02-13 00:06:30 +08:00
|
|
|
|
}
|
2022-05-02 12:30:18 +08:00
|
|
|
|
number, _ := strconv.ParseFloat(value, 64)
|
2022-02-13 00:06:30 +08:00
|
|
|
|
if number > 0 {
|
|
|
|
|
return number, nfp.TokenSectionPositive
|
|
|
|
|
}
|
|
|
|
|
if number < 0 {
|
2023-04-30 11:10:51 +08:00
|
|
|
|
var hasNeg bool
|
|
|
|
|
for _, sec := range nf.section {
|
|
|
|
|
if sec.Type == nfp.TokenSectionNegative {
|
|
|
|
|
hasNeg = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !hasNeg {
|
|
|
|
|
nf.usePositive = true
|
|
|
|
|
return number, nfp.TokenSectionPositive
|
|
|
|
|
}
|
2022-02-13 00:06:30 +08:00
|
|
|
|
return number, nfp.TokenSectionNegative
|
|
|
|
|
}
|
|
|
|
|
return number, nfp.TokenSectionZero
|
|
|
|
|
}
|