schema: add UnknownLocation and IsZoneKnown

Change-Id: Ia056d03a367502ea4d06e5748cc7de7072c3e12c
This commit is contained in:
Brad Fitzpatrick 2014-07-24 13:35:18 -07:00
parent 80203318d1
commit ab885a369c
2 changed files with 57 additions and 5 deletions

View File

@ -828,14 +828,40 @@ func NewDeleteClaim(target blob.Ref) *Builder {
// This is the "send a link to a friend" access model.
const ShareHaveRef = "haveref"
// RFC3339FromTime returns an RFC3339-formatted time in UTC.
// UnknownLocation is a magic timezone value used when the actual location
// of a time is unknown. For instance, EXIF files commonly have a time without
// a corresponding location or timezone offset.
var UnknownLocation = time.FixedZone("Unknown", -60) // 1 minute west
// IsZoneKnown reports whether t is in a known timezone.
// Camlistore uses the magic timezone offset of 1 minute west of UTC
// to mean that the timezone wasn't known.
func IsZoneKnown(t time.Time) bool {
if t.Location() == UnknownLocation {
return false
}
if _, off := t.Zone(); off == -60 {
return false
}
return true
}
// RFC3339FromTime returns an RFC3339-formatted time.
//
// If the timezone is known, the time will be converted to UTC and
// returned with a "Z" suffix. For unknown zones, the timezone will be
// "-00:01" (1 minute west of UTC).
//
// Fractional seconds are only included if the time has fractional
// seconds.
func RFC3339FromTime(t time.Time) string {
if t.UnixNano()%1e9 == 0 {
return t.UTC().Format(time.RFC3339)
if IsZoneKnown(t) {
t = t.UTC()
}
return t.UTC().Format(time.RFC3339Nano)
if t.UnixNano()%1e9 == 0 {
return t.Format(time.RFC3339)
}
return t.Format(time.RFC3339Nano)
}
var bytesCamliVersion = []byte("camliVersion")

View File

@ -158,11 +158,27 @@ func TestStringFromMixedArray(t *testing.T) {
}
}
func TestIsZoneKnown(t *testing.T) {
if !IsZoneKnown(time.Now()) {
t.Errorf("should know Now's zone")
}
if !IsZoneKnown(time.Now().UTC()) {
t.Errorf("UTC should be known")
}
if IsZoneKnown(time.Now().In(UnknownLocation)) {
t.Errorf("with explicit unknown location, should be false")
}
if IsZoneKnown(time.Now().In(time.FixedZone("xx", -60))) {
t.Errorf("with other fixed zone at -60, should be false")
}
}
func TestRFC3339(t *testing.T) {
tests := []string{
"2012-05-13T15:02:47Z",
"2012-05-13T15:02:47.1234Z",
"2012-05-13T15:02:47.123456789Z",
"2012-05-13T15:02:47-00:01",
}
for _, in := range tests {
tm, err := time.Parse(time.RFC3339, in)
@ -170,9 +186,19 @@ func TestRFC3339(t *testing.T) {
t.Errorf("error parsing %q", in)
continue
}
if out := RFC3339FromTime(tm); in != out {
knownZone := IsZoneKnown(tm)
out := RFC3339FromTime(tm)
if in != out {
t.Errorf("RFC3339FromTime(%q) = %q; want %q", in, out, in)
}
sub := "Z"
if !knownZone {
sub = "-00:01"
}
if !strings.Contains(out, sub) {
t.Errorf("expected substring %q in %q", sub, out)
}
}
}