使用Javascript和MongoDB中的UTC日期
Working with UTC Dates in Javascript and MongoDB
我在正确使用UTC日期时遇到问题,不知道是否有一种常见的方法来处理此问题。
基本上,我有一个javascript日期选择器,可以在其中选择日期。例如:
2014-10-15
当它用JSON.stringify()转换成字符串时,我得到的是:
2014-10-14T22:00:00+0200
我认为这是正确的,因为日期被转换为UTC日期。
当日期到达我的java(jersey)REST接口时,它看起来如下:
2014-10-14T22:00:00.000Z
日期看起来是一样的,但+0200已经不在了。可能是问题的原因。
下一步是将日期保存到我的mongo数据库中,然后该数据库存储如下日期:
2014-10-14 20:00:00.000Z
另外两个小时被取消了,我认为这是因为日期"再次"被转换为UTC。
我现在的问题是,如果我重新加载页面,我的输入字段现在显示:
2014-10-14
而不是2014-10-15。
如果我手动更改数据库中的日期,并再次添加2个小时以"2014-10-14T22:00:00.000Z"结束,则该日期将再次正确显示在前端-该日期现在正确表示为本地时间,因为2014-10-14T22-00:000Z之上的2个小时将使2014-10-15再次出现。
我的问题是:
我需要在哪里进行更改以防止这种情况发生?
a) 我在前端只使用本地时间,所以mongodb只转换为UTC。这对我来说听起来不太安全,因为我确信当从不同时区呼叫客户时,这会引起问题。
b) 我只使用UTC日期,但我需要以某种方式告诉mongodb日期已经是UTC,因此无需再次转换。
如有任何帮助,我们将不胜感激。
谢谢,Michael
编辑
我想我现在可能更进一步了。我可以告诉json反序列化程序可以预期的日期格式。我已将其配置为:
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
如果我手动测试日期格式,我最终会使用
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
System.out.println(sdf.parse("2014-10-14T22:00:00+0200"));
它产生
Tue Oct 14 22:00:00 CEST 2014
因此,难怪mongodb(或mongo-bson驱动程序)再次将日期转换为UTC。
然而,如果我这样做:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // Removed the "Z"
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.parse("2014-10-14T22:00:00+0200"));
它正确地得出:
Wed Oct 15 00:00:00 CEST 2014
当从mongodb驱动程序完成转换时,它可能会再次将其转换为"2014-10-14T22:00:00+0200",这是正确的。
但不确定这是否是最好的方式。。。如果客户日期在另一个时区,我会遇到问题吗?我想不是因为,例如,如果是"2014-10-15T06:0:00-0600",它可能也会把它变成正确的日期。。。
有人能确认这是要走的路吗?
谢谢!
希望这些信息能有所帮助。
MongoDB数据库不进行转换。它只是假设收到的日期是UTC时间。java驱动程序从日期对象获取UTC时间(以毫秒为单位)。以下代码来自mongo-java-driver-2.12.3.jar的BasicBSONEncoder.java。
protected void putDate( String name , Date d ){
_put( DATE , name );
_buf.writeLong( d.getTime() ); // d.getTime() Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
}
如果您对它还有疑问,可以直接用java代码创建一个Date Object,并将其保存到数据库中,以检查是否有进一步的转换。(比较时请注意java应用程序的时区)
现在,重点是:如果您得到2014-10-14T22:00:00+02000,那么源应该是2014-20110-15T000:00:000+0400或201410-15T02:000+0600等。这意味着在调用javascript日期选择器和JSON.stringify()时使用了不同的时区。
当您将字符串"2014-10-14T22:00:00+0200"发送到java应用程序并由SimpleDateFormat
解析时,请确保模式与数据一致(使用新的SimpleDateFormat("yyyy-MM-dd-'TH:MM:ssz")。不要忘记最后一个字符z,否则+0200将被删除,字符串的其余部分将根据java应用程序时区的时区进行解析。)
当使用SimpleDateFormat
对输出进行双重检查时,最好在将日期对象传递给System.out.print()
之前创建另一个新的SimpleDateFormat("yyyy-MM-dd'TH:MM:ssz")来格式化日期对象,因为按时区比较更容易。
如果可能的话,我建议您将UTC毫秒发送到java应用程序,因为它很容易获得并避免各种转换格式问题。
- Javascript格式UTC日期
- Date.js错误地分析了ISO 8601 UTC日期
- Highchart UTC日期始终设置为1970年1月1日
- 如何将 UTC 日期时间(字符串)转换为访问者时区
- 如何转换SalesForce Api提供的UTC日期格式,并使用Google Apps脚本将其转换为本地日期和时间格式
- 将UTC日期从Javascript发送到MVC
- 如何在 JS 中创建 UTC 日期
- JavaScript:如何使用纯Javascript将UTC日期时间转换为EST Hours
- 使用 JavaScript 或 jQuery 将 UTC 日期时间转换为本地日期时间
- 将 UTC 日期格式转换为 JavaScript 格式
- 使用 moment.js 将 UTC 日期更改为本地日期
- 用javascript找出UTC日期整数的年份
- PHP 和 Javascript 之间的 UTC 日期差异
- 在 .NET 和 JavaScript 之间使用 UTC 日期
- 想要显示服务器 UTC 日期时间,而不考虑客户端计算机的日期时间
- CouchDB 按月和年过滤 UTC 日期
- 在 javascript 中对 UTC 日期进行排序
- UTC日期之间的Moment.js差异
- 使用日期对象显示带有UTC日期时间输入的本地时间
- 在网页上将服务器的UTC日期时间转换为本地日期时间