time.Format() giving unpredictable results

770 views
Skip to first unread message

Dean Schulze

unread,
Apr 19, 2013, 3:04:07 PM4/19/13
to golan...@googlegroups.com
The following code gives the output shown below.  Only the first one is correct.  The godocs give the following advice:

"see the documentation for ANSIC"

There's no documentation for ANSIC except for a comment in a struct on the same page.

 Is this a bug with time.Format()?

==============================================

s := time.Now().Format("2006-01-02")
fmt.Println(s)
s1 := time.Now().Format("2006-01-18")
fmt.Println(s1)
s2 := time.Now().Format("2006-04-18")
fmt.Println(s2)
s3 := time.Now().Format("2013-01-02")
fmt.Println(s3)

2013-04-19
2013-04-48
2013-59-48
190412-04-19

Georg Reinke

unread,
Apr 19, 2013, 3:24:47 PM4/19/13
to golan...@googlegroups.com
Read the documentation again. The format passed to Parse _must_ be a
representation of the standard time, "Mon Jan 2 15:04:05 -0700 MST 2006". See
http://http://golang.org/pkg/time/#Parse.

I feel like this issue comes up every week or so lately.

Matt Kane's Brain

unread,
Apr 19, 2013, 3:39:28 PM4/19/13
to Dean Schulze, golang-nuts
Time formatting is weird. This isn't a bug. What you need to is write how the standard time would be formatted.

s := time.Now().Format("2006-01-02")

Here 2006 is replaced with the 4 digit year, 01 is replaced with the two digit month, and 02 is replaced with the two digit day. The numbers are significant.

s1 := time.Now().Format("2006-01-18")

In this case, the result is the same, but because 18 doesn't mean anything, the layout parser grabs the 1 (for unpadded month) and the 8 separately. The 8 doesn't have any special meaning, so it is printed verbatim.

s2 := time.Now().Format("2006-04-18")

Now, instead of finding "01", the parser finds 04 for the two-digute minute.

s3 := time.Now().Format("2013-01-02")

Now this one is weird.

"2013" has no special meaning. The layout parser is printing out:
2 - unpadded day -> 19
01 - padded month -> 04
3 - unpadded hour of the day in 12-hour format -> 12

02 is padded month again -> 04

and 02 is zero-padded day. -> 19

So, you get the strange result "190412-04-19"

I feel like the source for parsing that is more useful than the docs, but I have no suggestions for rewriting: http://golang.org/src/pkg/time/format.go?#L90


--
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/groups/opt_out.
 
 



--
matt kane's brain
twitter: the_real_mkb / nynexrepublic
http://hydrogenproject.com

Dave Rose

unread,
Apr 19, 2013, 9:46:40 PM4/19/13
to golan...@googlegroups.com
I had the same issue two days ago. I agree, the doc is not clear. Mk explained it well but in plain English I would say you must use the exact date provided in the src for Time.format . this is because the code knows that 2006-01-02 is Jan 2nd and not Feb 1st. I hope that helps a little.

Dean Schulze

unread,
Apr 21, 2013, 9:50:48 PM4/21/13
to golan...@googlegroups.com
So the only date the Parse() function knows is "Mon Jan 2 15:04:05 -0700 MST 2006"?  That's just lame.  They need to be very explicit and say that no other date or time will work.

This is one area where golang falls short of its predecessors.  For all the problems that Java has with dates it at least has an intuitive way to parse dates.

Jesse McNelis

unread,
Apr 21, 2013, 10:41:04 PM4/21/13
to Dean Schulze, golang-nuts
On Mon, Apr 22, 2013 at 11:50 AM, Dean Schulze <dean.w....@gmail.com> wrote:
So the only date the Parse() function knows is "Mon Jan 2 15:04:05 -0700 MST 2006"?  That's just lame.  They need to be very explicit and say that no other date or time will work.

It's pretty clearly documented.

"To define your own format, write down what the standard time would look like formatted your way; see the values of constants like ANSIC, StampMicro or Kitchen for examples."

Having the time pkg parse arbitrary dates to figure out the format is generally uncomputable.

--
=====================
http://jessta.id.au

Hotei

unread,
Apr 22, 2013, 1:00:45 AM4/22/13
to golan...@googlegroups.com
Dean,
I must admit when I first discovered the "template trick" go uses for date formatting my reaction was similar to yours.  I had to look at the source code and especially the constants section for hints on how it worked. However, once I recovered from my chagrin I had to agree that the go method is simple.  And it is effective.  Intuitive - not so much.  Luckily it's a mistake you'll never make again.  And if you can think of a better way to word it the documentation guys might take your advice.  Or might not.  Or it might just take a while.  I complained vigorously several years ago about godoc being broken (which was true at the time for user code) and there not being any decent examples for how to use pkg X and a year or two later godoc was improved greatly - and now it has a way to formally show examples.  My complaints probably had nothing to do with the improvements - but I guess my point is that it doesn't hurt to politely mention a problem here.  And a problem with a proposed solution is even better.  

Personally I agree with you that date formatting needs an example, even a one-liner would help a newbie.  But it's also not that hard to figure out on your own if you're not a newbie. Unfortunately since go 1.1 is getting close I doubt if this minor issue will get any attention but you never know.  I'm convinced that eventually the language will start to attract enough newbies that the old hands who maintain golang.org will get tired of answering the same question every week/day/... and start putting in more examples so they can get back to their real jobs.  

Hotei

unread,
Apr 22, 2013, 1:12:44 AM4/22/13
to golan...@googlegroups.com, Dean Schulze, jes...@jessta.id.au
Jesse,
Yes it is documented - and very well at that - but it's in the "wrong" place.  Newbies reading godoc for pkg time from top down will focus on time.Format() first, skipping the constants section because - since they're newbies they don't know they're supposed to look there first. The time.Format() section should either point out the examples in constants or it should have its own one-liner example. Or both.  Or we can keep answering the same questions.

roger peppe

unread,
Apr 22, 2013, 7:24:07 AM4/22/13
to luz...@gmail.com, golang-nuts
I like the time format idea, but I wish I could think of a better
way to remember the standard date. It would be perhaps
more memorable if the numbers increased from most-significant
to least-significant part - if you write it down in that
order now, it's clear that the year number is fairly arbitrary
(I've left the time zone offset at the end because it's a clear
exception):

year 2006; month 01; day 02; hour 03; min 04; sec 05; hour offset 07

this might be nicer:

2001/02/03 4:05:06pm +0700

... but it's way too late now, and having written down the above
I realise that all I need to do is remember that it was a Monday in 2006 and
the rest follows.


On 22 April 2013 07:57, <luz...@gmail.com> wrote:
> On Monday, April 22, 2013 3:50:48 AM UTC+2, Dean Schulze wrote:
>>
>> So the only date the Parse() function knows is "Mon Jan 2 15:04:05 -0700
>> MST 2006"? That's just lame.
>
>
> Think about it: if more than one template date was allowed it could be
> ambiguous. In "10-11-10" which number would be year, month, day or is it
> hours, minutes, seconds? Go's template date is very simple, it's basically
> 1-2-3-4-5-6-7.

Jan Mercl

unread,
Apr 22, 2013, 7:31:01 AM4/22/13
to roger peppe, luz...@gmail.com, golang-nuts
On Mon, Apr 22, 2013 at 1:24 PM, roger peppe <rogp...@gmail.com> wrote:
> I like the time format idea, but I wish I could think of a better
> way to remember the standard date.

I "see" it like this: 'Mon Jan 2 03:04:05PM 2006 -0700' which for me
"is" '0 1 2 3 4 5 6 7'. Easy to remember, I think. (Mon == zeroth day,
3(PM) == 15, the only irregularity).

-j

Volker Dobler

unread,
Apr 22, 2013, 7:39:57 AM4/22/13
to golan...@googlegroups.com, roger peppe, luz...@gmail.com
"Jan 2 2006" looks natural only for Americans. A 'Mon 1 Feb 2003
16:05:06' might look more natural for Europeans.

But  this discussion is not fruitful as too late to change.

V.

Dan Kortschak

unread,
Apr 22, 2013, 7:57:23 AM4/22/13
to Volker Dobler, golan...@googlegroups.com, roger peppe, luz...@gmail.com
In the C locale (now and here):

$ date
Mon Apr 22 21:24:26 CST 2013

This means, the docs are 5 keystrokes away (if you live in C, and ignore
the timezone).

Dean Schulze

unread,
Apr 22, 2013, 9:27:50 AM4/22/13
to golan...@googlegroups.com, Dean Schulze, jes...@jessta.id.au

That doesn't say that you can only use that particular date and time.  That needs to be explicit.

The fact that this question gets asked repeatedly shows that the documentation needs to be explicit about this.

Jan Mercl

unread,
Apr 22, 2013, 9:40:17 AM4/22/13
to Dean Schulze, golang-nuts, Jesse McNelis
On Mon, Apr 22, 2013 at 3:27 PM, Dean Schulze <dean.w....@gmail.com> wrote:
>
> That doesn't say that you can only use that particular date and time. That
> needs to be explicit.
>
> The fact that this question gets asked repeatedly shows that the
> documentation needs to be explicit about this.

I think it is explicit as explicit it can get. If I'm mistaken then
please reformulate the bellow to be "explicit":

[Q]

const (
ANSIC = "Mon Jan _2 15:04:05 2006"
UnixDate = "Mon Jan _2 15:04:05 MST 2006"
RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen = "3:04PM"
// Handy time stamps.
Stamp = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano = "Jan _2 15:04:05.000000000"
)

These are predefined layouts for use in Time.Format. The standard time
used in the layouts is:

Mon Jan 2 15:04:05 MST 2006

which is Unix time 1136243045. Since MST is GMT-0700, the standard
time can be thought of as

01/02 03:04:05PM '06 -0700

To define your own format, write down what the standard time would
look like formatted your way; see the values of constants like ANSIC,
StampMicro or Kitchen for examples.

[/Q]

-j

Matt Kane's Brain

unread,
Apr 22, 2013, 9:45:25 AM4/22/13
to Jan Mercl, Dean Schulze, golang-nuts, Jesse McNelis
Maybe this part should be first?

"To define your own format, write down what the standard time would
look like formatted your way; see the values of constants like ANSIC,
StampMicro or Kitchen for examples."
--
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/groups/opt_out.


Jan Mercl

unread,
Apr 22, 2013, 9:51:53 AM4/22/13
to Matt Kane's Brain, Dean Schulze, golang-nuts, Jesse McNelis
On Mon, Apr 22, 2013 at 3:45 PM, Matt Kane's Brain
<mkb-...@hydrogenproject.com> wrote:
> Maybe this part should be first?
>
> "To define your own format, write down what the standard time would
> look like formatted your way; see the values of constants like ANSIC,
> StampMicro or Kitchen for examples."

Sadly, you're right - in a certain sense. Some people don't bother to
read more than the first paragraph or two. If things don't work as
"documented" there, they immediately flood go-nuts, Go+ and SO (10+k
people) with the same question; which answer to can be found just a
bit lower than where they stopped reading.

-j

roger peppe

unread,
Apr 22, 2013, 10:03:10 AM4/22/13
to Dan Kortschak, Volker Dobler, golang-nuts, luz...@gmail.com
On 22 April 2013 12:57, Dan Kortschak <dan.ko...@adelaide.edu.au> wrote:
> In the C locale (now and here):
>
> $ date
> Mon Apr 22 21:24:26 CST 2013
>
> This means, the docs are 5 keystrokes away (if you live in C, and ignore
> the timezone).

That's a good point - one that I had overlooked and shall now remember!

The other slightly odd thing in this package is that there is no
constant for the
format used by Time.String. I'm not sure what we'd call it, mind.

nvcnvn

unread,
Apr 22, 2013, 10:17:00 AM4/22/13
to golan...@googlegroups.com
The time format make me confuse at first, then I must read the document again, carefully...
You see, for my country we use the format:
dd/mm/yyyy (for example 22/01/2012)

Now, we use "02" for "day", then we write: 02/01/2012
And then, when some guy who come from some countries like me look at the code, he may confuse about these number.
But after have a mess and read the document again (for poor English like me, read 3 times) its will be ok :))

Dean Schulze

unread,
Apr 22, 2013, 11:38:07 AM4/22/13
to golan...@googlegroups.com, Dean Schulze, Jesse McNelis
Here's some proposed wording that could be added:

"The only date and time that Format() can use is Mon Jan 2 15:04:05 -0700 MST 2006.   All layout strings passed to Format() must use this date and time in the format that you want your output to be in (e.g. "2006-01-02", "01.02.2006")

I saw the constants on the godoc page, but that doesn't say that that date and time is the only one that can be used.  Some of us are coming at this from decades of experience with other languages and I've not heard of a "standard time" for a date Format() layout string before.

Since this question keeps coming up on golang-nuts the community would benefit from an extra sentence or two in the documentation making clear that only one date and time can be used in the layout string.

Jan Mercl

unread,
Apr 22, 2013, 12:03:04 PM4/22/13
to Dean Schulze, golang-nuts, Jesse McNelis
On Mon, Apr 22, 2013 at 5:38 PM, Dean Schulze <dean.w....@gmail.com> wrote:

I don't get the "the only" part, I really don't know what you mean by that.

IMO its simple: There's a standard time. Format() expects a pattern
which shows how the standard time should be formatted.

-j

Chris Hines

unread,
Apr 22, 2013, 12:28:00 PM4/22/13
to golan...@googlegroups.com, Volker Dobler, roger peppe, luz...@gmail.com
Unfortunately not true on all OSes where Go runs.

Frank Schröder

unread,
Apr 22, 2013, 2:11:53 PM4/22/13
to golan...@googlegroups.com, Dean Schulze, Jesse McNelis
Yes, but when people read "pattern" they expect something like 'dd-MM-yyyy'. What time.Format() expects is an example and not a pattern. Once you understood it it makes sense but it is not obvious. At least not to everybody. Stumbled over this a couple of times myself.
Reply all
Reply to author
Forward
0 new messages