change all time fields to have type time.Time (#190)

* add Volume.Unmarshal

* add volumetenants.VolumeExt.Unmarshal

* create servers.Server time.Time fields

* json.Unmarshal can correctly handle time.RFC3339 (Server time fields)

* add v3 Token UnmarshalJSON method

* check for empty string when unmarshaling time

* add Member UnmarshalJSON

* v3 tokens.Token ExtractInto

* v3 trust.Trust UnmarshalJSON

* time.Time fields swift response objects

* time.Time fields for orchestration response objects

* time.Time fields for shared file systems response objects

* if we don't use pointers for the custom time fields, we don't need to check if they're nil

* style guide fixes: 'r' for receiver, 's' for struct

* remove unnecessary pointers from UnmarshalJSON methods
diff --git a/openstack/objectstorage/v1/accounts/results.go b/openstack/objectstorage/v1/accounts/results.go
index 216414b..9bc8340 100644
--- a/openstack/objectstorage/v1/accounts/results.go
+++ b/openstack/objectstorage/v1/accounts/results.go
@@ -2,9 +2,9 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 )
@@ -16,117 +16,124 @@
 
 // UpdateHeader represents the headers returned in the response from an Update request.
 type UpdateHeader struct {
-	ContentLength int64                   `json:"-"`
-	ContentType   string                  `json:"Content-Type"`
-	TransID       string                  `json:"X-Trans-Id"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	TransID       string    `json:"X-Trans-Id"`
+	Date          time.Time `json:"-"`
 }
 
-func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
+func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
 	type tmp UpdateHeader
-	var updateHeader *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &updateHeader)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = UpdateHeader(updateHeader.tmp)
+	*r = UpdateHeader(s.tmp)
 
-	switch updateHeader.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(updateHeader.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	return nil
+	r.Date = time.Time(s.Date)
+
+	return err
 }
 
 // Extract will return a struct of headers returned from a call to Get. To obtain
 // a map of headers, call the ExtractHeader method on the GetResult.
-func (ur UpdateResult) Extract() (*UpdateHeader, error) {
-	var uh *UpdateHeader
-	err := ur.ExtractInto(&uh)
-	return uh, err
+func (r UpdateResult) Extract() (*UpdateHeader, error) {
+	var s *UpdateHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	BytesUsed      int64                   `json:"-"`
-	ContainerCount int64                   `json:"-"`
-	ContentLength  int64                   `json:"-"`
-	ObjectCount    int64                   `json:"-"`
-	ContentType    string                  `json:"Content-Type"`
-	TransID        string                  `json:"X-Trans-Id"`
-	TempURLKey     string                  `json:"X-Account-Meta-Temp-URL-Key"`
-	TempURLKey2    string                  `json:"X-Account-Meta-Temp-URL-Key-2"`
-	Date           gophercloud.JSONRFC1123 `json:"Date"`
+	BytesUsed      int64     `json:"-"`
+	ContainerCount int64     `json:"-"`
+	ContentLength  int64     `json:"-"`
+	ObjectCount    int64     `json:"-"`
+	ContentType    string    `json:"Content-Type"`
+	TransID        string    `json:"X-Trans-Id"`
+	TempURLKey     string    `json:"X-Account-Meta-Temp-URL-Key"`
+	TempURLKey2    string    `json:"X-Account-Meta-Temp-URL-Key-2"`
+	Date           time.Time `json:"-"`
 }
 
-func (h *GetHeader) UnmarshalJSON(b []byte) error {
+func (r *GetHeader) UnmarshalJSON(b []byte) error {
 	type tmp GetHeader
-	var getHeader *struct {
+	var s struct {
 		tmp
 		BytesUsed      string `json:"X-Account-Bytes-Used"`
 		ContentLength  string `json:"Content-Length"`
 		ContainerCount string `json:"X-Account-Container-Count"`
 		ObjectCount    string `json:"X-Account-Object-Count"`
+		Date           string `json:"Date"`
 	}
-	err := json.Unmarshal(b, &getHeader)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = GetHeader(getHeader.tmp)
+	*r = GetHeader(s.tmp)
 
-	switch getHeader.BytesUsed {
+	switch s.BytesUsed {
 	case "":
-		h.BytesUsed = 0
+		r.BytesUsed = 0
 	default:
-		h.BytesUsed, err = strconv.ParseInt(getHeader.BytesUsed, 10, 64)
+		r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	fmt.Println("getHeader: ", getHeader.ContentLength)
-	switch getHeader.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(getHeader.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	switch getHeader.ObjectCount {
+	switch s.ObjectCount {
 	case "":
-		h.ObjectCount = 0
+		r.ObjectCount = 0
 	default:
-		h.ObjectCount, err = strconv.ParseInt(getHeader.ObjectCount, 10, 64)
+		r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	switch getHeader.ContainerCount {
+	switch s.ContainerCount {
 	case "":
-		h.ContainerCount = 0
+		r.ContainerCount = 0
 	default:
-		h.ContainerCount, err = strconv.ParseInt(getHeader.ContainerCount, 10, 64)
+		r.ContainerCount, err = strconv.ParseInt(s.ContainerCount, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	return nil
+	if s.Date != "" {
+		r.Date, err = time.Parse(time.RFC1123, s.Date)
+	}
+
+	return err
 }
 
 // GetResult is returned from a call to the Get function.
@@ -142,7 +149,7 @@
 	return s, err
 }
 
-// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
+// ExtractMetadata is a function that takes a GetResult (of type *htts.Response)
 // and returns the custom metatdata associated with the account.
 func (r GetResult) ExtractMetadata() (map[string]string, error) {
 	if r.Err != nil {
diff --git a/openstack/objectstorage/v1/accounts/testing/requests_test.go b/openstack/objectstorage/v1/accounts/testing/requests_test.go
index dc5d9de..97852f1 100644
--- a/openstack/objectstorage/v1/accounts/testing/requests_test.go
+++ b/openstack/objectstorage/v1/accounts/testing/requests_test.go
@@ -4,7 +4,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/accounts"
 	th "github.com/gophercloud/gophercloud/testhelper"
 	fake "github.com/gophercloud/gophercloud/testhelper/client"
@@ -24,7 +23,7 @@
 	th.AssertNoErr(t, res.Err)
 
 	expected := &accounts.UpdateHeader{
-		Date: gophercloud.JSONRFC1123(time.Date(2014, time.January, 17, 16, 9, 56, 0, loc)), // Fri, 17 Jan 2014 16:09:56 GMT
+		Date: time.Date(2014, time.January, 17, 16, 9, 56, 0, loc), // Fri, 17 Jan 2014 16:09:56 GMT
 	}
 	actual, err := res.Extract()
 	th.AssertNoErr(t, err)
@@ -48,7 +47,7 @@
 		ContainerCount: 2,
 		ObjectCount:    5,
 		BytesUsed:      14,
-		Date:           gophercloud.JSONRFC1123(time.Date(2014, time.January, 17, 16, 9, 56, 0, loc)), // Fri, 17 Jan 2014 16:09:56 GMT
+		Date:           time.Date(2014, time.January, 17, 16, 9, 56, 0, loc), // Fri, 17 Jan 2014 16:09:56 GMT
 	}
 	actual, err := res.Extract()
 	th.AssertNoErr(t, err)
diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go
index ebe6eba..8c11b8c 100644
--- a/openstack/objectstorage/v1/containers/results.go
+++ b/openstack/objectstorage/v1/containers/results.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -88,69 +89,72 @@
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	AcceptRanges     string                  `json:"Accept-Ranges"`
-	BytesUsed        int64                   `json:"-"`
-	ContentLength    int64                   `json:"-"`
-	ContentType      string                  `json:"Content-Type"`
-	Date             gophercloud.JSONRFC1123 `json:"Date"`
-	ObjectCount      int64                   `json:"-"`
-	Read             []string                `json:"-"`
-	TransID          string                  `json:"X-Trans-Id"`
-	VersionsLocation string                  `json:"X-Versions-Location"`
-	Write            []string                `json:"-"`
+	AcceptRanges     string    `json:"Accept-Ranges"`
+	BytesUsed        int64     `json:"-"`
+	ContentLength    int64     `json:"-"`
+	ContentType      string    `json:"Content-Type"`
+	Date             time.Time `json:"-"`
+	ObjectCount      int64     `json:"-"`
+	Read             []string  `json:"-"`
+	TransID          string    `json:"X-Trans-Id"`
+	VersionsLocation string    `json:"X-Versions-Location"`
+	Write            []string  `json:"-"`
 }
 
-func (h *GetHeader) UnmarshalJSON(b []byte) error {
+func (r *GetHeader) UnmarshalJSON(b []byte) error {
 	type tmp GetHeader
-	var getHeader *struct {
+	var s struct {
 		tmp
-		BytesUsed     string `json:"X-Container-Bytes-Used"`
-		ContentLength string `json:"Content-Length"`
-		ObjectCount   string `json:"X-Container-Object-Count"`
-		Write         string `json:"X-Container-Write"`
-		Read          string `json:"X-Container-Read"`
+		BytesUsed     string                  `json:"X-Container-Bytes-Used"`
+		ContentLength string                  `json:"Content-Length"`
+		ObjectCount   string                  `json:"X-Container-Object-Count"`
+		Write         string                  `json:"X-Container-Write"`
+		Read          string                  `json:"X-Container-Read"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &getHeader)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = GetHeader(getHeader.tmp)
+	*r = GetHeader(s.tmp)
 
-	switch getHeader.BytesUsed {
+	switch s.BytesUsed {
 	case "":
-		h.BytesUsed = 0
+		r.BytesUsed = 0
 	default:
-		h.BytesUsed, err = strconv.ParseInt(getHeader.BytesUsed, 10, 64)
+		r.BytesUsed, err = strconv.ParseInt(s.BytesUsed, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	switch getHeader.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(getHeader.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	switch getHeader.ObjectCount {
+	switch s.ObjectCount {
 	case "":
-		h.ObjectCount = 0
+		r.ObjectCount = 0
 	default:
-		h.ObjectCount, err = strconv.ParseInt(getHeader.ObjectCount, 10, 64)
+		r.ObjectCount, err = strconv.ParseInt(s.ObjectCount, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	h.Read = strings.Split(getHeader.Read, ",")
-	h.Write = strings.Split(getHeader.Write, ",")
+	r.Read = strings.Split(s.Read, ",")
+	r.Write = strings.Split(s.Write, ",")
 
-	return nil
+	r.Date = time.Time(s.Date)
+
+	return err
 }
 
 // GetResult represents the result of a get operation.
@@ -166,7 +170,7 @@
 	return s, err
 }
 
-// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
+// ExtractMetadata is a function that takes a GetResult (of type *stts.Response)
 // and returns the custom metadata associated with the container.
 func (r GetResult) ExtractMetadata() (map[string]string, error) {
 	if r.Err != nil {
@@ -184,36 +188,39 @@
 
 // CreateHeader represents the headers returned in the response from a Create request.
 type CreateHeader struct {
-	ContentLength int64                   `json:"-"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *CreateHeader) UnmarshalJSON(b []byte) error {
+func (r *CreateHeader) UnmarshalJSON(b []byte) error {
 	type tmp CreateHeader
-	var header *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &header)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = CreateHeader(header.tmp)
+	*r = CreateHeader(s.tmp)
 
-	switch header.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	return nil
+	r.Date = time.Time(s.Date)
+
+	return err
 }
 
 // CreateResult represents the result of a create operation. To extract the
@@ -233,36 +240,39 @@
 
 // UpdateHeader represents the headers returned in the response from a Update request.
 type UpdateHeader struct {
-	ContentLength int64                   `json:"-"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
+func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
 	type tmp UpdateHeader
-	var header *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &header)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = UpdateHeader(header.tmp)
+	*r = UpdateHeader(s.tmp)
 
-	switch header.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	return nil
+	r.Date = time.Time(s.Date)
+
+	return err
 }
 
 // UpdateResult represents the result of an update operation. To extract the
@@ -282,36 +292,39 @@
 
 // DeleteHeader represents the headers returned in the response from a Delete request.
 type DeleteHeader struct {
-	ContentLength int64                   `json:"-"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *DeleteHeader) UnmarshalJSON(b []byte) error {
+func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
 	type tmp DeleteHeader
-	var header *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &header)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = DeleteHeader(header.tmp)
+	*r = DeleteHeader(s.tmp)
 
-	switch header.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(header.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
-	return nil
+	r.Date = time.Time(s.Date)
+
+	return err
 }
 
 // DeleteResult represents the result of a delete operation. To extract the
diff --git a/openstack/objectstorage/v1/containers/testing/requests_test.go b/openstack/objectstorage/v1/containers/testing/requests_test.go
index abac922..bb0c784 100644
--- a/openstack/objectstorage/v1/containers/testing/requests_test.go
+++ b/openstack/objectstorage/v1/containers/testing/requests_test.go
@@ -4,7 +4,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers"
 	"github.com/gophercloud/gophercloud/pagination"
 	th "github.com/gophercloud/gophercloud/testhelper"
@@ -93,7 +92,7 @@
 	expected := &containers.CreateHeader{
 		ContentLength: 0,
 		ContentType:   "text/html; charset=UTF-8",
-		Date:          gophercloud.JSONRFC1123(time.Date(2016, time.August, 17, 19, 25, 43, 0, loc)), //Wed, 17 Aug 2016 19:25:43 GMT
+		Date:          time.Date(2016, time.August, 17, 19, 25, 43, 0, loc), //Wed, 17 Aug 2016 19:25:43 GMT
 		TransID:       "tx554ed59667a64c61866f1-0058b4ba37",
 	}
 	actual, err := res.Extract()
@@ -133,7 +132,7 @@
 		AcceptRanges: "bytes",
 		BytesUsed:    100,
 		ContentType:  "application/json; charset=utf-8",
-		Date:         gophercloud.JSONRFC1123(time.Date(2016, time.August, 17, 19, 25, 43, 0, loc)), //Wed, 17 Aug 2016 19:25:43 GMT
+		Date:         time.Date(2016, time.August, 17, 19, 25, 43, 0, loc), //Wed, 17 Aug 2016 19:25:43 GMT
 		ObjectCount:  4,
 		Read:         []string{"test"},
 		TransID:      "tx554ed59667a64c61866f1-0057b4ba37",
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index 4f7020c..0dcdbe2 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -7,6 +7,7 @@
 	"io/ioutil"
 	"strconv"
 	"strings"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -23,15 +24,34 @@
 	// Hash represents the MD5 checksum value of the object's content.
 	Hash string `json:"hash"`
 
-	// LastModified is the RFC3339Milli time the object was last modified, represented
-	// as a string. For any given object (obj), this value may be parsed to a time.Time:
-	// lastModified, err := time.Parse(gophercloud.RFC3339Milli, obj.LastModified)
-	LastModified gophercloud.JSONRFC3339MilliNoZ `json:"last_modified"`
+	// LastModified is the time the object was last modified, represented
+	// as a string.
+	LastModified time.Time `json:"-"`
 
 	// Name is the unique name for the object.
 	Name string `json:"name"`
 }
 
+func (r *Object) UnmarshalJSON(b []byte) error {
+	type tmp Object
+	var s *struct {
+		tmp
+		LastModified gophercloud.JSONRFC3339MilliNoZ `json:"last_modified"`
+	}
+
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+
+	*r = Object(s.tmp)
+
+	r.LastModified = time.Time(s.LastModified)
+
+	return nil
+
+}
+
 // ObjectPage is a single page of objects that is returned from a call to the
 // List function.
 type ObjectPage struct {
@@ -100,43 +120,50 @@
 
 // DownloadHeader represents the headers returned in the response from a Download request.
 type DownloadHeader struct {
-	AcceptRanges       string                  `json:"Accept-Ranges"`
-	ContentDisposition string                  `json:"Content-Disposition"`
-	ContentEncoding    string                  `json:"Content-Encoding"`
-	ContentLength      int64                   `json:"-"`
-	ContentType        string                  `json:"Content-Type"`
-	Date               gophercloud.JSONRFC1123 `json:"Date"`
-	DeleteAt           gophercloud.JSONUnix    `json:"X-Delete-At"`
-	ETag               string                  `json:"Etag"`
-	LastModified       gophercloud.JSONRFC1123 `json:"Last-Modified"`
-	ObjectManifest     string                  `json:"X-Object-Manifest"`
-	StaticLargeObject  bool                    `json:"X-Static-Large-Object"`
-	TransID            string                  `json:"X-Trans-Id"`
+	AcceptRanges       string    `json:"Accept-Ranges"`
+	ContentDisposition string    `json:"Content-Disposition"`
+	ContentEncoding    string    `json:"Content-Encoding"`
+	ContentLength      int64     `json:"-"`
+	ContentType        string    `json:"Content-Type"`
+	Date               time.Time `json:"-"`
+	DeleteAt           time.Time `json:"-"`
+	ETag               string    `json:"Etag"`
+	LastModified       time.Time `json:"-"`
+	ObjectManifest     string    `json:"X-Object-Manifest"`
+	StaticLargeObject  bool      `json:"X-Static-Large-Object"`
+	TransID            string    `json:"X-Trans-Id"`
 }
 
-func (h *DownloadHeader) UnmarshalJSON(b []byte) error {
+func (r *DownloadHeader) UnmarshalJSON(b []byte) error {
 	type tmp DownloadHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
+		DeleteAt      gophercloud.JSONUnix    `json:"X-Delete-At"`
+		LastModified  gophercloud.JSONRFC1123 `json:"Last-Modified"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = DownloadHeader(hTmp.tmp)
+	*r = DownloadHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+	r.DeleteAt = time.Time(s.DeleteAt)
+	r.LastModified = time.Time(s.LastModified)
+
 	return nil
 }
 
@@ -174,42 +201,49 @@
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	ContentDisposition string                  `json:"Content-Disposition"`
-	ContentEncoding    string                  `json:"Content-Encoding"`
-	ContentLength      int64                   `json:"Content-Length"`
-	ContentType        string                  `json:"Content-Type"`
-	Date               gophercloud.JSONRFC1123 `json:"Date"`
-	DeleteAt           gophercloud.JSONUnix    `json:"X-Delete-At"`
-	ETag               string                  `json:"Etag"`
-	LastModified       gophercloud.JSONRFC1123 `json:"Last-Modified"`
-	ObjectManifest     string                  `json:"X-Object-Manifest"`
-	StaticLargeObject  bool                    `json:"X-Static-Large-Object"`
-	TransID            string                  `json:"X-Trans-Id"`
+	ContentDisposition string    `json:"Content-Disposition"`
+	ContentEncoding    string    `json:"Content-Encoding"`
+	ContentLength      int64     `json:"-"`
+	ContentType        string    `json:"Content-Type"`
+	Date               time.Time `json:"-"`
+	DeleteAt           time.Time `json:"-"`
+	ETag               string    `json:"Etag"`
+	LastModified       time.Time `json:"-"`
+	ObjectManifest     string    `json:"X-Object-Manifest"`
+	StaticLargeObject  bool      `json:"X-Static-Large-Object"`
+	TransID            string    `json:"X-Trans-Id"`
 }
 
-func (h *GetHeader) UnmarshalJSON(b []byte) error {
+func (r *GetHeader) UnmarshalJSON(b []byte) error {
 	type tmp GetHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
+		DeleteAt      gophercloud.JSONUnix    `json:"X-Delete-At"`
+		LastModified  gophercloud.JSONRFC1123 `json:"Last-Modified"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = GetHeader(hTmp.tmp)
+	*r = GetHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+	r.DeleteAt = time.Time(s.DeleteAt)
+	r.LastModified = time.Time(s.LastModified)
+
 	return nil
 }
 
@@ -244,37 +278,42 @@
 
 // CreateHeader represents the headers returned in the response from a Create request.
 type CreateHeader struct {
-	ContentLength int64                   `json:"Content-Length"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	ETag          string                  `json:"Etag"`
-	LastModified  gophercloud.JSONRFC1123 `json:"Last-Modified"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	ETag          string    `json:"Etag"`
+	LastModified  time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *CreateHeader) UnmarshalJSON(b []byte) error {
+func (r *CreateHeader) UnmarshalJSON(b []byte) error {
 	type tmp CreateHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
+		LastModified  gophercloud.JSONRFC1123 `json:"Last-Modified"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = CreateHeader(hTmp.tmp)
+	*r = CreateHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+	r.LastModified = time.Time(s.LastModified)
+
 	return nil
 }
 
@@ -297,35 +336,38 @@
 
 // UpdateHeader represents the headers returned in the response from a Update request.
 type UpdateHeader struct {
-	ContentLength int64                   `json:"Content-Length"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"-"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *UpdateHeader) UnmarshalJSON(b []byte) error {
+func (r *UpdateHeader) UnmarshalJSON(b []byte) error {
 	type tmp UpdateHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = UpdateHeader(hTmp.tmp)
+	*r = UpdateHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+
 	return nil
 }
 
@@ -344,35 +386,38 @@
 
 // DeleteHeader represents the headers returned in the response from a Delete request.
 type DeleteHeader struct {
-	ContentLength int64                   `json:"Content-Length"`
-	ContentType   string                  `json:"Content-Type"`
-	Date          gophercloud.JSONRFC1123 `json:"Date"`
-	TransID       string                  `json:"X-Trans-Id"`
+	ContentLength int64     `json:"Content-Length"`
+	ContentType   string    `json:"Content-Type"`
+	Date          time.Time `json:"-"`
+	TransID       string    `json:"X-Trans-Id"`
 }
 
-func (h *DeleteHeader) UnmarshalJSON(b []byte) error {
+func (r *DeleteHeader) UnmarshalJSON(b []byte) error {
 	type tmp DeleteHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength string                  `json:"Content-Length"`
+		Date          gophercloud.JSONRFC1123 `json:"Date"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = DeleteHeader(hTmp.tmp)
+	*r = DeleteHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+
 	return nil
 }
 
@@ -391,39 +436,46 @@
 
 // CopyHeader represents the headers returned in the response from a Copy request.
 type CopyHeader struct {
-	ContentLength          int64                   `json:"Content-Length"`
-	ContentType            string                  `json:"Content-Type"`
-	CopiedFrom             string                  `json:"X-Copied-From"`
-	CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
-	Date                   gophercloud.JSONRFC1123 `json:"Date"`
-	ETag                   string                  `json:"Etag"`
-	LastModified           gophercloud.JSONRFC1123 `json:"Last-Modified"`
-	TransID                string                  `json:"X-Trans-Id"`
+	ContentLength          int64     `json:"-"`
+	ContentType            string    `json:"Content-Type"`
+	CopiedFrom             string    `json:"X-Copied-From"`
+	CopiedFromLastModified time.Time `json:"-"`
+	Date                   time.Time `json:"-"`
+	ETag                   string    `json:"Etag"`
+	LastModified           time.Time `json:"-"`
+	TransID                string    `json:"X-Trans-Id"`
 }
 
-func (h *CopyHeader) UnmarshalJSON(b []byte) error {
+func (r *CopyHeader) UnmarshalJSON(b []byte) error {
 	type tmp CopyHeader
-	var hTmp *struct {
+	var s struct {
 		tmp
-		ContentLength string `json:"Content-Length"`
+		ContentLength          string                  `json:"Content-Length"`
+		CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
+		Date                   gophercloud.JSONRFC1123 `json:"Date"`
+		LastModified           gophercloud.JSONRFC1123 `json:"Last-Modified"`
 	}
-	err := json.Unmarshal(b, &hTmp)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*h = CopyHeader(hTmp.tmp)
+	*r = CopyHeader(s.tmp)
 
-	switch hTmp.ContentLength {
+	switch s.ContentLength {
 	case "":
-		h.ContentLength = 0
+		r.ContentLength = 0
 	default:
-		h.ContentLength, err = strconv.ParseInt(hTmp.ContentLength, 10, 64)
+		r.ContentLength, err = strconv.ParseInt(s.ContentLength, 10, 64)
 		if err != nil {
 			return err
 		}
 	}
 
+	r.Date = time.Time(s.Date)
+	r.CopiedFromLastModified = time.Time(s.CopiedFromLastModified)
+	r.LastModified = time.Time(s.LastModified)
+
 	return nil
 }
 
diff --git a/openstack/objectstorage/v1/objects/testing/fixtures.go b/openstack/objectstorage/v1/objects/testing/fixtures.go
index 53f03f5..08faab8 100644
--- a/openstack/objectstorage/v1/objects/testing/fixtures.go
+++ b/openstack/objectstorage/v1/objects/testing/fixtures.go
@@ -8,7 +8,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
 	th "github.com/gophercloud/gophercloud/testhelper"
 	fake "github.com/gophercloud/gophercloud/testhelper/client"
@@ -32,14 +31,14 @@
 var ExpectedListInfo = []objects.Object{
 	{
 		Hash:         "451e372e48e0f6b1114fa0724aa79fa1",
-		LastModified: gophercloud.JSONRFC3339MilliNoZ(time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC)), //"2016-08-17T22:11:58.602650"
+		LastModified: time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC), //"2016-08-17T22:11:58.602650"
 		Bytes:        14,
 		Name:         "goodbye",
 		ContentType:  "application/octet-stream",
 	},
 	{
 		Hash:         "451e372e48e0f6b1114fa0724aa79fa1",
-		LastModified: gophercloud.JSONRFC3339MilliNoZ(time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC)),
+		LastModified: time.Date(2016, time.August, 17, 22, 11, 58, 602650000, time.UTC),
 		Bytes:        14,
 		Name:         "hello",
 		ContentType:  "application/octet-stream",
diff --git a/openstack/objectstorage/v1/objects/testing/requests_test.go b/openstack/objectstorage/v1/objects/testing/requests_test.go
index 21f8e9d..4f26632 100644
--- a/openstack/objectstorage/v1/objects/testing/requests_test.go
+++ b/openstack/objectstorage/v1/objects/testing/requests_test.go
@@ -7,7 +7,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
 	"github.com/gophercloud/gophercloud/pagination"
 	th "github.com/gophercloud/gophercloud/testhelper"
@@ -47,7 +46,7 @@
 	expected := &objects.DownloadHeader{
 		ContentLength: 36,
 		ContentType:   "text/plain; charset=utf-8",
-		Date:          gophercloud.JSONRFC1123(time.Date(2009, time.November, 10, 23, 0, 0, 0, loc)),
+		Date:          time.Date(2009, time.November, 10, 23, 0, 0, 0, loc),
 	}
 	actual, err := response.Extract()
 	th.AssertNoErr(t, err)