适用于地理位置不同的用户的日期操作/存储的Java最佳实践
我已经阅读了关于日期操作的所有其他Q / A,但它们似乎都没有给我满意的答案.
我有一个地理位置不同的用户项目,它在一些类和数据中使用Date.问题是我正在寻找一种有效的方法来操纵各自时区中不同用户的日期,大多数答案建议使用Joda库进行日期操作,这还不太明白因为我还没有找到任何您无法使用传统Java进行操作,因此,如果有人可以解释我使用传统Java无法完成的Joda操作,那么我可以考虑使用它. 我终于开始使用System.currentTimeMillis()将我的日期保存到数据库(任何数据库).这样可以避免让我担心使用数据库存储日期的时区.如果我想查询数据库中的特定日期或日期范围,我会使用我想要查询的日期的长值来执行查询: SELECT * FROM table1 WHERE date1>=1476653369000 在检索ResultSet时,我会使用请求数据的用户的时区将从数据库检索到的long值格式化为可读日期. Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(resultSet.getLong(1)); cal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta")); Date myDate = cal.getTime(); 根据我读过的一些观点,有些人强调说存储System.currentTimeMillis()肯定不是最好的做法,但是,由于某些原因,他们都错过了为什么不推荐这样做.我错过了什么吗?这是否会导致转换的性能问题Long-> Date / Date-> Long?在数据库中使用Long而不是Date时是否有任何用例无法实现?有人可以发布关于此的理由解释吗? 另一方面,假设我继续使用Date值在数据库中存储日期,有没有办法避免在处理数据库Date时担心时区? 提前致谢. 解决方法
不,你当然没有全部阅读. >您可能已经了解到,旧的日期时间类(例如java.util.Date和java.util.Calendar)和Joda-Time项目都被java.time类取代(1,890个结果用于搜索’ java.time’). 我会稍微简短一点,因为所有这些已经在Stack Overflow上已经多次介绍过了. 以UTC工作.在Java中,这意味着通常使用Instant类. Instant instant = Instant.now(); 任何严肃的数据库(如Postgres)都会以UTC格式跟踪日期时间值. JDBC驱动程序处理从数据库内部存储数据转换为Java类型的详细信息.符合JDBC 4.2及更高版本的JDBC驱动程序可以通过PreparedStatement :: setObject& amp;来直接处理java.time类型. ResultSet :: getObject方法. myPreparedStatement.setObject( …,instant ); 对于不兼容的驱动程序,回退到使用java.sql.Timestamp等java.sql类型与数据库通信,并通过添加到旧类的新方法转换为java.time类型.数据库如何处理日期时间值的内部细节可能与java.time的完全不同.在大多数情况下,JDBC驱动程序会隐藏您的所有细节.但是一个关键问题是解决方案,您应该在数据库中学习. java.time类处理日期时间,分辨率最高为nanoseconds,但您的数据库可能不会.例如,Postgres使用microseconds的分辨率.因此来回意味着数据丢失.您希望在java.time类上使用截断方法来匹配您的数据库. myPreparedStatement.setTimestamp( …,java.sql.Timestamp.from( instant ) ); 所以,没有涉及时区.所以没有“担心处理数据库日期时的时区”. 当你想通过区域wall-clock time的镜头看同一时刻时,应用ZoneId获得 ZoneId z = ZoneId.of( "Asia/Kolkata" ); ZonedDateTime zdt = instant.atZone( z ); 将分区日期时间恢复到数据库时,提取Instant. Instant instant = zdt.toInstant(); 请注意,在任何特定时刻,日期和时间在全球各个时区都有所不同.因此,如果确切的时刻很重要,例如合同到期时,请注意使用仅限日期的值.要么使用确切时刻的日期时间值,要么将预期时区与日期一起存储,以便稍后计算确切时刻. LocalDate ld = LocalDate.of( 2016,1,1 ); // Determine the first moment of 2016-01-01 as it happens in Kolkata. ZonedDateTime zdt = ld.atStartOfDay( ZoneId.of( "Asia/Kolkata" ) ); Instant instant = zdt.toInstant(); // Adjust to UTC and store. 关于java.time java.time框架内置于Java 8及更高版本中.这些类取代了麻烦的旧legacy日期时间类,如 Joda-Time项目现在在maintenance mode,建议迁移到java.time. 要了解更多信息,请参阅Oracle Tutorial.并搜索Stack Overflow以获取许多示例和说明.规格是JSR 310. 从哪里获取java.time类? > Java SE 8和SE 9及更高版本 >内置. > Java SE 6和SE 7 >大部分java.time功能都被反向移植到Java 6& 07年7月7日. > Android > ThreeTenABP项目专门针对Android调整了ThreeTen-Backport(如上所述). ThreeTen-Extra项目使用其他类扩展了java.time.该项目是未来可能添加到java.time的试验场.您可以在这里找到一些有用的类,例如 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |