Repository navigation
Parsing
Four entry points, one for each combination of layout language and default location:
ptime.Parse(layout, value) // pattern letters, UTC default
ptime.ParseInLocation(layout, value, loc) // pattern letters, explicit default
ptime.ParseTimeFormat(layout, value) // reference time, UTC default
ptime.ParseTimeFormatInLocation(layout, value, loc) // reference time, explicit defaultThe layout languages are the ones described in Formatting, so
anything Format writes, Parse reads.
pt, err := ptime.Parse(ptime.DateTime, "1394-07-02 12:59:59")
pt, err = ptime.Parse(ptime.RFC3339, "1394-07-02T12:59:59+03:30")
pt, err = ptime.Parse("d MMM yyyy", "2 مهر 1394")
pt, err = ptime.Parse("d MMI yyyy", "2 میزان 1394")
pt, err = ptime.ParseTimeFormat("2006/01/02", "1394/07/02")Following time.Parse, a value without zone information is interpreted in
UTC:
pt, _ := ptime.Parse(ptime.DateOnly, "1404-05-20")
pt.Location() // UTCUse ParseInLocation when the text comes from a context with a known zone:
pt, _ := ptime.ParseInLocation(ptime.DateOnly, "1404-05-20", ptime.Iran())
pt.Location() // Asia/TehranA zone in the value always wins over the default:
| Value contains | Result |
|---|---|
Z |
UTC |
+03:30, +0330, +03
|
a fixed zone at that offset |
Asia/Tehran via the z or MST pattern |
that named location |
| nothing | the default location |
If the z pattern matches a name the host has no data for, parsing fails with
unknown time zone — unless the value also carried an offset, in which case a
fixed zone with that name and offset is used.
Fields absent from the layout default to Farvardin 1 of year 1, 00:00:00:
pt, _ := ptime.Parse(ptime.TimeOnly, "12:59:59")
pt.Date() // 1 Farvardin 1yy and 06 map onto the 1350-1449 window, which covers every year the
calendar is realistically used for:
| Input | Year |
|---|---|
00 – 49
|
1400 – 1449 |
50 – 99
|
1350 – 1399 |
ptime.Parse("yy/MM/dd", "04/05/20") // 1404-05-20
ptime.Parse("yy/MM/dd", "94/07/02") // 1394-07-02Two character patterns require exactly two digits; single character patterns
accept one or two. This matches time.Parse, where 01 needs two digits and
1 accepts one or two.
ptime.Parse("yyyy-MM-dd", "1404-5-20") // error: MM needs two digits
ptime.Parse("yyyy-M-d", "1404-5-20") // fine
ptime.Parse("yyyy-M-d", "1404-05-20") // also fineBecause of this leniency, Parse(layout, Format(layout)) is not always byte
identical to the input — but it always yields the same instant.
Careful with adjacent numeric fields. A layout like
yyyyMMddwith no separators is ambiguous for a greedy parser, the same way it is in the standard library. Keep a separator between numeric fields when the text will be parsed again.
Out of range values are errors, not silently clamped:
ptime.Parse(ptime.DateOnly, "1394-13-02") // error: month out of range
ptime.Parse(ptime.DateOnly, "1394-07-31") // error: Mehr has 30 days
ptime.Parse(ptime.DateOnly, "1394-12-30") // error: 1394 is not a leap year
ptime.Parse(ptime.DateOnly, "1403-12-30") // fine: 1403 is a leap year
ptime.Parse(ptime.DateOnly, "1394-07-02 extra") // error: extra textFailures return a *ParseError that names the layout element that did not match
and the input that remained:
_, err := ptime.Parse(ptime.DateOnly, "1394/07/02")
var perr *ptime.ParseError
if errors.As(err, &perr) {
perr.Layout // yyyy-MM-dd
perr.Value // 1394/07/02
perr.LayoutElem // -
perr.ValueElem // /07/02
perr.Message // "" for a plain mismatch
}
fmt.Println(err)
// ptime: cannot parse "/07/02" as "-" in "1394/07/02"The parsers are covered by three fuzz targets:
-
FuzzParse— a successful parse is stable underFormatandParseagain -
FuzzParseNeverPanics— arbitrary layouts and values never panic -
FuzzRoundTrip— every representable moment survives aFormat/Parseround trip
Run them locally with make fuzz, or make fuzz FUZZTIME=5m for a longer pass.
MIT licensed · Source · pkg.go.dev · Site