github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/common/format.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 ) 11 12 // FormatTime returns a string with the local time formatted 13 // in an arbitrary format used for status or and localized tz 14 // or in UTC timezone and format RFC3339 if u is specified. 15 func FormatTime(t *time.Time, formatISO bool) string { 16 if formatISO { 17 // If requested, use ISO time format. 18 // The format we use is RFC3339 without the "T". From the spec: 19 // NOTE: ISO 8601 defines date and time separated by "T". 20 // Applications using this syntax may choose, for the sake of 21 // readability, to specify a full-date and full-time separated by 22 // (say) a space character. 23 return t.UTC().Format("2006-01-02 15:04:05Z") 24 } 25 // Otherwise use local time. 26 return t.Local().Format("02 Jan 2006 15:04:05Z07:00") 27 } 28 29 // ConformYAML ensures all keys of any nested maps are strings. This is 30 // necessary because YAML unmarshals map[interface{}]interface{} in nested 31 // maps, which cannot be serialized by bson. Also, handle []interface{}. 32 // cf. gopkg.in/juju/charm.v4/actions.go cleanse 33 func ConformYAML(input interface{}) (interface{}, error) { 34 switch typedInput := input.(type) { 35 36 case map[string]interface{}: 37 newMap := make(map[string]interface{}) 38 for key, value := range typedInput { 39 newValue, err := ConformYAML(value) 40 if err != nil { 41 return nil, err 42 } 43 newMap[key] = newValue 44 } 45 return newMap, nil 46 47 case map[interface{}]interface{}: 48 newMap := make(map[string]interface{}) 49 for key, value := range typedInput { 50 typedKey, ok := key.(string) 51 if !ok { 52 return nil, errors.New("map keyed with non-string value") 53 } 54 newMap[typedKey] = value 55 } 56 return ConformYAML(newMap) 57 58 case []interface{}: 59 newSlice := make([]interface{}, len(typedInput)) 60 for i, sliceValue := range typedInput { 61 newSliceValue, err := ConformYAML(sliceValue) 62 if err != nil { 63 return nil, errors.New("map keyed with non-string value") 64 } 65 newSlice[i] = newSliceValue 66 } 67 return newSlice, nil 68 69 default: 70 return input, nil 71 } 72 }