aboutsummaryrefslogtreecommitdiff
path: root/src/time/format.go
diff options
context:
space:
mode:
authorEmmanuel T Odeke <emmanuel@orijtech.com>2021-03-11 17:34:09 -0800
committerEmmanuel Odeke <emmanuel@orijtech.com>2021-03-16 00:27:31 +0000
commitf02a26bed0f21de7aeef7a60cf62dac2e3dab737 (patch)
tree8e944aa73d315e365b393cf86179bd7a2050350a /src/time/format.go
parenta9b3c4bd0602f95afc58328d9953534f5e5fe4f6 (diff)
downloadgo-f02a26bed0f21de7aeef7a60cf62dac2e3dab737.tar.gz
go-f02a26bed0f21de7aeef7a60cf62dac2e3dab737.zip
time: support "," as separator for fractional seconds
Accepts comma "," as a separator for fractional seconds hence we now accept: * 2006-01-02 15:04:05,999999999 -0700 MST * Mon Jan _2 15:04:05,120007 2006 * Mon Jan 2 15:04:05,120007 2006 This change follows the recommendations of ISO 8601 per https://en.wikipedia.org/wiki/ISO_8601#cite_note-26 which states ISO 8601:2004(E), ISO, 2004-12-01, "4.2.2.4 ... the decimal fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0, i.e. the comma [,] or full stop [.]. Of these, the comma is the preferred sign." Unfortunately, I couldn't directly access the ISO 8601 document because suddenly it is behind a paywall on the ISO website, charging CHF 158 (USD 179) for 38 pages :-( However, this follows publicly available cited literature, as well as the recommendations from the proposal approval. Fixes #6189 Updates #27746 Updates #26002 Updates #36145 Updates #43813 Fixes #43823 Change-Id: Ibe96064e8ee27c239be78c880fa561a1a41e190c Reviewed-on: https://go-review.googlesource.com/c/go/+/300996 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> Reviewed-by: Rob Pike <r@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/time/format.go')
-rw-r--r--src/time/format.go30
1 files changed, 18 insertions, 12 deletions
diff --git a/src/time/format.go b/src/time/format.go
index c4f3358f59..7586035872 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -26,13 +26,14 @@ import "errors"
// compatibility with fixed-width Unix time formats.
//
// A decimal point followed by one or more zeros represents a fractional
-// second, printed to the given number of decimal places. A decimal point
-// followed by one or more nines represents a fractional second, printed to
-// the given number of decimal places, with trailing zeros removed.
+// second, printed to the given number of decimal places.
+// Either a comma or decimal point followed by one or more nines represents
+// a fractional second, printed to the given number of decimal places, with
+// trailing zeros removed.
// When parsing (only), the input may contain a fractional second
// field immediately after the seconds field, even if the layout does not
-// signify its presence. In that case a decimal point followed by a maximal
-// series of digits is parsed as a fractional second.
+// signify its presence. In that case either a comma or a decimal point
+// followed by a maximal series of digits is parsed as a fractional second.
//
// Numeric time zone offsets format as follows:
// -0700 ±hhmm
@@ -261,7 +262,7 @@ func nextStdChunk(layout string) (prefix string, std int, suffix string) {
return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
}
- case '.': // .000 or .999 - repeated digits for fractional seconds.
+ case '.', ',': // ,000, or .000, or ,999, or .999 - repeated digits for fractional seconds.
if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
ch := layout[i+1]
j := i + 1
@@ -484,9 +485,10 @@ func (t Time) String() string {
// desired output. The same display rules will then be applied to the time
// value.
//
-// A fractional second is represented by adding a period and zeros
-// to the end of the seconds section of layout string, as in "15:04:05.000"
-// to format a time stamp with millisecond precision.
+// A fractional second is represented by adding either a comma or a
+// period and zeros to the end of the seconds section of layout string,
+// as in "15:04:05,000" or "15:04:05.000" to format a time stamp with
+// millisecond precision.
//
// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
// and convenient representations of the reference time. For more information
@@ -940,7 +942,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
}
// Special case: do we have a fractional second but no
// fractional second in the format?
- if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
+ if len(value) >= 2 && commaOrPeriod(value[0]) && isDigit(value, 1) {
_, std, _ = nextStdChunk(layout)
std &= stdMask
if std == stdFracSecond0 || std == stdFracSecond9 {
@@ -1070,7 +1072,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
value = value[ndigit:]
case stdFracSecond9:
- if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
+ if len(value) < 2 || !commaOrPeriod(value[0]) || value[1] < '0' || '9' < value[1] {
// Fractional second omitted.
break
}
@@ -1279,8 +1281,12 @@ func parseSignedOffset(value string) int {
return len(value) - len(rem)
}
+func commaOrPeriod(b byte) bool {
+ return b == '.' || b == ','
+}
+
func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
- if value[0] != '.' {
+ if !commaOrPeriod(value[0]) {
err = errBad
return
}