gpt4 book ai didi

java - 从时间戳构造java.util.Date对象时发生时区问题

转载 作者:行者123 更新时间:2023-12-01 08:06:32 26 4
gpt4 key购买 nike

我面临时区问题。让我尝试描述一下:

我的Web应用程序和数据库运行在时区(欧洲/马德里,即UTC + 1)与本地时区(印度/加尔各答,即UTC + 5:30)不同的服务器上。

可以说我的当地当前时间是:IST 2014年1月15日星期三14:35:00和
该服务器当前时间为:2014年1月15日星期三CET 2014年,即滞后4:30小时。

现在,当我尝试使用网页(GUI)中的日历选择将日期时间保存在数据库上时,可以说,我选择的日期时间是:Wed Jan 15 18:30:00,要保存的最终日期在DB中成为1月15日星期三14:00:00(请参见滞后时间4:30)。

让我告诉您上述流程的编码部分。

从我的网页日历中选择->将所选日期时间的时间戳(长)传递给我的服务器端控制器->在服务器端后,我正在构造java.util.Date对象并保存到DB,如下所示:

java.util.Date newDt = new java.util.Date(timeStampInMillis);


在这里,timeStampInMillis是我从GUI中选择的日期时间转换而来的。

在这里,它将给定的时间戳保存在该服务器的当前时区(UTC + 01:00)中,这就是保存的日期时间滞后4:30小时的方式。

但是我想保存为原样,即从日历GUI中选择的日期时间。

我有一些解决方案,例如,可以在我的日历GUI中传递所选日期时间的String表示形式,然后解析格式并保存到DB中,而不是通过时间戳在服务器端控制器中构造Date对象。

但是我想知道我是否可以使用Timezone API做任何事情。

希望我的问题对您清楚。如果没有,请澄清您的疑问。

需要你的帮助...

谢谢。

最佳答案

不清楚的问题

您的问题可能会写得更好。您应该尝试将其缩小为非常具体的示例。您甚至都没有指定讨论中的毫秒值。

服务器时间

几乎应始终将服务器设置为没有夏令时的UTC / GMT时区。在某些系统(例如Mac OS X)上,这很困难。在这种情况下,将机器的时区设置为“ Atlantic / Reykjavik”,因为冰岛全年都处于UTC / GMT时间,而没有任何夏令时的废话。

避免使用java.util.Date

众所周知,与Java捆绑在一起的java.util.Date和.Calendar类很麻烦。

难点之一是,当Date没有分配时区时,其toString方法在呈现字符串时使用默认时区。因此,对于天真的程序员来说,日期似乎有一个时区,而没有。

使用Java 8捆绑的Joda-Time库或新的java.time。*类。在StackOverflow上搜索两者的许多示例。

全球化思考,本地化呈现

您的大多数业务逻辑和数据库存储都应在UTC / GMT中完成(无时区偏移)。诸如Postgres之类的称职数据库默认情况下会这样做。

通常,仅切换到时区以呈现给用户。

时区

始终指定一个时区。不要依赖默认时区,因为这会导致生产意外或任何机器更改其时区的时间。

避免使用三个字母代码,因为它们既不是标准化的也不是唯一的。使用正确的时区名称。

this one之类的列表中查找您的时区名称(略过时,请阅读详细信息)。我认为您在问题中提到“印度/加尔各答”是不正确的。应该是“亚洲/加尔各答”。

ISO 8601

如果必须serialize,请仅使用ISO 8601格式。这种格式是人类可读,明确且明确定义的。

印度时区示例:2014-01-19T12:38:31 + 05:30

UTC / GMT“ Zulu”的示例:2013-11-22T18:28.023Z

java.sql。*类

使用java.sql。*类通过JDBC与数据库进行通信。

您可以通过传递自1970年开始的毫秒数来构造java.sql.Timestamp对象。在Joda-Time中,调用getMillis获取要传递的值。

避免毫秒

通常,我宁愿避免以毫秒为单位跟踪时间。人们容易陷入麻烦,因为某些系统以秒,毫秒或纳秒为单位来跟踪时间。此外,有许多时代在使用,而不总是1970年第一天的Unix风格。

我尝试通过以下任一方法:


日期时间对象,例如Joda-Time DateTime实例
ISO 8601字符串。


范例程式码

但是,如果您确定毫秒值代表了UTC / GMT自1970年第一天以来的真实毫秒数,请在Joda-Time中使用这种代码。请注意,“ L”将数字标记为长整数。

DateTime dateTime = new DateTime( 1390276603054L );

DateTime dateTimeSpain = dateTime.toDateTime( DateTimeZone.forID( "Europe/Madrid" ) );
DateTime dateTimeIndia = dateTime.toDateTime( DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeUtcGmt = dateTime.toDateTime( DateTimeZone.UTC );

// For database.
java.sql.Timestamp timestamp = new java.sql.Timestamp( dateTimeSpain.getMillis() );


转储到控制台...

System.out.println( "dateTime (default time zone): " + dateTime );
System.out.println( "dateTimeSpain: " + dateTimeSpain );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeUtcGmt: " + dateTimeUtcGmt );
System.out.println( "timestamp: " + timestamp ); // "toString" uses default time zone.


运行时...

dateTime (default time zone): 2014-01-20T19:56:43.054-08:00
dateTimeSpain: 2014-01-21T04:56:43.054+01:00
dateTimeIndia: 2014-01-21T09:26:43.054+05:30
dateTimeUtcGmt: 2014-01-21T03:56:43.054Z
timestamp: 2014-01-20 19:56:43.054




关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧 legacy日期时间类,例如 java.util.DateCalendarSimpleDateFormat

现在位于 Joda-Time中的 maintenance mode项目建议迁移到 java.time类。

要了解更多信息,请参见 Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为 JSR 310

您可以直接与数据库交换java.time对象。使用与 JDBC driver或更高版本兼容的 JDBC 4.2。不需要字符串,不需要 java.sql.*类。

在哪里获取java.time类?


Java SE 8Java SE 9Java SE 10Java SE 11和更高版本-具有捆绑实现的标准Java API的一部分。


Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


大多数java.time功能都被反向移植到 ThreeTen-Backport中的Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于较早的Android(<26), ThreeTenABP项目改编为 ThreeTen-Backport(如上所述)。请参见 How to use ThreeTenABP…



ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuartermore

关于java - 从时间戳构造java.util.Date对象时发生时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21228755/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com