如何传送时间参数到服务端

前言

我所在的项目SM负责扫码支付的处理,所有的数据都存储在 MongoDB 中,因为这段时间的业务发展,数据库越来越大,同时也感觉到了查询的速度越来越慢。
后端同事加班加点变得频繁,使用各种方法来给解决 MongoDB 查询慢的问题,能加索引的加索引,能优化查询语句的优化。
另外公司也请来了一位 MongoDB 的大牛来讲解一些 MongoDB 的最佳体验。
比如我接下来要讲的:时间数据的存储。

服务端的时间类型设置

SM项目是我和另外两个前同事一起搭建起来的,当初的技术选型(Polymer + Golang + MongoDB )对我们来说都是第一次在生产项目上的应用,所以有一些不规范的使用。
比如在时间数据的存储上,我们直接在数据库存储了类似 “YYYY-MM-DD hh:mm:ss” 的字符串。经过大牛的点拨后,我们意识到这是一个非常糟糕的处理方法。

正好最近有个新需求,需要给一个结构体增加时间方面的字段。于是我这么设计了结构体的属性:

1
2
3
4
5
6
7
8
type Agent struct {
...
ContractStartDate *time.Time `bson:"contractStartDate,omitempty" json:"contractStartDate,string"` // 合同开始日期
ContractEndDate *time.Time `bson:"contractEndDate,omitempty" json:"contractEndDate,string"` // 合同结束日期
...
}

注意这里的时间的类型必须定义为指针,所择会出现前端传送空的时间到服务器的时候,服务器自动把时间解析成耶稣诞生的时点了。

存进MongoDB数据库的时间如下所示,自带时区属性,便于项目国际化拓展。

1
2
3
4
5
6
{
...
"contractStartDate" : ISODate("2014-05-01T00:00:00.000+0800"),
"contractEndDate" : ISODate("2017-05-31T00:00:00.000+0800"),
...
}

前端时间传送到服务端的选择

如何将前端的时间参数发送给服务端,并且服务端正确解析呢?

如果是POST请求,并且参数都是放到body里面的话,此时的数据一般是JSON字符串。
JavaScript中的Date类型的数据转成JSON字符串的形式如下。
因为都是符合ISO标准的字符串,服务端是能够正确解析的。

1
2
3
4
5
6
{
...
"contractStartDate":"2016-05-31T16:00:00.000Z",
"contractEndDate":"2016-06-29T16:00:00.000Z",
...
}

如果是GET请求,并且时间参数放在query后面呢?这时候就没有像上面那么简单了,下面这两张图是分别在windows和mac平台上的谷歌浏览器中发起的请求。
可以看到,在两个平台上,JavaScript中的Date对象作为query参数是不一样的,那么问题来了,挖…不,该怎么破?
我这边的建议是使用一些操作时间的类库,比如 momentjs

windows下Chrome浏览器

windows下Chrome浏览器

Mac下Chrome浏览器

Mac下Chrome浏览器