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  }