Time: custom layout

559 views
Skip to first unread message

bsr

unread,
May 13, 2011, 5:33:51 PM5/13/11
to golang-nuts
Hello,

I am trying to Parse time from string. The output of the program is

Sun May 13 00:00:00 +0000 2011
Sun May 13 00:00:00 +0000 2011

Why it is Sunday, as I expect Friday :-)

thanks.
bsr.
====== Program ========
package main

import (
"time"
)

func main() {
f1 := "2006/01/02" //02 Jan
v1 := "2011/05/13" //13 May

f2 := "01/02/2006" //02 Jan
v2 := "05/13/2011" //13 May

t, err := time.Parse(f1, v1)
if err != nil {
println(err.String())
} else {
println(t.String())
}

t, err = time.Parse(f2, v2)
if err != nil {
println(err.String())
} else {
println(t.String())
}
}

Kyle Lemons

unread,
May 13, 2011, 6:11:47 PM5/13/11
to bsr, golang-nuts
Time.Parse() only parses the fields it extracts.  You are only parsing out the year, month, and date, and those are the only things extracted:


&time.Time{Year:2011, Month:5, Day:13, Hour:0, Minute:0, Second:0, Weekday:0, ZoneOffset:0, Zone:""}
&time.Time{Year:2011, Month:5, Day:13, Hour:0, Minute:0, Second:0, Weekday:0, ZoneOffset:0, Zone:""}
Also you should avoid using println, use the fmt package.
--
~Kyle

"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" 
— Brian Kernighan

peterGo

unread,
May 13, 2011, 6:52:28 PM5/13/11
to golang-nuts
bsr,

"Only those elements present in the value will be set in the returned
time structure."
http://golang.org/pkg/time/#Time.Parse

You can solve the problem with a simple wrapper function. For example,
parseTime,

package main

import (
"fmt"
"os"
"time"
)

func parseTime(alayout, avalue string) (*time.Time, os.Error) {
t, err := time.Parse(alayout, avalue)
if err != nil {
return nil, err
}
return time.SecondsToUTC(t.Seconds()), nil
}

func main() {
f1 := "2006/01/02" //02 Jan
v1 := "2011/05/13" //13 May

f2 := "01/02/2006" //02 Jan
v2 := "05/13/2011" //13 May

t, err := parseTime(f1, v1)
if err != nil {
fmt.Println(err.String())
} else {
fmt.Println(t.String())
}

t, err = parseTime(f2, v2)
if err != nil {
fmt.Println(err.String())
} else {
fmt.Println(t.String())
}
}

Peter

bsr

unread,
May 13, 2011, 7:20:48 PM5/13/11
to golang-nuts
Thanks Kyle, Peter for timely help.. I was about to request for an API
to get DayOfWeek, as I thought it may compute from the date part of
time (Year, Month and Date). But, I understand now that it will be
erroneous without specifying the timezone. I think the current
implementation is fine that way, as if you don't specify a part in
Time, you can't expect it to be correct.
thanks again.
bsr.

bsr

unread,
May 14, 2011, 10:14:24 AM5/14/11
to golang-nuts
Hello,
Please help me to understand how time can be recorder better in a
webapp considering different timezone and daylight savings time
differences.

1. I plan to store all the time values in the system in UTC (in
seconds - int64 format). The manipulation (comparing the dates etc)
would be based on this value. Also any system generated time stamps
would be UTC().Seconds()

2. To accept a date-time input from the user, I will record date, time
(in 24hr format) and TimeZone values. This will cover everything in
Time struct, except "Weekday" and "ZoneOffset". So the questions are
Qn: does this cover daylight savings time for the zone user currently
in , or should I record ZoneOffset instead of Zone

Qn: Does the above data sufficient to represent the UTC time by
a. t, _ := Parse(alayout, avalue string) (*Time, os.Error) , with
whatever format
b. Convert this to UTC. t.Seconds() [I am not sure whether this
would be based on UTC or the timezone present in Time struct. The docs
say
"Seconds returns the number of seconds since January 1, 1970
represented by the parsed Time value." ]

3. To display the time back to the User, in the timezone specified by
the user (in the profile),
a. t := SecondsToUTC(utc)
b. s := t.Format("RFC3339")

Qn: Now, If I only need the date part, just do string manipulation on
"s", or is there a way to provide custom formatter for "Format"

thank you verymuch for ur time and help.
bsr.

peterGo

unread,
May 14, 2011, 1:09:52 PM5/14/11
to golang-nuts
bsr,

Usually, all times should at least be stored as a UTC time, some dates
should also be stored as a local time.

If I am a bank and all transactions accepted by 3 p.m. local time
(standard or daylight savings time depending on the time of year) are
posted that day, the UTC time does not tell me what day I should post
the transaction, the local time does. Also, a local timestamp is often
useful as an audit trail. For example, a bank teller or ATM
transaction should have both a UTC and a local timestamp.

UTC time provides a unique (ignoring leap seconds) set of ordered
values across all time zones.

For a complete UTC time, time.Parse or set the Year, Month, Day, Hour,
Minute, and Second time.Time values. ZoneOffset should be zero for UTC
time.

Local time is represented as numeric zone offset (in minutes) from a
UTC time.

For a complete local time, time.Parse or set the Year, Month, Day,
Hour, Minute, Second, and ZoneOffset time.Time values.

Any time.Time missing values are set to zero values for the type (for
Weekday that's Sunday). ZoneOffset is zero for UTC time. Weekday can
be computed from Year, Month, and Day time.Time values by converting
to seconds and back. Full and abbreviated time.Time.Zone strings are
not well-defined.

Time zone abbreviations are relative to a geographic location and
date. If my time zone abbreviation is EST, am I in Sydney, Australia
or New York City, USA? If live in Pulaski County, Indiana, USA, what
was my time zone abbreviation in 2006 and what is it now? Time zone
strings and abbreviations are not portable across time zone databases.
For example, compare Linux (tzdata) and Windows (registry).

As seasonal time zones change, absent the zone offset a local time is
not unique, when clocks are turned back local timestamps repeat. In
Samoa, the local time dates are not unique as they switch to and fro
across the International Date Line.

When time.Time t is converted by t.Seconds(), the number of seconds is
adjusted by the value of Time.ZoneOffset minutes.

For standard parse and format layouts, use the layout name. For
example, s := t.Format(time.RFC3339).

You can provide a custom format layout in the same way that you
provide a custom parse layout. For example, s :=
t.Format("2006-01-02") for just the date.

Peter

bsr

unread,
May 14, 2011, 2:16:17 PM5/14/11
to golang-nuts
Wow!.. that was quite informative.. thank you very much for your time.
One question though,

"Local time is represented as numeric zone offset (in minutes) from a
UTC time. "

I didn't quite understand this. In my mind, localtime in sec = utc in
sec + (+/-)zone offset in sec

thanks again for all ur help.
bsr.

peterGo

unread,
May 14, 2011, 4:09:44 PM5/14/11
to golang-nuts
bsr,

A zone offset is expressed as ±hhmm or ±hh (ISO 8601:2004); the zone
offset resolution is minutes. Almost all zone offsets are multiples of
an hour (60 minutes), but there are some that are multiples of 15
minutes, for example, Kathmandu, Nepal is 45 minutes. When you Parse
or Format a zone offset, allow for hours and minutes.

In the current implementation of the Go time package, the time zone is
converted to seconds before it's stored in the Time.ZoneOffset field.

Peter

Michael Jones

unread,
May 14, 2011, 6:09:07 PM5/14/11
to peterGo, golang-nuts
...and India is UTC/GMT +5:30 hours, so at least 1.1 billion / 6.5 billion = 23% of humans enjoy a half-hour offset. Thinking globally hurts. ;-)
--

Michael T. Jones

   Chief Technology Advocate, Google Inc.

   1600 Amphitheatre Parkway, Mountain View, California 94043

   Email: m...@google.com  Mobile: 650-335-5765  Fax: 650-649-1938

   Organizing the world's information to make it universally accessible and useful


Reply all
Reply to author
Forward
0 new messages