使用客户端的时区将字符串日期转换为Java对象(不含语言环境)

时间:2016-12-20 20:54:23

标签: java date timezone jodatime

我需要为用户在数据库中搜索结果的日期创建一个24小时窗口。用户可以在任何TimeZone中,服务器在PST中,数据库使用mongodb(UTC)。

查找用户发送Wed Dec 21 2016 00:07:11 GMT+0530 (IST)之类的内容,然后服务器创建具有相同日期和时间的new DateTime()(默认情况下不会转换为JVM的时区)

我想到的一个解决方法是在用户的时区中使用TimeAtStartOfDay创建一个日期,并为窗口添加addDays加1。

例如:String date = "Wed Dec 21 2016 00:07:11 GMT+0530 (IST)" convert to "2016-12-21 00:00:00.000Z"注意:服务器在PST中,因此简单的日期对象将无法工作。

如何使用用户的时区(即字符串日期用户传递给BE)在Java中创建Date对象。

1 个答案:

答案 0 :(得分:1)

服务器的JVM当前默认时区应与您的编程无关。始终将可选参数中的所需/预期时区传递给各种方法调用。恕我直言,那些时区参数应该是必需的而不是可选的。

我不知道或不使用MongoDB,但this page表示日期时间值的本机类型是aa 64-bit整数,表示自Unix时代以来milliseconds的数量(1970年1月1日)UTC

仅限日期的值不明确,没有时区的上下文时没有实际意义。对于任何给定的时刻,日期在全球范围内因地区而异。午夜过后几分钟是巴黎法国新的一天,而在加拿大蒙特利尔仍然是“昨天”。

因此,如果需要时区,我们在哪里获得一个?最终,唯一安全可靠的方法是询问用户。以continent/region格式提醒用户proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

在不询问用户的情况下,您只能假设或猜测。有一些方法可以通过JavaScript检测Web应用程序客户端浏览器的当前默认时区。已经多次讨论Stack Overflow,所以搜索。但是您不确定浏览器区域是由用户向您发出查询的。如果您的用户经过适当的培训,可以采用时区或假设UTC。

区域设置 nothing 与时区有关,仅在生成字符串表示时显示。 Locale确定(a)用于翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大小写,标点符号等问题的文化规范。您可以拥有Asia/Kolkata时区,Locale.CANADA_FRENCH演示文稿,或Pacific/Auckland时区,Locale.ITALY演示文稿。因此,语言环境与此问题无关。

LocalDate用于仅限日期的部分。

LocalDate ld = LocalDate.of( 2016 , Month.MARCH , 23 );

提供时区。

ZoneId z = ZoneId.of( "America/Montreal" );

第一时刻开始新的一天。让java.time确定这一点,因为第一个时刻总是时间00:00:00。夏令时(DST)等异常可能会导致不同的开始时间。

ZonedDateTime zdtStart = ld.atStartOfDay( z );

我们需要搜索查询的结束时间。通常在日期时间处理中,我们使用半开放方法,其中开头是包含,而结尾是独占。因此,我们希望一天的查询可以运行,但不包括跟随日的第一个时刻。

ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( z );  // Or, zdtStart.plusDays( 1 )

显然,MondoDB需要我们将其转换为自UTC时代以来的毫秒数。为此,提取Instant

Instant instantStart = zdtStart.toInstant();
Instant instantStop = zdtStop.toInstant();

从那些中提取epoch-count。这可能意味着数据丢失! java.time类以分辨率nanoseconds跟踪值。达到毫秒可能意味着截断一小段时间。

long millisStart = instantStart.toEpochMilli(); // WARNING: possible data loss.
long millisStop = instantStop.toEpochMilli(); // WARNING: possible data loss.