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/blockstorage/extensions/volumetenants/results.go b/openstack/blockstorage/extensions/volumetenants/results.go
index 0d4c670..b7d51c7 100644
--- a/openstack/blockstorage/extensions/volumetenants/results.go
+++ b/openstack/blockstorage/extensions/volumetenants/results.go
@@ -1,7 +1,12 @@
 package volumetenants
 
-// An extension to the base Volume object
+// VolumeExt is an extension to the base Volume object
 type VolumeExt struct {
 	// TenantID is the id of the project that owns the volume.
 	TenantID string `json:"os-vol-tenant-attr:tenant_id"`
 }
+
+// UnmarshalJSON to override default
+func (r *VolumeExt) UnmarshalJSON(b []byte) error {
+	return nil
+}
diff --git a/openstack/blockstorage/v2/volumes/results.go b/openstack/blockstorage/v2/volumes/results.go
index 41fbf5c..674ec34 100644
--- a/openstack/blockstorage/v2/volumes/results.go
+++ b/openstack/blockstorage/v2/volumes/results.go
@@ -1,18 +1,38 @@
 package volumes
 
 import (
+	"encoding/json"
+	"time"
+
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
 
 type Attachment struct {
-	AttachedAt   gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
-	AttachmentID string                          `json:"attachment_id"`
-	Device       string                          `json:"device"`
-	HostName     string                          `json:"host_name"`
-	ID           string                          `json:"id"`
-	ServerID     string                          `json:"server_id"`
-	VolumeID     string                          `json:"volume_id"`
+	AttachedAt   time.Time `json:"-"`
+	AttachmentID string    `json:"attachment_id"`
+	Device       string    `json:"device"`
+	HostName     string    `json:"host_name"`
+	ID           string    `json:"id"`
+	ServerID     string    `json:"server_id"`
+	VolumeID     string    `json:"volume_id"`
+}
+
+func (r *Attachment) UnmarshalJSON(b []byte) error {
+	type tmp Attachment
+	var s struct {
+		tmp
+		AttachedAt gophercloud.JSONRFC3339MilliNoZ `json:"attached_at"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = Attachment(s.tmp)
+
+	r.AttachedAt = time.Time(s.AttachedAt)
+
+	return err
 }
 
 // Volume contains all the information associated with an OpenStack Volume.
@@ -26,9 +46,9 @@
 	// AvailabilityZone is which availability zone the volume is in.
 	AvailabilityZone string `json:"availability_zone"`
 	// The date when this volume was created.
-	CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+	CreatedAt time.Time `json:"-"`
 	// The date when this volume was last updated
-	UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	UpdatedAt time.Time `json:"-"`
 	// Instances onto which the volume is attached.
 	Attachments []Attachment `json:"attachments"`
 	// Human-readable display name for the volume.
@@ -57,6 +77,25 @@
 	Multiattach bool `json:"multiattach"`
 }
 
+func (r *Volume) UnmarshalJSON(b []byte) error {
+	type tmp Volume
+	var s struct {
+		tmp
+		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+		UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = Volume(s.tmp)
+
+	r.CreatedAt = time.Time(s.CreatedAt)
+	r.UpdatedAt = time.Time(s.UpdatedAt)
+
+	return err
+}
+
 // VolumePage is a pagination.pager that is returned from a call to the List function.
 type VolumePage struct {
 	pagination.SinglePageBase
diff --git a/openstack/blockstorage/v2/volumes/testing/requests_test.go b/openstack/blockstorage/v2/volumes/testing/requests_test.go
index fd3dbcb..0a18544 100644
--- a/openstack/blockstorage/v2/volumes/testing/requests_test.go
+++ b/openstack/blockstorage/v2/volumes/testing/requests_test.go
@@ -4,7 +4,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumetenants"
 	"github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -35,7 +34,7 @@
 				Attachments: []volumes.Attachment{{
 					ServerID:     "83ec2e3b-4321-422b-8706-a84185f52a0a",
 					AttachmentID: "05551600-a936-4d4a-ba42-79a037c1-c91a",
-					AttachedAt:   gophercloud.JSONRFC3339MilliNoZ(time.Date(2016, 8, 6, 14, 48, 20, 0, time.UTC)),
+					AttachedAt:   time.Date(2016, 8, 6, 14, 48, 20, 0, time.UTC),
 					HostName:     "foobar",
 					VolumeID:     "d6cacb1a-8b59-4c88-ad90-d70ebb82bb75",
 					Device:       "/dev/vdc",
@@ -44,7 +43,7 @@
 				AvailabilityZone:   "nova",
 				Bootable:           "false",
 				ConsistencyGroupID: "",
-				CreatedAt:          gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 17, 3, 35, 3, 0, time.UTC)),
+				CreatedAt:          time.Date(2015, 9, 17, 3, 35, 3, 0, time.UTC),
 				Description:        "",
 				Encrypted:          false,
 				Metadata:           map[string]string{"foo": "bar"},
@@ -67,7 +66,7 @@
 				AvailabilityZone:   "nova",
 				Bootable:           "false",
 				ConsistencyGroupID: "",
-				CreatedAt:          gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 17, 3, 32, 29, 0, time.UTC)),
+				CreatedAt:          time.Date(2015, 9, 17, 3, 32, 29, 0, time.UTC),
 				Description:        "",
 				Encrypted:          false,
 				Metadata:           map[string]string{},
@@ -134,7 +133,7 @@
 			Attachments: []volumes.Attachment{{
 				ServerID:     "83ec2e3b-4321-422b-8706-a84185f52a0a",
 				AttachmentID: "05551600-a936-4d4a-ba42-79a037c1-c91a",
-				AttachedAt:   gophercloud.JSONRFC3339MilliNoZ(time.Date(2016, 8, 6, 14, 48, 20, 0, time.UTC)),
+				AttachedAt:   time.Date(2016, 8, 6, 14, 48, 20, 0, time.UTC),
 				HostName:     "foobar",
 				VolumeID:     "d6cacb1a-8b59-4c88-ad90-d70ebb82bb75",
 				Device:       "/dev/vdc",
@@ -143,7 +142,7 @@
 			AvailabilityZone:   "nova",
 			Bootable:           "false",
 			ConsistencyGroupID: "",
-			CreatedAt:          gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 17, 3, 35, 3, 0, time.UTC)),
+			CreatedAt:          time.Date(2015, 9, 17, 3, 35, 3, 0, time.UTC),
 			Description:        "",
 			Encrypted:          false,
 			Metadata:           map[string]string{"foo": "bar"},
@@ -166,7 +165,7 @@
 			AvailabilityZone:   "nova",
 			Bootable:           "false",
 			ConsistencyGroupID: "",
-			CreatedAt:          gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 17, 3, 32, 29, 0, time.UTC)),
+			CreatedAt:          time.Date(2015, 9, 17, 3, 32, 29, 0, time.UTC),
 			Description:        "",
 			Encrypted:          false,
 			Metadata:           map[string]string{},
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index a23923a..c121a6b 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -7,6 +7,7 @@
 	"fmt"
 	"net/url"
 	"path"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -101,12 +102,12 @@
 }
 
 // ExtractImageID gets the ID of the newly created server image from the header
-func (res CreateImageResult) ExtractImageID() (string, error) {
-	if res.Err != nil {
-		return "", res.Err
+func (r CreateImageResult) ExtractImageID() (string, error) {
+	if r.Err != nil {
+		return "", r.Err
 	}
 	// Get the image id from the header
-	u, err := url.ParseRequestURI(res.Header.Get("Location"))
+	u, err := url.ParseRequestURI(r.Header.Get("Location"))
 	if err != nil {
 		return "", err
 	}
@@ -137,26 +138,27 @@
 	// Name contains the human-readable name for the server.
 	Name string `json:"name"`
 	// Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
-	Updated string
-	Created string
-	HostID  string
+	Updated time.Time `json:"updated"`
+	Created time.Time `json:"created"`
+	HostID  string    `json:"hostid"`
 	// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
-	Status string
+	Status string `json:"status"`
 	// Progress ranges from 0..100.
 	// A request made against the server completes only once Progress reaches 100.
-	Progress int
+	Progress int `json:"progress"`
 	// AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
-	AccessIPv4, AccessIPv6 string
+	AccessIPv4 string `json:"accessIPv4"`
+	AccessIPv6 string `json:"accessIPv6"`
 	// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
-	Image map[string]interface{}
+	Image map[string]interface{} `json:"-"`
 	// Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
-	Flavor map[string]interface{}
+	Flavor map[string]interface{} `json:"flavor"`
 	// Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
-	Addresses map[string]interface{}
+	Addresses map[string]interface{} `json:"addresses"`
 	// Metadata includes a list of all user-specified key-value pairs attached to the server.
-	Metadata map[string]string
+	Metadata map[string]string `json:"metadata"`
 	// Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
-	Links []interface{}
+	Links []interface{} `json:"links"`
 	// KeyName indicates which public key was injected into the server on launch.
 	KeyName string `json:"key_name"`
 	// AdminPass will generally be empty ("").  However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
@@ -166,30 +168,30 @@
 	SecurityGroups []map[string]interface{} `json:"security_groups"`
 }
 
-func (s *Server) UnmarshalJSON(b []byte) error {
+func (r *Server) UnmarshalJSON(b []byte) error {
 	type tmp Server
-	var server *struct {
+	var s struct {
 		tmp
-		Image interface{}
+		Image interface{} `json:"image"`
 	}
-	err := json.Unmarshal(b, &server)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
 
-	*s = Server(server.tmp)
+	*r = Server(s.tmp)
 
-	switch t := server.Image.(type) {
+	switch t := s.Image.(type) {
 	case map[string]interface{}:
-		s.Image = t
+		r.Image = t
 	case string:
 		switch t {
 		case "":
-			s.Image = nil
+			r.Image = nil
 		}
 	}
 
-	return nil
+	return err
 }
 
 // ServerPage abstracts the raw results of making a List() request against the API.
@@ -200,17 +202,17 @@
 }
 
 // IsEmpty returns true if a page contains no Server results.
-func (page ServerPage) IsEmpty() (bool, error) {
-	servers, err := ExtractServers(page)
-	return len(servers) == 0, err
+func (r ServerPage) IsEmpty() (bool, error) {
+	s, err := ExtractServers(r)
+	return len(s) == 0, err
 }
 
 // NextPageURL uses the response's embedded link reference to navigate to the next page of results.
-func (page ServerPage) NextPageURL() (string, error) {
+func (r ServerPage) NextPageURL() (string, error) {
 	var s struct {
 		Links []gophercloud.Link `json:"servers_links"`
 	}
-	err := page.ExtractInto(&s)
+	err := r.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
diff --git a/openstack/compute/v2/servers/testing/fixtures.go b/openstack/compute/v2/servers/testing/fixtures.go
index adedb46..40d5ed2 100644
--- a/openstack/compute/v2/servers/testing/fixtures.go
+++ b/openstack/compute/v2/servers/testing/fixtures.go
@@ -4,6 +4,7 @@
 	"fmt"
 	"net/http"
 	"testing"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
@@ -304,10 +305,12 @@
 `
 
 var (
+	herpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:10:02Z")
+	herpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:10:10Z")
 	// ServerHerp is a Server struct that should correspond to the first result in ServerListBody.
 	ServerHerp = servers.Server{
 		Status:  "ACTIVE",
-		Updated: "2014-09-25T13:10:10Z",
+		Updated: herpTimeUpdated,
 		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
 		Addresses: map[string]interface{}{
 			"private": []interface{}{
@@ -350,7 +353,7 @@
 		ID:       "ef079b0c-e610-4dfb-b1aa-b49f07ac48e5",
 		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
 		Name:     "herp",
-		Created:  "2014-09-25T13:10:02Z",
+		Created:  herpTimeCreated,
 		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
 		Metadata: map[string]string{},
 		SecurityGroups: []map[string]interface{}{
@@ -360,10 +363,12 @@
 		},
 	}
 
+	derpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:41Z")
+	derpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:49Z")
 	// ServerDerp is a Server struct that should correspond to the second server in ServerListBody.
 	ServerDerp = servers.Server{
 		Status:  "ACTIVE",
-		Updated: "2014-09-25T13:04:49Z",
+		Updated: derpTimeUpdated,
 		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
 		Addresses: map[string]interface{}{
 			"private": []interface{}{
@@ -406,7 +411,7 @@
 		ID:       "9e5476bd-a4ec-4653-93d6-72c93aa682ba",
 		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
 		Name:     "derp",
-		Created:  "2014-09-25T13:04:41Z",
+		Created:  derpTimeCreated,
 		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
 		Metadata: map[string]string{},
 		SecurityGroups: []map[string]interface{}{
@@ -416,10 +421,12 @@
 		},
 	}
 
+	merpTimeCreated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:41Z")
+	merpTimeUpdated, _ = time.Parse(time.RFC3339, "2014-09-25T13:04:49Z")
 	// ServerMerp is a Server struct that should correspond to the second server in ServerListBody.
 	ServerMerp = servers.Server{
 		Status:  "ACTIVE",
-		Updated: "2014-09-25T13:04:49Z",
+		Updated: merpTimeUpdated,
 		HostID:  "29d3c8c896a45aa4c34e52247875d7fefc3d94bbcc9f622b5d204362",
 		Addresses: map[string]interface{}{
 			"private": []interface{}{
@@ -454,7 +461,7 @@
 		ID:       "9e5476bd-a4ec-4653-93d6-72c93aa682bb",
 		UserID:   "9349aff8be7545ac9d2f1d00999a23cd",
 		Name:     "merp",
-		Created:  "2014-09-25T13:04:41Z",
+		Created:  merpTimeCreated,
 		TenantID: "fcad67a6189847c4aecfa3c81a05783b",
 		Metadata: map[string]string{},
 		SecurityGroups: []map[string]interface{}{
diff --git a/openstack/identity/v3/extensions/trusts/results.go b/openstack/identity/v3/extensions/trusts/results.go
index 3d3c7f2..bdd8e84 100644
--- a/openstack/identity/v3/extensions/trusts/results.go
+++ b/openstack/identity/v3/extensions/trusts/results.go
@@ -1,7 +1,5 @@
 package trusts
 
-import "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
-
 type TrusteeUser struct {
 	ID string `json:"id"`
 }
@@ -19,11 +17,6 @@
 	RedelegationCount  int         `json:"redelegation_count"`
 }
 
-type Token struct {
-	tokens.Token
-	Trust Trust `json:"OS-TRUST:trust"`
-}
-
 type TokenExt struct {
-	Token Token `json:"token"`
+	Trust Trust `json:"OS-TRUST:trust"`
 }
diff --git a/openstack/identity/v3/extensions/trusts/testing/fixtures.go b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
index b4106a3..e311526 100644
--- a/openstack/identity/v3/extensions/trusts/testing/fixtures.go
+++ b/openstack/identity/v3/extensions/trusts/testing/fixtures.go
@@ -4,24 +4,13 @@
 	"fmt"
 	"net/http"
 	"testing"
-	"time"
 
-	"github.com/gophercloud/gophercloud"
-	"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
 	"github.com/gophercloud/gophercloud/testhelper"
 )
 
 // HandleCreateTokenWithTrustID verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
 func HandleCreateTokenWithTrustID(t *testing.T, options tokens.AuthOptionsBuilder, requestJSON string) {
-	testhelper.SetupHTTP()
-	defer testhelper.TeardownHTTP()
-
-	client := gophercloud.ServiceClient{
-		ProviderClient: &gophercloud.ProviderClient{},
-		Endpoint:       testhelper.Endpoint(),
-	}
-
 	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "POST")
 		testhelper.TestHeader(t, r, "Content-Type", "application/json")
@@ -75,30 +64,4 @@
     }
 }`)
 	})
-
-	var actual trusts.TokenExt
-	err := tokens.Create(&client, options).ExtractInto(&actual)
-	if err != nil {
-		t.Errorf("Create returned an error: %v", err)
-	}
-	expected := trusts.TokenExt{
-		Token: trusts.Token{
-			Token: tokens.Token{
-				ExpiresAt: gophercloud.JSONRFC3339Milli(time.Date(2013, 02, 27, 18, 30, 59, 999999000, time.UTC)),
-			},
-			Trust: trusts.Trust{
-				ID:            "fe0aef",
-				Impersonation: false,
-				TrusteeUser: trusts.TrusteeUser{
-					ID: "0ca8f6",
-				},
-				TrustorUser: trusts.TrustorUser{
-					ID: "bd263c",
-				},
-				RedelegatedTrustID: "3ba234",
-				RedelegationCount:  2,
-			},
-		},
-	}
-	testhelper.AssertDeepEquals(t, expected, actual)
 }
diff --git a/openstack/identity/v3/extensions/trusts/testing/requests_test.go b/openstack/identity/v3/extensions/trusts/testing/requests_test.go
index f0e41dc..f8a65ad 100644
--- a/openstack/identity/v3/extensions/trusts/testing/requests_test.go
+++ b/openstack/identity/v3/extensions/trusts/testing/requests_test.go
@@ -2,12 +2,18 @@
 
 import (
 	"testing"
+	"time"
 
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/trusts"
 	"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
+	th "github.com/gophercloud/gophercloud/testhelper"
+	"github.com/gophercloud/gophercloud/testhelper/client"
 )
 
 func TestCreateUserIDPasswordTrustID(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
 	ao := trusts.AuthOptsExt{
 		TrustID: "de0945a",
 		AuthOptionsBuilder: &tokens.AuthOptions{
@@ -32,4 +38,37 @@
 			}
 		}
 	`)
+
+	var actual struct {
+		tokens.Token
+		trusts.TokenExt
+	}
+	err := tokens.Create(client.ServiceClient(), ao).ExtractInto(&actual)
+	if err != nil {
+		t.Errorf("Create returned an error: %v", err)
+	}
+	expected := struct {
+		tokens.Token
+		trusts.TokenExt
+	}{
+		tokens.Token{
+			ExpiresAt: time.Date(2013, 02, 27, 18, 30, 59, 999999000, time.UTC),
+		},
+		trusts.TokenExt{
+			Trust: trusts.Trust{
+				ID:            "fe0aef",
+				Impersonation: false,
+				TrusteeUser: trusts.TrusteeUser{
+					ID: "0ca8f6",
+				},
+				TrustorUser: trusts.TrustorUser{
+					ID: "bd263c",
+				},
+				RedelegatedTrustID: "3ba234",
+				RedelegationCount:  2,
+			},
+		},
+	}
+
+	th.AssertDeepEquals(t, expected, actual)
 }
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index 2144a2b..0f1e8c2 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -1,7 +1,10 @@
 package tokens
 
-import "errors"
-import "github.com/gophercloud/gophercloud"
+import (
+	"time"
+
+	"github.com/gophercloud/gophercloud"
+)
 
 // Endpoint represents a single API endpoint offered by a service.
 // It matches either a public, internal or admin URL.
@@ -35,7 +38,7 @@
 
 // ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
 type ServiceCatalog struct {
-	Entries []CatalogEntry
+	Entries []CatalogEntry `json:"catalog"`
 }
 
 // commonResult is the deferred result of a Create or a Get call.
@@ -51,34 +54,23 @@
 
 // ExtractToken interprets a commonResult as a Token.
 func (r commonResult) ExtractToken() (*Token, error) {
-	var s struct {
-		Token *Token `json:"token"`
-	}
-
+	var s Token
 	err := r.ExtractInto(&s)
 	if err != nil {
 		return nil, err
 	}
 
-	if s.Token == nil {
-		return nil, errors.New("'token' missing in JSON response")
-	}
-
 	// Parse the token itself from the stored headers.
-	s.Token.ID = r.Header.Get("X-Subject-Token")
+	s.ID = r.Header.Get("X-Subject-Token")
 
-	return s.Token, err
+	return &s, err
 }
 
 // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
 func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
-	var s struct {
-		Token struct {
-			Entries []CatalogEntry `json:"catalog"`
-		} `json:"token"`
-	}
+	var s ServiceCatalog
 	err := r.ExtractInto(&s)
-	return &ServiceCatalog{Entries: s.Token.Entries}, err
+	return &s, err
 }
 
 // CreateResult defers the interpretation of a created token.
@@ -103,5 +95,9 @@
 	// ID is the issued token.
 	ID string `json:"id"`
 	// ExpiresAt is the timestamp at which this token will no longer be accepted.
-	ExpiresAt gophercloud.JSONRFC3339Milli `json:"expires_at"`
+	ExpiresAt time.Time `json:"expires_at"`
+}
+
+func (r commonResult) ExtractInto(v interface{}) error {
+	return r.ExtractIntoStructPtr(v, "token")
 }
diff --git a/openstack/identity/v3/tokens/testing/requests_test.go b/openstack/identity/v3/tokens/testing/requests_test.go
index 27f3fdc..ddffeb4 100644
--- a/openstack/identity/v3/tokens/testing/requests_test.go
+++ b/openstack/identity/v3/tokens/testing/requests_test.go
@@ -39,10 +39,12 @@
 		options.Scope = *scope
 	}
 
-	_, err := tokens.Create(&client, &options).Extract()
-	if err != nil {
-		t.Errorf("Create returned an error: %v", err)
+	expected := &tokens.Token{
+		ExpiresAt: time.Date(2014, 10, 2, 13, 45, 0, 0, time.UTC),
 	}
+	actual, err := tokens.Create(&client, &options).Extract()
+	testhelper.AssertNoErr(t, err)
+	testhelper.CheckDeepEquals(t, expected, actual)
 }
 
 func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) {
@@ -423,7 +425,7 @@
 	}
 
 	expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014")
-	if token.ExpiresAt != gophercloud.JSONRFC3339Milli(expected) {
+	if token.ExpiresAt != expected {
 		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), time.Time(token.ExpiresAt).Format(time.UnixDate))
 	}
 }
@@ -526,7 +528,5 @@
 
 	options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"}
 	_, err := tokens.Create(&client, &options).Extract()
-	if err == nil {
-		t.Error("Create succeeded with no token returned")
-	}
+	testhelper.AssertNoErr(t, err)
 }
diff --git a/openstack/imageservice/v2/images/results.go b/openstack/imageservice/v2/images/results.go
index 653c68c..ae674de 100644
--- a/openstack/imageservice/v2/images/results.go
+++ b/openstack/imageservice/v2/images/results.go
@@ -66,10 +66,10 @@
 	Properties map[string]string `json:"properties"`
 
 	// CreatedAt is the date when the image has been created.
-	CreatedAt time.Time `json:"-"`
+	CreatedAt time.Time `json:"created_at"`
 
 	// UpdatedAt is the date when the last change has been made to the image or it's properties.
-	UpdatedAt time.Time `json:"-"`
+	UpdatedAt time.Time `json:"updated_at"`
 
 	// File is the trailing path after the glance endpoint that represent the location
 	// of the image or the path to retrieve it.
@@ -79,36 +79,29 @@
 	Schema string `json:"schema"`
 }
 
-func (s *Image) UnmarshalJSON(b []byte) error {
+func (r *Image) UnmarshalJSON(b []byte) error {
 	type tmp Image
-	var p *struct {
+	var s struct {
 		tmp
 		SizeBytes interface{} `json:"size"`
-		CreatedAt string      `json:"created_at"`
-		UpdatedAt string      `json:"updated_at"`
 	}
-	err := json.Unmarshal(b, &p)
+	err := json.Unmarshal(b, &s)
 	if err != nil {
 		return err
 	}
-	*s = Image(p.tmp)
+	*r = Image(s.tmp)
 
-	switch t := p.SizeBytes.(type) {
+	switch t := s.SizeBytes.(type) {
 	case nil:
 		return nil
 	case float32:
-		s.SizeBytes = int64(t)
+		r.SizeBytes = int64(t)
 	case float64:
-		s.SizeBytes = int64(t)
+		r.SizeBytes = int64(t)
 	default:
 		return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t)
 	}
 
-	s.CreatedAt, err = time.Parse(time.RFC3339, p.CreatedAt)
-	if err != nil {
-		return err
-	}
-	s.UpdatedAt, err = time.Parse(time.RFC3339, p.UpdatedAt)
 	return err
 }
 
diff --git a/openstack/imageservice/v2/members/results.go b/openstack/imageservice/v2/members/results.go
index 1d2a9c0..d3cc1ce 100644
--- a/openstack/imageservice/v2/members/results.go
+++ b/openstack/imageservice/v2/members/results.go
@@ -1,7 +1,6 @@
 package members
 
 import (
-	"encoding/json"
 	"time"
 
 	"github.com/gophercloud/gophercloud"
@@ -10,33 +9,12 @@
 
 // Member model
 type Member struct {
-	CreatedAt time.Time `json:"-"`
+	CreatedAt time.Time `json:"created_at"`
 	ImageID   string    `json:"image_id"`
 	MemberID  string    `json:"member_id"`
 	Schema    string    `json:"schema"`
 	Status    string    `json:"status"`
-	UpdatedAt time.Time `json:"-"`
-}
-
-func (s *Member) UnmarshalJSON(b []byte) error {
-	type tmp Member
-	var p *struct {
-		tmp
-		CreatedAt string `json:"created_at"`
-		UpdatedAt string `json:"updated_at"`
-	}
-	err := json.Unmarshal(b, &p)
-	if err != nil {
-		return err
-	}
-
-	*s = Member(p.tmp)
-	s.CreatedAt, err = time.Parse(time.RFC3339, p.CreatedAt)
-	if err != nil {
-		return err
-	}
-	s.UpdatedAt, err = time.Parse(time.RFC3339, p.UpdatedAt)
-	return err
+	UpdatedAt time.Time `json:"updated_at"`
 }
 
 // Extract Member model from request if possible
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)
diff --git a/openstack/orchestration/v1/stackevents/results.go b/openstack/orchestration/v1/stackevents/results.go
index 6c7f183..46fb0ff 100644
--- a/openstack/orchestration/v1/stackevents/results.go
+++ b/openstack/orchestration/v1/stackevents/results.go
@@ -1,6 +1,9 @@
 package stackevents
 
 import (
+	"encoding/json"
+	"time"
+
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -10,7 +13,7 @@
 	// The name of the resource for which the event occurred.
 	ResourceName string `json:"resource_name"`
 	// The time the event occurred.
-	Time gophercloud.JSONRFC3339NoZ `json:"event_time"`
+	Time time.Time `json:"-"`
 	// The URLs to the event.
 	Links []gophercloud.Link `json:"links"`
 	// The logical ID of the stack resource.
@@ -27,6 +30,24 @@
 	ResourceProperties map[string]interface{} `json:"resource_properties"`
 }
 
+func (r *Event) UnmarshalJSON(b []byte) error {
+	type tmp Event
+	var s struct {
+		tmp
+		Time gophercloud.JSONRFC3339NoZ `json:"event_time"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+
+	*r = Event(s.tmp)
+
+	r.Time = time.Time(s.Time)
+
+	return nil
+}
+
 // FindResult represents the result of a Find operation.
 type FindResult struct {
 	gophercloud.Result
diff --git a/openstack/orchestration/v1/stackevents/testing/fixtures.go b/openstack/orchestration/v1/stackevents/testing/fixtures.go
index a7af025..a40e8d4 100644
--- a/openstack/orchestration/v1/stackevents/testing/fixtures.go
+++ b/openstack/orchestration/v1/stackevents/testing/fixtures.go
@@ -16,7 +16,7 @@
 var FindExpected = []stackevents.Event{
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -39,7 +39,7 @@
 	},
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -133,7 +133,7 @@
 var ListExpected = []stackevents.Event{
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -156,7 +156,7 @@
 	},
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -258,7 +258,7 @@
 var ListResourceEventsExpected = []stackevents.Event{
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -281,7 +281,7 @@
 	},
 	{
 		ResourceName: "hello_world",
-		Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
+		Time:         time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
 		Links: []gophercloud.Link{
 			{
 				Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -382,7 +382,7 @@
 // GetExpected represents the expected object from a Get request.
 var GetExpected = &stackevents.Event{
 	ResourceName: "hello_world",
-	Time:         gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
+	Time:         time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
 	Links: []gophercloud.Link{
 		{
 			Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
diff --git a/openstack/orchestration/v1/stackresources/results.go b/openstack/orchestration/v1/stackresources/results.go
index bd3e29f..59c02a3 100644
--- a/openstack/orchestration/v1/stackresources/results.go
+++ b/openstack/orchestration/v1/stackresources/results.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -9,18 +10,37 @@
 
 // Resource represents a stack resource.
 type Resource struct {
-	Attributes   map[string]interface{}     `json:"attributes"`
-	CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
-	Description  string                     `json:"description"`
-	Links        []gophercloud.Link         `json:"links"`
-	LogicalID    string                     `json:"logical_resource_id"`
-	Name         string                     `json:"resource_name"`
-	PhysicalID   string                     `json:"physical_resource_id"`
-	RequiredBy   []interface{}              `json:"required_by"`
-	Status       string                     `json:"resource_status"`
-	StatusReason string                     `json:"resource_status_reason"`
-	Type         string                     `json:"resource_type"`
-	UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	Attributes   map[string]interface{} `json:"attributes"`
+	CreationTime time.Time              `json:"-"`
+	Description  string                 `json:"description"`
+	Links        []gophercloud.Link     `json:"links"`
+	LogicalID    string                 `json:"logical_resource_id"`
+	Name         string                 `json:"resource_name"`
+	PhysicalID   string                 `json:"physical_resource_id"`
+	RequiredBy   []interface{}          `json:"required_by"`
+	Status       string                 `json:"resource_status"`
+	StatusReason string                 `json:"resource_status_reason"`
+	Type         string                 `json:"resource_type"`
+	UpdatedTime  time.Time              `json:"-"`
+}
+
+func (r *Resource) UnmarshalJSON(b []byte) error {
+	type tmp Resource
+	var s struct {
+		tmp
+		CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+		UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = Resource(s.tmp)
+
+	r.CreationTime = time.Time(s.CreationTime)
+	r.UpdatedTime = time.Time(s.UpdatedTime)
+
+	return nil
 }
 
 // FindResult represents the result of a Find operation.
diff --git a/openstack/orchestration/v1/stackresources/testing/fixtures.go b/openstack/orchestration/v1/stackresources/testing/fixtures.go
index adcd4c6..e890337 100644
--- a/openstack/orchestration/v1/stackresources/testing/fixtures.go
+++ b/openstack/orchestration/v1/stackresources/testing/fixtures.go
@@ -28,8 +28,8 @@
 		},
 		LogicalID:    "hello_world",
 		StatusReason: "state changed",
-		UpdatedTime:  gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
-		CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC)),
+		UpdatedTime:  time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+		CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
 		RequiredBy:   []interface{}{},
 		Status:       "CREATE_IN_PROGRESS",
 		PhysicalID:   "49181cd6-169a-4130-9455-31185bbfc5bf",
@@ -99,8 +99,8 @@
 		},
 		LogicalID:    "hello_world",
 		StatusReason: "state changed",
-		UpdatedTime:  gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
-		CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC)),
+		UpdatedTime:  time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+		CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
 		RequiredBy:   []interface{}{},
 		Status:       "CREATE_IN_PROGRESS",
 		PhysicalID:   "49181cd6-169a-4130-9455-31185bbfc5bf",
@@ -177,7 +177,7 @@
 	LogicalID:    "wordpress_instance",
 	Attributes:   map[string]interface{}{"SXSW": "atx"},
 	StatusReason: "state changed",
-	UpdatedTime:  gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC)),
+	UpdatedTime:  time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC),
 	RequiredBy:   []interface{}{},
 	Status:       "CREATE_COMPLETE",
 	PhysicalID:   "00e3a2fe-c65d-403c-9483-4db9930dd194",
diff --git a/openstack/orchestration/v1/stacks/results.go b/openstack/orchestration/v1/stacks/results.go
index 6b6f3a3..8df5419 100644
--- a/openstack/orchestration/v1/stacks/results.go
+++ b/openstack/orchestration/v1/stacks/results.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -47,15 +48,34 @@
 
 // ListedStack represents an element in the slice extracted from a List operation.
 type ListedStack struct {
-	CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
-	Description  string                     `json:"description"`
-	ID           string                     `json:"id"`
-	Links        []gophercloud.Link         `json:"links"`
-	Name         string                     `json:"stack_name"`
-	Status       string                     `json:"stack_status"`
-	StatusReason string                     `json:"stack_status_reason"`
-	Tags         []string                   `json:"tags"`
-	UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	CreationTime time.Time          `json:"-"`
+	Description  string             `json:"description"`
+	ID           string             `json:"id"`
+	Links        []gophercloud.Link `json:"links"`
+	Name         string             `json:"stack_name"`
+	Status       string             `json:"stack_status"`
+	StatusReason string             `json:"stack_status_reason"`
+	Tags         []string           `json:"tags"`
+	UpdatedTime  time.Time          `json:"-"`
+}
+
+func (r *ListedStack) UnmarshalJSON(b []byte) error {
+	type tmp ListedStack
+	var s struct {
+		tmp
+		CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+		UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = ListedStack(s.tmp)
+
+	r.CreationTime = time.Time(s.CreationTime)
+	r.UpdatedTime = time.Time(s.UpdatedTime)
+
+	return nil
 }
 
 // ExtractStacks extracts and returns a slice of ListedStack. It is used while iterating
@@ -70,22 +90,41 @@
 
 // RetrievedStack represents the object extracted from a Get operation.
 type RetrievedStack struct {
-	Capabilities        []interface{}              `json:"capabilities"`
-	CreationTime        gophercloud.JSONRFC3339NoZ `json:"creation_time"`
-	Description         string                     `json:"description"`
-	DisableRollback     bool                       `json:"disable_rollback"`
-	ID                  string                     `json:"id"`
-	Links               []gophercloud.Link         `json:"links"`
-	NotificationTopics  []interface{}              `json:"notification_topics"`
-	Outputs             []map[string]interface{}   `json:"outputs"`
-	Parameters          map[string]string          `json:"parameters"`
-	Name                string                     `json:"stack_name"`
-	Status              string                     `json:"stack_status"`
-	StatusReason        string                     `json:"stack_status_reason"`
-	Tags                []string                   `json:"tags"`
-	TemplateDescription string                     `json:"template_description"`
-	Timeout             int                        `json:"timeout_mins"`
-	UpdatedTime         gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	Capabilities        []interface{}            `json:"capabilities"`
+	CreationTime        time.Time                `json:"-"`
+	Description         string                   `json:"description"`
+	DisableRollback     bool                     `json:"disable_rollback"`
+	ID                  string                   `json:"id"`
+	Links               []gophercloud.Link       `json:"links"`
+	NotificationTopics  []interface{}            `json:"notification_topics"`
+	Outputs             []map[string]interface{} `json:"outputs"`
+	Parameters          map[string]string        `json:"parameters"`
+	Name                string                   `json:"stack_name"`
+	Status              string                   `json:"stack_status"`
+	StatusReason        string                   `json:"stack_status_reason"`
+	Tags                []string                 `json:"tags"`
+	TemplateDescription string                   `json:"template_description"`
+	Timeout             int                      `json:"timeout_mins"`
+	UpdatedTime         time.Time                `json:"-"`
+}
+
+func (r *RetrievedStack) UnmarshalJSON(b []byte) error {
+	type tmp RetrievedStack
+	var s struct {
+		tmp
+		CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+		UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = RetrievedStack(s.tmp)
+
+	r.CreationTime = time.Time(s.CreationTime)
+	r.UpdatedTime = time.Time(s.UpdatedTime)
+
+	return nil
 }
 
 // GetResult represents the result of a Get operation.
@@ -115,19 +154,38 @@
 
 // PreviewedStack represents the result of a Preview operation.
 type PreviewedStack struct {
-	Capabilities        []interface{}              `json:"capabilities"`
-	CreationTime        gophercloud.JSONRFC3339NoZ `json:"creation_time"`
-	Description         string                     `json:"description"`
-	DisableRollback     bool                       `json:"disable_rollback"`
-	ID                  string                     `json:"id"`
-	Links               []gophercloud.Link         `json:"links"`
-	Name                string                     `json:"stack_name"`
-	NotificationTopics  []interface{}              `json:"notification_topics"`
-	Parameters          map[string]string          `json:"parameters"`
-	Resources           []interface{}              `json:"resources"`
-	TemplateDescription string                     `json:"template_description"`
-	Timeout             int                        `json:"timeout_mins"`
-	UpdatedTime         gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	Capabilities        []interface{}      `json:"capabilities"`
+	CreationTime        time.Time          `json:"-"`
+	Description         string             `json:"description"`
+	DisableRollback     bool               `json:"disable_rollback"`
+	ID                  string             `json:"id"`
+	Links               []gophercloud.Link `json:"links"`
+	Name                string             `json:"stack_name"`
+	NotificationTopics  []interface{}      `json:"notification_topics"`
+	Parameters          map[string]string  `json:"parameters"`
+	Resources           []interface{}      `json:"resources"`
+	TemplateDescription string             `json:"template_description"`
+	Timeout             int                `json:"timeout_mins"`
+	UpdatedTime         time.Time          `json:"-"`
+}
+
+func (r *PreviewedStack) UnmarshalJSON(b []byte) error {
+	type tmp PreviewedStack
+	var s struct {
+		tmp
+		CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+		UpdatedTime  gophercloud.JSONRFC3339NoZ `json:"updated_time"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = PreviewedStack(s.tmp)
+
+	r.CreationTime = time.Time(s.CreationTime)
+	r.UpdatedTime = time.Time(s.UpdatedTime)
+
+	return nil
 }
 
 // PreviewResult represents the result of a Preview operation.
diff --git a/openstack/orchestration/v1/stacks/testing/fixtures.go b/openstack/orchestration/v1/stacks/testing/fixtures.go
index 2afbed2..f3e3b57 100644
--- a/openstack/orchestration/v1/stacks/testing/fixtures.go
+++ b/openstack/orchestration/v1/stacks/testing/fixtures.go
@@ -61,7 +61,7 @@
 		},
 		StatusReason: "Stack CREATE completed successfully",
 		Name:         "postman_stack",
-		CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
+		CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
 		Status:       "CREATE_COMPLETE",
 		ID:           "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
 		Tags:         []string{"rackspace", "atx"},
@@ -76,8 +76,8 @@
 		},
 		StatusReason: "Stack successfully updated",
 		Name:         "gophercloud-test-stack-2",
-		CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 11, 17, 39, 16, 0, time.UTC)),
-		UpdatedTime:  gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC)),
+		CreationTime: time.Date(2014, 12, 11, 17, 39, 16, 0, time.UTC),
+		UpdatedTime:  time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC),
 		Status:       "UPDATE_COMPLETE",
 		ID:           "db6977b2-27aa-4775-9ae7-6213212d4ada",
 		Tags:         []string{"sfo", "satx"},
@@ -158,7 +158,7 @@
 	StatusReason: "Stack CREATE completed successfully",
 	Name:         "postman_stack",
 	Outputs:      []map[string]interface{}{},
-	CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
+	CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
 	Links: []gophercloud.Link{
 		{
 			Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
@@ -256,7 +256,7 @@
 		"OS::stack_id":   "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
 	},
 	Name:         "postman_stack",
-	CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
+	CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
 	Links: []gophercloud.Link{
 		{
 			Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
diff --git a/openstack/sharedfilesystems/v2/securityservices/results.go b/openstack/sharedfilesystems/v2/securityservices/results.go
index 746b2b3..6874208 100644
--- a/openstack/sharedfilesystems/v2/securityservices/results.go
+++ b/openstack/sharedfilesystems/v2/securityservices/results.go
@@ -1,6 +1,11 @@
 package securityservices
 
-import "github.com/gophercloud/gophercloud"
+import (
+	"encoding/json"
+	"time"
+
+	"github.com/gophercloud/gophercloud"
+)
 
 // SecurityService contains all the information associated with an OpenStack
 // SecurityService.
@@ -28,9 +33,28 @@
 	// The security service host name or IP address
 	Server string `json:"server"`
 	// The date and time stamp when the security service was created
-	CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+	CreatedAt time.Time `json:"-"`
 	// The date and time stamp when the security service was updated
-	UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	UpdatedAt time.Time `json:"-"`
+}
+
+func (r *SecurityService) UnmarshalJSON(b []byte) error {
+	type tmp SecurityService
+	var s struct {
+		tmp
+		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+		UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = SecurityService(s.tmp)
+
+	r.CreatedAt = time.Time(s.CreatedAt)
+	r.UpdatedAt = time.Time(s.UpdatedAt)
+
+	return nil
 }
 
 type commonResult struct {
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/results.go b/openstack/sharedfilesystems/v2/sharenetworks/results.go
index 1eb64bc..6762ef2 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/results.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/results.go
@@ -1,8 +1,10 @@
 package sharenetworks
 
 import (
+	"encoding/json"
 	"net/url"
 	"strconv"
+	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -34,9 +36,28 @@
 	// The Share Network description
 	Description string `json:"description"`
 	// The date and time stamp when the Share Network was created
-	CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+	CreatedAt time.Time `json:"-"`
 	// The date and time stamp when the Share Network was updated
-	UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	UpdatedAt time.Time `json:"-"`
+}
+
+func (r *ShareNetwork) UnmarshalJSON(b []byte) error {
+	type tmp ShareNetwork
+	var s struct {
+		tmp
+		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+		UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = ShareNetwork(s.tmp)
+
+	r.CreatedAt = time.Time(s.CreatedAt)
+	r.UpdatedAt = time.Time(s.UpdatedAt)
+
+	return nil
 }
 
 type commonResult struct {
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
index 0b28623..46c2d92 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
@@ -4,7 +4,6 @@
 	"testing"
 	"time"
 
-	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/sharenetworks"
 	"github.com/gophercloud/gophercloud/pagination"
 	th "github.com/gophercloud/gophercloud/testhelper"
@@ -63,7 +62,7 @@
 		{
 			ID:              "32763294-e3d4-456a-998d-60047677c2fb",
 			Name:            "net_my1",
-			CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 57, 13, 0, time.UTC)),
+			CreatedAt:       time.Date(2015, 9, 4, 14, 57, 13, 0, time.UTC),
 			Description:     "descr",
 			NetworkType:     "",
 			CIDR:            "",
@@ -72,13 +71,13 @@
 			NeutronSubnetID: "53482b62-2c84-4a53-b6ab-30d9d9800d06",
 			IPVersion:       0,
 			SegmentationID:  0,
-			UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(nilTime),
+			UpdatedAt:       nilTime,
 			ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 		},
 		{
 			ID:              "713df749-aac0-4a54-af52-10f6c991e80c",
 			Name:            "net_my",
-			CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC)),
+			CreatedAt:       time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC),
 			Description:     "desecr",
 			NetworkType:     "",
 			CIDR:            "",
@@ -87,13 +86,13 @@
 			NeutronSubnetID: "53482b62-2c84-4a53-b6ab-30d9d9800d06",
 			IPVersion:       0,
 			SegmentationID:  0,
-			UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(nilTime),
+			UpdatedAt:       nilTime,
 			ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 		},
 		{
 			ID:              "fa158a3d-6d9f-4187-9ca5-abbb82646eb2",
 			Name:            "",
-			CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 51, 41, 0, time.UTC)),
+			CreatedAt:       time.Date(2015, 9, 4, 14, 51, 41, 0, time.UTC),
 			Description:     "",
 			NetworkType:     "",
 			CIDR:            "",
@@ -102,7 +101,7 @@
 			NeutronSubnetID: "",
 			IPVersion:       0,
 			SegmentationID:  0,
-			UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(nilTime),
+			UpdatedAt:       nilTime,
 			ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 		},
 	}
@@ -150,7 +149,7 @@
 	expected := sharenetworks.ShareNetwork{
 		ID:              "7f950b52-6141-4a08-bbb5-bb7ffa3ea5fd",
 		Name:            "net_my1",
-		CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 56, 45, 0, time.UTC)),
+		CreatedAt:       time.Date(2015, 9, 4, 14, 56, 45, 0, time.UTC),
 		Description:     "descr",
 		NetworkType:     "",
 		CIDR:            "",
@@ -159,7 +158,7 @@
 		NeutronSubnetID: "53482b62-2c84-4a53-b6ab-30d9d9800d06",
 		IPVersion:       0,
 		SegmentationID:  0,
-		UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(nilTime),
+		UpdatedAt:       nilTime,
 		ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 	}
 
@@ -179,7 +178,7 @@
 	expected := sharenetworks.ShareNetwork{
 		ID:              "713df749-aac0-4a54-af52-10f6c991e80c",
 		Name:            "net_my2",
-		CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC)),
+		CreatedAt:       time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC),
 		Description:     "new description",
 		NetworkType:     "",
 		CIDR:            "",
@@ -188,7 +187,7 @@
 		NeutronSubnetID: "new-neutron-subnet-id",
 		IPVersion:       4,
 		SegmentationID:  0,
-		UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC)),
+		UpdatedAt:       time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC),
 		ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 	}
 
@@ -214,7 +213,7 @@
 	expected := sharenetworks.ShareNetwork{
 		ID:              "713df749-aac0-4a54-af52-10f6c991e80c",
 		Name:            "net_my2",
-		CreatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC)),
+		CreatedAt:       time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC),
 		Description:     "new description",
 		NetworkType:     "",
 		CIDR:            "",
@@ -223,7 +222,7 @@
 		NeutronSubnetID: "",
 		IPVersion:       4,
 		SegmentationID:  0,
-		UpdatedAt:       gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC)),
+		UpdatedAt:       time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC),
 		ProjectID:       "16e1ab15c35a457e9c2b2aa189f544e1",
 	}
 
diff --git a/openstack/sharedfilesystems/v2/shares/results.go b/openstack/sharedfilesystems/v2/shares/results.go
index aef9f9a..224d1df 100644
--- a/openstack/sharedfilesystems/v2/shares/results.go
+++ b/openstack/sharedfilesystems/v2/shares/results.go
@@ -1,6 +1,9 @@
 package shares
 
 import (
+	"encoding/json"
+	"time"
+
 	"github.com/gophercloud/gophercloud"
 )
 
@@ -60,7 +63,24 @@
 	SnapshotSupport          bool   `json:"snapshot_support"`
 	SourceCgsnapshotMemberID string `json:"source_cgsnapshot_member_id"`
 	// Timestamp when the share was created
-	CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+	CreatedAt time.Time `json:"-"`
+}
+
+func (r *Share) UnmarshalJSON(b []byte) error {
+	type tmp Share
+	var s struct {
+		tmp
+		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
+	}
+	err := json.Unmarshal(b, &s)
+	if err != nil {
+		return err
+	}
+	*r = Share(s.tmp)
+
+	r.CreatedAt = time.Time(s.CreatedAt)
+
+	return nil
 }
 
 type commonResult struct {
diff --git a/openstack/sharedfilesystems/v2/shares/testing/request_test.go b/openstack/sharedfilesystems/v2/shares/testing/request_test.go
index 7735e02..5b700a6 100644
--- a/openstack/sharedfilesystems/v2/shares/testing/request_test.go
+++ b/openstack/sharedfilesystems/v2/shares/testing/request_test.go
@@ -1,12 +1,12 @@
 package testing
 
 import (
-	"github.com/gophercloud/gophercloud"
+	"testing"
+	"time"
+
 	"github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/shares"
 	th "github.com/gophercloud/gophercloud/testhelper"
 	"github.com/gophercloud/gophercloud/testhelper/client"
-	"testing"
-	"time"
 )
 
 func TestCreate(t *testing.T) {
@@ -57,16 +57,15 @@
 			"project": "my_app",
 			"aim":     "doc",
 		},
-		Status:          "available",
-		Description:     "My custom share London",
-		Host:            "manila2@generic1#GENERIC1",
-		HasReplicas:     false,
-		ReplicationType: "",
-		TaskState:       "",
-		SnapshotSupport: true,
-		Name:            "my_test_share",
-		CreatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(
-			2015, time.September, 18, 10, 25, 24, 0, time.UTC)),
+		Status:                   "available",
+		Description:              "My custom share London",
+		Host:                     "manila2@generic1#GENERIC1",
+		HasReplicas:              false,
+		ReplicationType:          "",
+		TaskState:                "",
+		SnapshotSupport:          true,
+		Name:                     "my_test_share",
+		CreatedAt:                time.Date(2015, time.September, 18, 10, 25, 24, 0, time.UTC),
 		ShareProto:               "NFS",
 		VolumeType:               "default",
 		SourceCgsnapshotMemberID: "",