在Javascript和MongoDB中使用UTC日期
我在正确使用UTC日期时遇到了一个问题,我想知道是否有一种通用的方法来处理这个问题 基本上,我有一个javascript日期选择器,可以在其中选择日期。例如:在Javascript和MongoDB中使用UTC日期,java,javascript,mongodb,date,momentjs,Java,Javascript,Mongodb,Date,Momentjs,我在正确使用UTC日期时遇到了一个问题,我想知道是否有一种通用的方法来处理这个问题 基本上,我有一个javascript日期选择器,可以在其中选择日期。例如: 2014-10-15 当使用JSON.stringify()将其转换为字符串时,我的结果是: 2014-10-14T22:00:00+0200 我假设这是正确的,因为日期转换为UTC日期 当日期到达我的java(jersey)REST接口时,它看起来如下所示: 2014-10-14T22:00:00.000Z 日期似乎相同,但
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:00.000Z上方的2小时再次表示2014-10-15
我的问题是:
我需要在哪里进行更改以防止这种情况发生
a) 我只在前端使用本地时间,因此mongodb只能转换为UTC。这听起来不太安全,因为我确信当从不同的时区调用客户机时,这会导致问题
b) 我只使用UTC日期,但我需要告诉mongodb该日期已经是UTC,因此无需再次转换
任何帮助都将不胜感激
谢谢,
迈克尔
编辑
我想我现在可能更进一步了。我可以告诉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(或MongoBSON驱动程序)再次将日期转换为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:00:00-0600”,它可能也会把它变成正确的日期
有人能证实这是一条路吗
谢谢 希望这些信息能给你一些帮助 MongoDB数据库不进行转换。它只是假设收到的日期是UTC时间。java驱动程序从date对象获取UTC时间(以毫秒为单位)。以下代码来自mongo-java-driver-2.12.3.jar的basicbonencoder.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代码中新建一个日期对象,并将其保存到数据库中,以检查是否有进一步的转换。(比较时请注意java应用程序的时区)
现在,关键是:如果您得到2014-10-14T22:00:00+0200,那么源代码应该是2014-10-15T00:00:00+0400,或者2014-10-15T02:00:00+0600,等等。这意味着在调用javascript日期选择器和JSON.stringify()之间使用了不同的时区 当您向java应用程序发送字符串“2014-10-14T22:00:00+0200”并由
SimpleDataFormat
解析时,请确保模式与数据一致(使用新的SimpleDataFormat(“yyyy-MM-dd'T'HH:MM:ssz”)。不要忘记最后一个字符z,否则+0200将被删除,字符串的其余部分将根据java应用程序时区进行解析。)
使用SimpleDataFormat
仔细检查输出时,最好创建另一个新的SimpleDataFormat(“yyy-MM-dd'HH:MM:ssz”)来格式化日期对象,然后再将其传递到System.out.print()
,因为它更容易按时区进行比较
如果可能的话,我建议您将UTC毫秒数发送到java应用程序,因为它很容易获取并避免各种转换格式问题 UTC日期令人痛苦。一种选择是将日期传递并存储为“2014-10-14”字符串,否则,您只需非常小心,在每个步骤中,日期都代表该日期的UTC午夜。是的,我也考虑过这一点,但我担心如果我现在不解决此问题,它将在以后的另一个场景中困扰我。我认为我发布的编辑(出于某种原因,我注销了,因此stackoverflow认为社区进行了编辑)可能是解决转换问题的解决方案。。。但不是100%确定。