当前位置: 首页 > 知识库问答 >
问题:

针对地理位置不同的用户的数据处理/存储的Java最佳实践

宇文灿
2023-03-14

我已经阅读了所有关于日期操纵的问答,但似乎没有一个能给我一个满意的答案。

我有一个具有不同地域用户的项目,它在一些类和数据中使用date。事情是,我正在寻找一种有效的方法来操作日期为不同的用户在他们各自的时区,大多数的答案建议使用Joda库的date操作,这是很不理解,因为我仍然没有找到任何操作您不能做的传统Java,所以如果有人可以解释我可以做什么Joda不能做的传统Java,那么我可能会考虑使用它。

我最终找到了使用System.CurrentTimeMillis()将我的日期保存到数据库(任何数据库)中的方法。这将避免我担心什么时区正在使用数据库存储日期。如果我要查询数据库中的特定日期或日期范围,我将使用我要查询的日期long执行查询:

SELECT * FROM table1 WHERE date1>=1476653369000

在检索resultset时,我将使用请求数据的用户的时区将从数据库检索的long值格式化为可读的date

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时,有没有一种方法可以避免担心时区问题呢?

提前道谢。

共有1个答案

那开济
2023-03-14

我读过所有关于日期操纵的问答

不,你肯定没有全部读过。

  • 您应该了解到,遗留的日期-时间类(如java.util.Date&java.util.Calendar)和Joda-Time项目都被java.time类所取代(在“java.time”上搜索的结果为1,890个)。
  • 您将学会不将日期-时间值作为从纪元开始的计数来跟踪。调试和日志记录变得非常困难,因为bug没有被发现,因为人类无法破译长整数作为日期-时间的含义。而且,由于在各种软件项目中使用了许多计数粒度(整秒、毫秒、微秒、纳秒、一整天等等)和至少几十个历元,因此会导致数据的模糊性,而假设会导致错误、曲解和混淆。
  • 您将学会在数据库中使用日期-时间类型来跟踪日期-时间值。
  • 您将学会使用UTC存储日期-时间值。仅在逻辑需要或用户希望显示时调整到时区。“想全局,现局部。”
  • 您将了解到,虽然这是一项大胆的行业优先工作,但遗留的日期-时间类设计欠佳、令人困惑和麻烦。看看Java日期和时间API有什么问题吗?讨论一下。Joda-Time是行业中第一个很好的日期时间库,并启发了它的替换,即Java8和更高版本中内置的Java.time类。

我将稍微简短一些,因为所有这些已经在堆栈溢出上讨论过很多次了。

以协调世界时工作。在Java中,这意味着instant类是常用的。instant类以UTC表示时间线上的一个时刻,分辨率为纳秒(最多为十进制分数的九(9)位)。

Instant instant = Instant.now();

任何重要的数据库(如Postgres)都跟踪UTC中的日期-时间值。您的JDBC驱动程序处理从数据库内部存储的数据转换为Java类型的细节。符合JDBC 4.2及更高版本的JDBC驱动程序可以通过PreparedStatement::SetObject&ResultSet::GetObject方法直接处理java.time类型。

myPreparedStatement.setObject( … , instant );

对于不兼容的驱动程序,回到使用java.sql类型(如java.sql.timestamp)与数据库通信,并通过添加到旧类中的新方法转换为java.time类型。数据库如何处理日期-时间值的内部细节可能与java.time的处理方式有很大不同。在大多数情况下,JDBC驱动程序对您隐藏了所有的细节。但一个关键问题是解析,您应该在数据库中研究它。java.time类以高达纳秒的分辨率处理日期时间,但数据库可能不会。例如,Postgres使用微秒的分辨率。所以来回就意味着数据丢失。您希望在java.time类上使用截断方法来匹配您的数据库。

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) );

所以,不涉及时区。因此不必“在处理数据库日期时担心时区”。

当您希望通过一个区域的挂钟时间的镜头看到同一时刻时,应用ZoneID以获得ZonedDateTime

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );

将分区日期时间返回数据库时,提取即时

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框架内置在Java8和更高版本中。这些类取代了麻烦的旧的遗留日期-时间类,如java.util.date.calendar、&java.text.SimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time。

要了解更多信息,请参阅Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR310。

从哪里获取java.time类?

    null
    null
    null

ThreeTen-Extra项目使用额外的类扩展了java.time。这个项目是将来可能添加java.time的一个试验场。您可以在这里找到一些有用的类,如intervalyearweekyearquard等等。

 类似资料:
  • 问题内容: 如何在Rails 3中存储和处理网站用户的地理位置(经度和纬度),以便它检查是否在每个页面请求中我们已经在该用户的会话中保存了这些详细信息(如果我们正在不保存详细信息,那么我们应该从浏览器中请求用户的位置,然后将这些详细信息存储在会话中)? 问题答案: 根据您的要求,我会说您实际上并不需要ajax,因为大多数处理将使用JS(要求用户访问其位置,解析响应等)完成,因此我将使用JS设置一个

  • 问题内容: 我有一个用Go编写的Web服务,目前我将这个Global包导入到任何地方,其中包含与MongoDB的连接(通过MGO),但是我不得不说这对我来说非常讨厌。在Go中维护与数据源的连接的最佳实践是什么?我来自PHP世界,因此来自Global:S 问题答案: 导入一个将初始化对象导出为包级别变量或通过访问器/初始化程序导出的包没有错。后者也许对古典“ OOP主义者”更具吸引力。

  • 我正在做我的第一个react项目,我有一个问题。 使用,在react中处理和存储数据的最佳方法是什么? 我当前的工作流程: 在 将数据存储在(例如在中作为子对象` 使用控件的属性中的数据,如

  • 问题内容: 我的用户数据库中有一些我希望进行加密的数据。要求时,大多数数据将需要解密,但是也有一些密码可以保持加密(过去我们会使用 pwdcompare, 但我相信现在已经过时了)。 我已经按照这里的步骤进行操作,所以现在我已经成功地加密了我的数据。 我不了解的是在运行时打开主密钥以加密/解密数据的正确方法。如果我想使用存储过程来检索加密的数据,该如何打开主密钥?我是否使用存储的proc参数传递主

  • bugu-mongo支持地理位置数据的存储、索引、查询。相关的类都位于com.bugull.mongo.geo包中。 注意: MongoDB对于地理位置数据,默认使用的是WGS84坐标系。如果你的地理位置数据来源是其他坐标系的,请记得先进行转换。 存储、索引 MongoDB能够存储不同类型的地理位置数据,这些数据都是GeoJSON格式。 目前,bugu-mongo支持: Point LineStr

  • 目前,我的应用程序的某些部分在将大量数据加载到报告表时遇到了速度问题。报告表中的数据是从多个表中提取的,并运行一些复杂的查询,但这是必需的。 除了优化代码,我的问题是,您个人如何处理需要向用户显示的大量数据,最佳实践是什么? 目前我正在处理所有的数据,然后通过javascript库生成数据表。 我知道的事情: 用户不需要一次看到所有数据 用户需要能够搜索所有数据 用户需要能够过滤数据 最好的方法真