What is the reason behind time.Parse using a reference time?

1,358 views
Skip to first unread message

jade...@gmail.com

unread,
Apr 14, 2014, 9:19:29 AM4/14/14
to golan...@googlegroups.com
In java, we do things like new SimpleDateFormat("HH:mm:ss");. In php, something like date_parse_from_format("j.n.Y H:iP", $date) or just strtotime($date). In perl, we create a datetime parser with a pattern that might look like pattern => '%B %d, %Y %I:%M %p %Z'. And so on and so on.

However, in go we give it this ambiguous reference time, as in t, err := time.Parse("2006-01-02 15:04", "2011-01-19 22:15").

This seems odd to me. On first glance, I can't tell which is layout and which is string, but we can move around that. Then, when using it, I'm uncertain as to how to change formats without looking it up, I'm uncertain as to whether or not my reference time is supposed to be just random numbers or if I should specify things like 12-hour time vs 24-hour time, or if post-1970 is different than pre-1970, and overall I don't understand the reason why we choose arbitrary numbers instead of the aforementioned conventions of things like Y-M-d.

Thanks for any clarification on this. It's very clunky and tricky to use at the moment, but I'm sure I'd understand it more if I more fully understood the rational or what this approach solves that the other does not.

Andy Balholm

unread,
Apr 14, 2014, 11:47:35 AM4/14/14
to golan...@googlegroups.com, jade...@gmail.com
Using a reference time is actually simpler than using formatting codes—once you get your head around the idea of what the reference time is. The numbers aren't random; there is one reference time: the specific instant in time that the time package uses for all its formatting functions. You just format that instant the way you want your times formatted, and the time package will imitate that format.

Gustavo Niemeyer

unread,
Apr 14, 2014, 11:47:56 AM4/14/14
to jade...@gmail.com, golan...@googlegroups.com
On Mon, Apr 14, 2014 at 10:19 AM, <jade...@gmail.com> wrote:
> However, in go we give it this ambiguous reference time, as in t, err :=
> time.Parse("2006-01-02 15:04", "2011-01-19 22:15").
>
> This seems odd to me. On first glance, I can't tell which is layout and
> which is string, but we can move around that.

I can, but that's probably because I'm used to it. You can easily
avoid the ambiguity by defining the layout in a constant, though.

> Then, when using it, I'm
> uncertain as to how to change formats without looking it up, I'm uncertain
> as to whether or not my reference time is supposed to be just random numbers

The documentation [1] says it's not about random numbers:

"The layout defines the format by showing how the reference time, Mon
Jan 2 15:04:05 -0700 MST 2006 would be interpreted if it were the
value;"

So it's how *that* specific reference time would look like.

[1] http://golang.org/pkg/time/#Parse

> or if I should specify things like 12-hour time vs 24-hour time, or if

If the layout says "15" for 3pm, it will expect a 0-23 time range. If
it says "3", it will expect 0-12. If it says "3pm", it expects 0-12 +
am/pm. It honestly sounds much easier to relate to than looking up %
codes.

> post-1970 is different than pre-1970,

Why would it be? The epoch is unrelated to date/time strings.

> and overall I don't understand the
> reason why we choose arbitrary numbers instead of the aforementioned
> conventions of things like Y-M-d.

My reaction when I first saw it was the exact opposite: it feels
brilliant to be able to have a layout that can represent how the end
result looks like, rather than remembering codes.


gustavo @ http://niemeyer.net

jade...@gmail.com

unread,
Apr 14, 2014, 12:41:48 PM4/14/14
to golan...@googlegroups.com, jade...@gmail.com
Your reply makes me think that perhaps I should just spend a bit more time wrapping my mind around the docs instead of pulling something and expecting it to behave like other languages' implementation. =)

Thanks,
Jean

Jackman

unread,
Apr 14, 2014, 4:42:55 PM4/14/14
to jade...@gmail.com, golan...@googlegroups.com
I'm not sure if it's good or bad, so I'd like to hear what the experts have to say about the following practice:

I use int64 UTC Epoch/Unix timestamps for just about everything until it gets to the user, at which time I format it the way the client wants it. Any corner cases or irregularities in the various time implementations make me want to scream and kick things. Even if it takes a little more CPU time, I'm not wasting my time or other people's time because UTC Unix timestamps are as close to universal as there is.

As far as the actual format string, I like it, too. I haven't actually memorized the reference date, however. I usually just paste it in as a comment above my own format string.



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Andrew Jackman
kd7...@gmail.com

Caleb Spare

unread,
Apr 14, 2014, 4:54:55 PM4/14/14
to Jackman, jade...@gmail.com, golang-nuts
​The reference time should be easy to remember​
: it's simply 1234567

0
​​
1
/0
​​
2
​​
3
:
​​
45
pm
2
​006​ -0700

The only part you really need to memorize is that it's 3pm, not 0300. (And maybe that it's American month/day rather than day/month.)

-Caleb

Ingo Oeser

unread,
Apr 14, 2014, 5:09:43 PM4/14/14
to golan...@googlegroups.com, jade...@gmail.com
It is actually just "1 2 3 4 5 6 7" in some random US centric format like
"Jan 2 3:04 pm 06 -0700"

meaning

Jan -> 1st month
2 -> 2nd day
3 -> 3 o'clock pm
4 -> 4th minute
5 -> 5th second
6 -> 6th year in this century
7 -> 7 hours behind GMT.

So I hope this can help people remember it. It certainly helped me :-)

roger peppe

unread,
Apr 14, 2014, 6:12:14 PM4/14/14
to Ingo Oeser, golang-nuts, jade...@gmail.com
FWIW, though I love the idea, I really wish that the
reference time had been defined from
most significant to least significant time unit.

Rob Pike

unread,
Apr 14, 2014, 7:17:44 PM4/14/14
to roger peppe, Ingo Oeser, golang-nuts, jade...@gmail.com
The choice was made by the output of the date command on my Unix
machine. I should have realized the format varies with locale. Mea
culpa. But I can still claim it's easy to remember and well
documented.

-rob

Jonathan

unread,
Apr 14, 2014, 7:59:55 PM4/14/14
to golan...@googlegroups.com
Am I the only one seeing this?
Why does Google Groups offer to translate Rob's message to English?
Why does it think it's Latin?
Why does it translate it to this?

Third choice was made by the output of the date command on my Unix 
machine. 1 should have realized the forms vary with locality. My 
fault. But it's easy to remember and prep 1 can still Claire 
documented. 

-B 

Dan Kortschak

unread,
Apr 14, 2014, 8:55:54 PM4/14/14
to Rob Pike, roger peppe, Ingo Oeser, golang-nuts, jade...@gmail.com
What is your locale? My date returned the year and timezone in reversed
order from the time parse string - year last. The locale here is
en_AU.UTF-8, but changing it to C.UTF-8 or en_US.UTF-8 makes no
difference.

David Symonds

unread,
Apr 14, 2014, 9:07:49 PM4/14/14
to Jonathan, golang-nuts
alea iacta est

Dan Kortschak

unread,
Apr 14, 2014, 9:19:08 PM4/14/14
to David Symonds, Jonathan, golang-nuts
Sono Pazzi Questi Romani

Andy Balholm

unread,
Apr 15, 2014, 11:10:37 AM4/15/14
to golan...@googlegroups.com
On Monday, April 14, 2014 4:59:55 PM UTC-7, Jonathan wrote:
Am I the only one seeing this?
No. 

Why does Google Groups offer to translate Rob's message to English?
Why does it think it's Latin?
I don't know. The Google Translate page detects it as English. Of course mea culpa is Latin, but there's much more English. Did his email to the mailing list have a language header that was set to Latin because he switched his spellchecker to Latin to make sure he got "mea culpa" right?
 
Why does it translate it to this?
Probably because Google Translate's Latin corpus doesn't have adequate examples of English words in Latin works, so it makes crazy guesses. If I tell Google translate that it's French or Spanish, it comes through with fewer changes.

fred...@gmail.com

unread,
Apr 17, 2014, 8:57:12 AM4/17/14
to golan...@googlegroups.com
"Mea Culpa" was originally a Latin language phrase.  I saw it too.

RickyS

unread,
Apr 17, 2014, 9:00:14 AM4/17/14
to golan...@googlegroups.com, jade...@gmail.com
When I saw the reference time I knew automatically that one of the Go Authors had a child on that date.  And I haven't paid attention to it since.  It seems that what I knew was wrong.

gta

unread,
Apr 17, 2014, 9:09:38 AM4/17/14
to golan...@googlegroups.com, David Symonds, Jonathan
SPQR? ;)

On Tuesday, 15 April 2014 03:19:08 UTC+2, kortschak wrote:
Sono Pazzi Questi Romani

Thomas Bushnell, BSG

unread,
Apr 17, 2014, 11:17:57 AM4/17/14
to fred...@gmail.com, golang-nuts
It's still a Latin phrase, in fact. :)


On Thu, Apr 17, 2014 at 5:57 AM, <fred...@gmail.com> wrote:
"Mea Culpa" was originally a Latin language phrase.  I saw it too.

Andy Balholm

unread,
Apr 17, 2014, 11:42:55 AM4/17/14
to golan...@googlegroups.com, David Symonds, Jonathan
Normally SPQR stands for Senatus PopulusQue Romanus, but if the people that translated the Asterix books into Italian are anything like the ones that translated them into English, the resemblance is probably deliberate. 

Jonathan

unread,
Apr 17, 2014, 11:47:58 AM4/17/14
to golan...@googlegroups.com, fred...@gmail.com

That was the peculiarity that set me off:  I didn't see (and still don't when I go back) the "Mea Culpa".  I had no clue why the translation was being offered. (Altho' in the translation "My fault." did appear.

Jonathan

Dan Kortschak

unread,
Apr 17, 2014, 5:44:19 PM4/17/14
to Andy Balholm, golan...@googlegroups.com, David Symonds, Jonathan
Yup. To understand all the jokes in Asterix, you need to have at least some understanding of the major European languages. Obelix in English says "These Romans are crazy," which in Italian is "Sono Pazzi Questi Romani" typefaced with the SPQR in latin face to match its appearance on the Roman standard. Dogmatix's name in the French version is Idéfix, which is not funny unless you know the English. There are many others, but unfortunately the margin is too small (and I no longer have all my copies).

Uderzo and Goscinny are French, but ethnically Italian and Polish respectively, so I would bet that they had a signficant part in the language used in the non-French editions.

/OT

sp55a...@gmail.com

unread,
Aug 15, 2019, 12:28:35 AM8/15/19
to golang-nuts
I think "2006-01-02 15:04" is a good idea, but have bad practice.
you cannot understand this code directly. then it is easy to write wrong code like: time.Parse("1970-01-01 00:00", "2011-01-19 22:15")

Wojciech S. Czarnecki

unread,
Aug 15, 2019, 8:48:17 AM8/15/19
to golan...@googlegroups.com
On Wed, 14 Aug 2019 19:12:40 -0700 (PDT)
sp55a...@gmail.com wrote:
> What is the reason behind time.Parse using a reference time?

The rationale is that every position of the reference time can be
treated as an enum (of int) stating the exact meaning of the field:

01/02 03:04:05PM '06 -0700
1 2 3 4 5 6 7 : M D h m s year zone/offset

You then use these enums to tell the parser where in *your* date/time
format to parse these fields are. These are accompanied by words of
"Mon"/"Monday" "Jan"/"January" to show parser that format use names.

Eg. you may need the "06/01" ("year's last two digit / month") format to
extract dates off some monthly financial reports.
In other place you will use "__2/06" ("day-of-year/year") to parse
daily sales reports.

Read https://golang.org/pkg/time/#pkg-constants till it clicks in :)

This is as simple and brilliant as many other things in Go.
Just the docs are somewhat terse.

> I think "2006-01-02 15:04" is a good idea, but have bad practice.
> you cannot understand this code directly. then it is easy to write wrong
> code like: time.Parse("1970-01-01 00:00", "2011-01-19 22:15")

With format placeholders other languages use code is less readable
until you memorize all of mnemonics. [ man date, look what %_I does mean].
In Go you need only to remember that month is a first member of
"month, day, hour, minutes, seconds, year, zone" sequence and you
can read/understand any of hundreds being in use date formats.

Hope this helps,

--
Wojciech S. Czarnecki
<< ^oo^ >> OHIR-RIPE

Michael Baldry

unread,
Aug 15, 2019, 8:24:40 PM8/15/19
to golang-nuts
I agree with that. It is an odd choice, as I've never seen any other library use a reference date like that - there may be many but in 20 years, I've not seen one. 

I think your argument about Parse is valid, but in most cases, you'll be passing in a variable for the date you are parsing and the format will be in a constant, so you'd be more likely to have something like time.Parse(myTimeFormat, request.birthday) or something. 

It's useful to remember the reference time has a pattern, but the MST, 12 hour clock and it not being in a common order (day month, then year later) makes it less obvious, it is essentially: 01/02 03:04:05PM '06 -0700, that fact is obscured when parsing in common formats.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.


--
Michael




Company number: 08133555 
Registered in England
Registered office: 22 Finwell Road, Rainham, Kent, ME8 7PY

Wojciech S. Czarnecki

unread,
Aug 16, 2019, 4:40:22 AM8/16/19
to golan...@googlegroups.com
On Thu, 15 Aug 2019 07:52:24 +0100
Michael Baldry <mic...@brightbits.co.uk> wrote:

> It's useful to remember the reference time has a pattern,
> but the MST, 12 hour clock and it not being in a common order

There is no such thing as "common order" of date/time notation.
This notation is a part of the local culture. The Go format pattern happens
to be the "most natural" — though just for its birthplace (United States).

> (day month, then year later)
Thats natural for a big part of Europe and a chunk of Africa.

> it is essentially: 01/02 03:04:05PM '06 -0700, that
> fact is obscured when parsing in common formats.

Hope this helps :)

roger peppe

unread,
Aug 16, 2019, 5:03:45 AM8/16/19
to Michael Baldry, golang-nuts
On Fri, 16 Aug 2019 at 01:24, Michael Baldry <mic...@brightbits.co.uk> wrote:
I agree with that. It is an odd choice, as I've never seen any other library use a reference date like that - there may be many but in 20 years, I've not seen one. 

I think your argument about Parse is valid, but in most cases, you'll be passing in a variable for the date you are parsing and the format will be in a constant, so you'd be more likely to have something like time.Parse(myTimeFormat, request.birthday) or something. 

It's useful to remember the reference time has a pattern, but the MST, 12 hour clock and it not being in a common order (day month, then year later) makes it less obvious, it is essentially: 01/02 03:04:05PM '06 -0700, that fact is obscured when parsing in common formats.

To me, that's the only significant flaw in this way of doing things. I can never remember the order. I believe it should have been defined in most-significant to least-significant order (same order as RFC3339), but unfortunately it's too late for that now.


On Thu, Aug 15, 2019 at 5:28 AM <sp55a...@gmail.com> wrote:
I think "2006-01-02 15:04" is a good idea, but have bad practice.
you cannot understand this code directly. then it is easy to write wrong code like: time.Parse("1970-01-01 00:00", "2011-01-19 22:15")

On Monday, April 14, 2014 at 9:19:29 PM UTC+8, Jean de Klerk wrote:
In java, we do things like new SimpleDateFormat("HH:mm:ss");. In php, something like date_parse_from_format("j.n.Y H:iP", $date) or just strtotime($date). In perl, we create a datetime parser with a pattern that might look like pattern => '%B %d, %Y %I:%M %p %Z'. And so on and so on.

However, in go we give it this ambiguous reference time, as in t, err := time.Parse("2006-01-02 15:04", "2011-01-19 22:15").

This seems odd to me. On first glance, I can't tell which is layout and which is string, but we can move around that. Then, when using it, I'm uncertain as to how to change formats without looking it up, I'm uncertain as to whether or not my reference time is supposed to be just random numbers or if I should specify things like 12-hour time vs 24-hour time, or if post-1970 is different than pre-1970, and overall I don't understand the reason why we choose arbitrary numbers instead of the aforementioned conventions of things like Y-M-d.

Thanks for any clarification on this. It's very clunky and tricky to use at the moment, but I'm sure I'd understand it more if I more fully understood the rational or what this approach solves that the other does not.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5d3a4adf-2b4c-4a4f-896e-85206da552a5%40googlegroups.com.


--
Michael




Company number: 08133555 
Registered in England
Registered office: 22 Finwell Road, Rainham, Kent, ME8 7PY

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

Victor Giordano

unread,
Aug 17, 2019, 10:21:56 AM8/17/19
to golang-nuts
I feel the same way, Jean.
I quite don't get it a the first, and still some times i require to look very well to distinguish the layout pattern for the string value beign parsed.
Reply all
Reply to author
Forward
0 new messages