Skip to content

Commit e922d73

Browse files
authored
refs #4347, add ZZZ and ZZZZ patterns for timezone offsets without colons (#17318)
1 parent 76a3b35 commit e922d73

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

changelog.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,19 @@
8383
- `writeStackTrace` is available in JS backend now.
8484

8585
- Added `decodeQuery` to `std/uri`.
86+
8687
- `strscans.scanf` now supports parsing single characters.
87-
- `strscans.scanTuple` added which uses `strscans.scanf` internally, returning a tuple which can be unpacked for easier usage of `scanf`.
88+
89+
- `strscans.scanTuple` added which uses `strscans.scanf` internally,
90+
returning a tuple which can be unpacked for easier usage of `scanf`.
8891

8992
- Added `setutils.toSet` that can take any iterable and convert it to a built-in `set`,
9093
if the iterable yields a built-in settable type.
94+
9195
- Added `setutils.fullSet` which returns a full built-in `set` for a valid type.
96+
9297
- Added `setutils.complement` which returns the complement of a built-in `set`.
98+
9399
- Added `setutils.[]=`.
94100

95101
- Added `math.isNaN`.
@@ -100,20 +106,24 @@
100106
- Added `jsbigints` module, arbitrary precision integers for JavaScript target.
101107

102108
- Added `math.copySign`.
109+
103110
- Added new operations for singly- and doubly linked lists: `lists.toSinglyLinkedList`
104111
and `lists.toDoublyLinkedList` convert from `openArray`s; `lists.copy` implements
105112
shallow copying; `lists.add` concatenates two lists - an O(1) variation that consumes
106113
its argument, `addMoved`, is also supplied.
107114

108115
- Added `euclDiv` and `euclMod` to `math`.
116+
109117
- Added `httpcore.is1xx` and missing HTTP codes.
118+
110119
- Added `jsconsole.jsAssert` for JavaScript target.
111120

112121
- Added `posix_utils.osReleaseFile` to get system identification from `os-release` file on Linux and the BSDs.
113122
https://www.freedesktop.org/software/systemd/man/os-release.html
114123

115124
- `math.round` now is rounded "away from zero" in JS backend which is consistent
116-
with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior.
125+
with other backends. See #9125. Use `-d:nimLegacyJsRound` for previous behavior.
126+
117127
- Added `socketstream` module that wraps sockets in the stream interface
118128

119129
- Changed the behavior of `uri.decodeQuery` when there are unencoded `=`
@@ -127,26 +137,29 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior.
127137

128138
- Added `math.signbit`.
129139

130-
131140
- Removed the optional `longestMatch` parameter of the `critbits._WithPrefix` iterators (it never worked reliably)
141+
132142
- In `lists`: renamed `append` to `add` and retained `append` as an alias;
133143
added `prepend` and `prependMoved` analogously to `add` and `addMoved`;
134144
added `remove` for `SinglyLinkedList`s.
135145

136146
- Deprecated `any`. See https://github.com/nim-lang/RFCs/issues/281
137147

138148
- Added `std/sysrand` module to get random numbers from a secure source
139-
provided by the operating system.
149+
provided by the operating system.
140150

141151
- Added optional `options` argument to `copyFile`, `copyFileToDir`, and
142152
`copyFileWithPermissions`. By default, on non-Windows OSes, symlinks are
143153
followed (copy files symlinks point to); on Windows, `options` argument is
144154
ignored and symlinks are skipped.
155+
145156
- On non-Windows OSes, `copyDir` and `copyDirWithPermissions` copy symlinks as
146157
symlinks (instead of skipping them as it was before); on Windows symlinks are
147158
skipped.
159+
148160
- On non-Windows OSes, `moveFile` and `moveDir` move symlinks as symlinks
149161
(instead of skipping them sometimes as it was before).
162+
150163
- Added optional `followSymlinks` argument to `setFilePermissions`.
151164

152165
- Added `os.isAdmin` to tell whether the caller's process is a member of the
@@ -196,10 +209,12 @@ provided by the operating system.
196209

197210
- `std/options` changed `$some(3)` to `"some(3)"` instead of `"Some(3)"`
198211
and `$none(int)` to `"none(int)"` instead of `"None[int]"`.
212+
199213
- Added `std/jsfetch` module [Fetch](https://developer.mozilla.org/docs/Web/API/Fetch_API) wrapper for JavaScript target.
214+
200215
- Added `std/jsheaders` module [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) wrapper for JavaScript target.
201-
- Added `std/jsformdata` module [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) wrapper for JavaScript target.
202216

217+
- Added `std/jsformdata` module [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) wrapper for JavaScript target.
203218

204219
- `system.addEscapedChar` now renders `\r` as `\r` instead of `\c`, to be compatible
205220
with most other languages.
@@ -208,7 +223,12 @@ provided by the operating system.
208223

209224
- Added `jscore.debugger` to [call any available debugging functionality, such as breakpoints.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger)
210225

211-
- Added `htmlgen.portal` for [making "SPA style" pages using HTML only.](https://web.dev/hands-on-portals)
226+
- Added `htmlgen.portal` for [making "SPA style" pages using HTML only](https://web.dev/hands-on-portals).
227+
228+
- Added `ZZZ` and `ZZZZ` patterns to `times.nim` `DateTime` parsing, to match time
229+
zone offsets without colons, e.g. `UTC+7 -> +0700`.
230+
231+
212232

213233

214234
## Language changes
@@ -229,6 +249,8 @@ provided by the operating system.
229249

230250
- `typedesc[Foo]` now renders as such instead of `type Foo` in compiler messages.
231251

252+
253+
232254
## Compiler changes
233255

234256
- Added `--declaredlocs` to show symbol declaration location in messages.
@@ -266,6 +288,8 @@ provided by the operating system.
266288

267289
- Added `unsafeIsolate` and `extract` to `std/isolation`.
268290

291+
292+
269293
## Tool changes
270294

271295
- The rst parser now supports markdown table syntax.

lib/pure/times.nim

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,12 @@
110110
| `UTC-5 -> -05`
111111
`zzz` Same as above but with `:mm` where *mm* represents minutes. | `UTC+7 -> +07:00`
112112
| `UTC-5 -> -05:00`
113+
`ZZZ` Same as above but with `mm` where *mm* represents minutes. | `UTC+7 -> +0700`
114+
| `UTC-5 -> -0500`
113115
`zzzz` Same as above but with `:ss` where *ss* represents seconds. | `UTC+7 -> +07:00:00`
114116
| `UTC-5 -> -05:00:00`
117+
`ZZZZ` Same as above but with `ss` where *ss* represents seconds. | `UTC+7 -> +070000`
118+
| `UTC-5 -> -050000`
115119
`g` Era: AD or BC | `300 AD -> AD`
116120
| `300 BC -> BC`
117121
`fff` Milliseconds display | `1000000 nanoseconds -> 1`
@@ -1469,6 +1473,7 @@ type
14691473
uuuu
14701474
UUUU
14711475
z, zz, zzz, zzzz
1476+
ZZZ, ZZZZ
14721477
g
14731478

14741479
# This is a special value used to mark literal format values.
@@ -1621,6 +1626,8 @@ proc stringToPattern(str: string): FormatPattern =
16211626
of "zz": result = zz
16221627
of "zzz": result = zzz
16231628
of "zzzz": result = zzzz
1629+
of "ZZZ": result = ZZZ
1630+
of "ZZZZ": result = ZZZZ
16241631
of "g": result = g
16251632
else: raise newException(TimeFormatParseError,
16261633
"'" & str & "' is not a valid pattern")
@@ -1727,7 +1734,7 @@ proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string,
17271734
result.add '+' & $year
17281735
of UUUU:
17291736
result.add $dt.year
1730-
of z, zz, zzz, zzzz:
1737+
of z, zz, zzz, zzzz, ZZZ, ZZZZ:
17311738
if dt.timezone != nil and dt.timezone.name == "Etc/UTC":
17321739
result.add 'Z'
17331740
else:
@@ -1738,16 +1745,18 @@ proc formatPattern(dt: DateTime, pattern: FormatPattern, result: var string,
17381745
result.add $(absOffset div 3600)
17391746
of zz:
17401747
result.add (absOffset div 3600).intToStr(2)
1741-
of zzz:
1748+
of zzz, ZZZ:
17421749
let h = (absOffset div 3600).intToStr(2)
17431750
let m = ((absOffset div 60) mod 60).intToStr(2)
1744-
result.add h & ":" & m
1745-
of zzzz:
1751+
let sep = if pattern == zzz: ":" else: ""
1752+
result.add h & sep & m
1753+
of zzzz, ZZZZ:
17461754
let absOffset = abs(dt.utcOffset)
17471755
let h = (absOffset div 3600).intToStr(2)
17481756
let m = ((absOffset div 60) mod 60).intToStr(2)
17491757
let s = (absOffset mod 60).intToStr(2)
1750-
result.add h & ":" & m & ":" & s
1758+
let sep = if pattern == zzzz: ":" else: ""
1759+
result.add h & sep & m & sep & s
17511760
else: assert false
17521761
of g:
17531762
result.add if dt.year < 1: "BC" else: "AD"
@@ -1881,7 +1890,7 @@ proc parsePattern(input: string, pattern: FormatPattern, i: var int,
18811890
parsed.year = some(year)
18821891
of UUUU:
18831892
parsed.year = some(takeInt(1..high(int), allowSign = true))
1884-
of z, zz, zzz, zzzz:
1893+
of z, zz, zzz, zzzz, ZZZ, ZZZZ:
18851894
case input[i]
18861895
of '+', '-':
18871896
let sign = if input[i] == '-': 1 else: -1
@@ -1892,21 +1901,24 @@ proc parsePattern(input: string, pattern: FormatPattern, i: var int,
18921901
offset = takeInt(1..2) * 3600
18931902
of zz:
18941903
offset = takeInt(2..2) * 3600
1895-
of zzz:
1904+
of zzz, ZZZ:
18961905
offset.inc takeInt(2..2) * 3600
1897-
if input[i] != ':':
1898-
return false
1899-
i.inc
1906+
if pattern == zzz:
1907+
if input[i] != ':':
1908+
return false
1909+
i.inc
19001910
offset.inc takeInt(2..2) * 60
1901-
of zzzz:
1911+
of zzzz, ZZZZ:
19021912
offset.inc takeInt(2..2) * 3600
1903-
if input[i] != ':':
1904-
return false
1905-
i.inc
1913+
if pattern == zzzz:
1914+
if input[i] != ':':
1915+
return false
1916+
i.inc
19061917
offset.inc takeInt(2..2) * 60
1907-
if input[i] != ':':
1908-
return false
1909-
i.inc
1918+
if pattern == zzzz:
1919+
if input[i] != ':':
1920+
return false
1921+
i.inc
19101922
offset.inc takeInt(2..2)
19111923
else: assert false
19121924
parsed.utcOffset = some(offset * sign)

tests/stdlib/ttimes.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ template runTimezoneTests() =
8484
"2001-01-12T08:04:05Z", 11)
8585
parseTest("2001-01-12T15:04:05 +07:30:59", "yyyy-MM-dd'T'HH:mm:ss zzzz",
8686
"2001-01-12T07:33:06Z", 11)
87+
parseTest("2001-01-12T15:04:05 +0700", "yyyy-MM-dd'T'HH:mm:ss ZZZ",
88+
"2001-01-12T08:04:05Z", 11)
89+
parseTest("2001-01-12T15:04:05 +073059", "yyyy-MM-dd'T'HH:mm:ss ZZZZ",
90+
"2001-01-12T07:33:06Z", 11)
8791
# Kitchen = "3:04PM"
8892
parseTestTimeOnly("3:04PM", "h:mmtt", "15:04:00")
8993

0 commit comments

Comments
 (0)