github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/apiv3/model/time.go (about)

     1  package model
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/evergreen-ci/evergreen/util"
     7  )
     8  
     9  const (
    10  	// This string defines ISO-8601 UTC with 3 fractional seconds behind a dot
    11  	// specified by the API spec document.
    12  	APITimeFormat = "\"2006-01-02T15:04:05.000Z\""
    13  )
    14  
    15  type APITime time.Time
    16  
    17  // NewTime creates a new APITime from an existing time.Time. It handles changing
    18  // converting from the times time zone to UTC.
    19  func NewTime(t time.Time) APITime {
    20  	utcT := t.In(time.UTC)
    21  	return APITime(time.Date(
    22  		utcT.Year(),
    23  		utcT.Month(),
    24  		utcT.Day(),
    25  		utcT.Hour(),
    26  		utcT.Minute(),
    27  		utcT.Second(),
    28  		utcT.Nanosecond(),
    29  		time.FixedZone("", 0),
    30  	))
    31  }
    32  
    33  // UnmarshalJSON implements the custom unmarshalling of this type so that it can
    34  // be correctly parsed from an API request.
    35  func (at *APITime) UnmarshalJSON(b []byte) error {
    36  	str := string(b)
    37  	t := time.Time{}
    38  	var err error
    39  	if str != "null" {
    40  		t, err = time.ParseInLocation(APITimeFormat, str, time.FixedZone("", 0))
    41  		if err != nil {
    42  			return err
    43  		}
    44  	}
    45  	(*at) = APITime(t)
    46  	return nil
    47  
    48  }
    49  
    50  // MarshalJSON implements the custom marshalling of this type so that it can
    51  // be correctly written out in an API response.
    52  func (at APITime) MarshalJSON() ([]byte, error) {
    53  	t := time.Time(at)
    54  	if util.IsZeroTime(t) {
    55  		return []byte("null"), nil
    56  	}
    57  	return []byte(t.Format(APITimeFormat)), nil
    58  }
    59  
    60  func (at APITime) String() string {
    61  	return time.Time(at).String()
    62  }