time.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package saml
  2. import "time"
  3. // RelaxedTime is a version of time.Time that supports the time format
  4. // found in SAML documents.
  5. type RelaxedTime time.Time
  6. const timeFormat = "2006-01-02T15:04:05.999Z07:00"
  7. // MarshalText implements encoding.TextMarshaler
  8. func (m RelaxedTime) MarshalText() ([]byte, error) {
  9. // According to section 1.2.2 of the OASIS SAML 1.1 spec, we can't trust
  10. // other applications to handle time resolution finer than a millisecond.
  11. //
  12. // The time MUST be expressed in UTC.
  13. return []byte(m.String()), nil
  14. }
  15. func (m RelaxedTime) String() string {
  16. return time.Time(m).Round(time.Millisecond).UTC().Format(timeFormat)
  17. }
  18. // UnmarshalText implements encoding.TextUnmarshaler
  19. func (m *RelaxedTime) UnmarshalText(text []byte) error {
  20. if len(text) == 0 {
  21. *m = RelaxedTime(time.Time{})
  22. return nil
  23. }
  24. t, err1 := time.Parse(time.RFC3339, string(text))
  25. if err1 == nil {
  26. t = t.Round(time.Millisecond)
  27. *m = RelaxedTime(t)
  28. return nil
  29. }
  30. t, err2 := time.Parse(time.RFC3339Nano, string(text))
  31. if err2 == nil {
  32. t = t.Round(time.Millisecond)
  33. *m = RelaxedTime(t)
  34. return nil
  35. }
  36. t, err2 = time.Parse("2006-01-02T15:04:05.999999999", string(text))
  37. if err2 == nil {
  38. t = t.Round(time.Millisecond)
  39. *m = RelaxedTime(t)
  40. return nil
  41. }
  42. return err1
  43. }