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/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",