英文:
Java Time in Mills vs Epoch time, and issues with time zones
问题
Epoch时间是通用的,无论你身在何处,纪元时间都将保持不变。
在Java中,你可以使用日历(calendar)、日期(date)和本地日期时间(LocalDateTime)来获取当前时间。
由Java计算的日期和时间的毫秒时间是否在地球上的任何位置都相同?或者它们是否会因你当前所在的时区而不同?
提出这个问题的原因是,我的当前应用程序需要并行处理不同时区的日期。如果我使用特定的时区,应用程序的结果与其他时区的结果不同步。
对于如何解决这个问题,你有什么建议?
例如:假设一个顾客在美国于2020年1月1日购买了一个产品,在服务器的时区中,日期本身是不同的,而在新加坡时区,这笔交易在2019年不会被处理,因为偏移超过了18小时。然而,该交易将会被处理为2018年。
我看到以下可能的解决方案。对于如何进一步进行,你有什么建议?
-> 配置MySQL连接的时区,以确保在处理过程中始终获得正确的日期和时间,以符合交易。但是,这可能对于Windows服务器不起作用。
-> 永久地添加偏移小时和分钟到时间中,这样就不需要在整个代码中进行进一步的计算。
-> 修改整个代码,到处使用时区,并在所有地方使用日期、小时和分钟,以确保你正在处理正确的交易。
英文:
The Epoch time is universal, no matter where you live, the epoch time shall remain the same.
In Java, you can use calendar, date and LocalDateTime to fetch the current time.
Will the Time in Millis for the date and time calculated by java be the same where ever you are on earth? Or will they differ based on the time zone, you are currently in?
The reason for this question being, my current application needs to process dates for different timezones in parallel. If I use a specific zone, the application results are not in sync wrt other time zones.
Any advice on how to solve this issue?
Eg: Say, A customer buys a product in US on 1'st Jan 2020, at 6:00 AM. In server's timezone, the date itself is different and this transaction doesn't get processed in Singapore time zone, for 2019, as the offset is over 18 hours. However, the transaction gets processed for the year 2018.
I see the following possible solutions. Any advice on how to proceed further?
-> Configure the timezone for MySQL connection, to ensure you always have the right date and time as per the transaction while processing. However, this might not function for Windows server.
-> Add the offset hours and minutes to the time, permanently, so, no further calculations are needed throughout the code.
-> Modify the whole code to use timezone everywhere and use the date, hours and minutes everywhere, to ensure you are processing the right transaction.
答案1
得分: 2
我建议:
- 在Java中,使用
Instant
表示时间点。它不依赖于时区(就像纪元时间一样)。它是一个对象,而不是裸的long
值。它以UTC格式打印,这比秒数更可读。 - 在MySQL中,使用
timestamp
数据类型。这是一个以UTC为基准的时间戳,因此也不受数据库服务器或连接的时区影响。
仅对输入和输出进行转换,以便使用ZonedDateTime
表示特定时区的日期和时间。我不记得MySQL JDBC驱动程序是否接受Instant
进行存储;如果不接受,将其转换为UTC的OffsetDateTime
后再进行存储。无论如何,MySQL和JDBC驱动程序都会确保正确存储和检索时间点,这是一个很大的优点。
有了这些建议,您无需为MySQL连接配置特定的时区(如果有人配置了时区,也不会造成任何损害)。您需要为美国、新加坡和其他地方的用户转换输入和输出的日期和时间。这仅影响您的界面,而不影响您的模型。如果代码已经以不同方式编写,这可能需要对现有代码进行更改。
链接:相关问题:用于地理多样化用户的日期操作/存储的Java最佳实践
英文:
I suggest:
- In Java use
Instant
for a point in time. It’s independent of time zone (just like epoch time. It’s an object rather than a nakedlong
value. It prints in UTC, which is more readable than a count of seconds. - In MySQL use the
timestamp
datatype. This is a timestamp in UTC, so also unaffected by the time zone of the database server or connection.
Only for input and output convert to and from a ZonedDateTime
for the date and time in a specific time zone. I don’t remember whether the MySQL JDBC driver accepts an Instant
for storage; if not, convert to an OffsetDateTime
in UTC before storing. MySQL and the JDBC driver will make sure that the correct point in time is stored and retrieved back in any case, which is a great plus.
With these suggestions you don’t need to configure a specific time zone for your MySQL connection (and if someone configures one, no harm is done). You will need to convert dates and times for input and output for users in the USA, Singapore and elsewhere. This affects your interface alone, not your model. And it may entail changes to your existing code base if it is coded differently.
Link: Related question: Java Best Practice for Date Manipulation/Storage for Geographically Diverse Users
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论