Skip to content

Instantly share code, notes, and snippets.

@cbandy
Created February 10, 2015 06:29
Show Gist options
  • Save cbandy/77c104ff37d9c8a1ea7a to your computer and use it in GitHub Desktop.
Save cbandy/77c104ff37d9c8a1ea7a to your computer and use it in GitHub Desktop.
Simple but slow way to decode PostgreSQL timestamptz
func decodeTimestamptzISO(s []byte) time.Time {
if s[4] != '-' {
// Replace year with a 4-digit year that can be parsed
yearSep := bytes.IndexByte(s, '-')
year, _ := strconv.Atoi(string(s[:yearSep]))
replaced := append([]byte(`9600`), s[yearSep:]...)
// Add back remaining years
return decodeTimestamptzISO(replaced).AddDate(year-9600, 0, 0)
}
if s[len(s)-1] == 'C' {
// Time is before current era
yearSep := bytes.IndexByte(s, '-')
year, _ := strconv.Atoi(string(s[:yearSep]))
replaced := append([]byte(`0001`), s[yearSep:len(s)-3]...)
return decodeTimestamptzISO(replaced).AddDate(-year, 0, 0)
}
const (
HourOffset = "2006-01-02 15:04:05.999999999-07"
MinuteOffset = "2006-01-02 15:04:05.999999999-07:00"
SecondOffset = "2006-01-02 15:04:05.999999999-07:00:00"
)
var result time.Time
var err error
switch {
case s[len(s)-3] != ':':
result, err = time.ParseInLocation(HourOffset, string(s), locZeroOffset)
case s[len(s)-6] != ':':
result, err = time.ParseInLocation(MinuteOffset, string(s), locZeroOffset)
default:
result, err = time.ParseInLocation(SecondOffset, string(s), locZeroOffset)
}
if err != nil {
errorf(err.Error())
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment