在Java中操作和存储日期的最佳实践是什么?

在Java中操作和存储日期的最佳实践是什么?,java,date,Java,Date,操作和存储日期的最佳实践是什么,例如在企业java应用程序中使用GregoriaCalendar 寻找反馈,我将把所有优秀的答案整合成其他人可以使用的最佳实践。为了开始讨论,以下是我的经验: 在为典型的三层Java企业项目创建标准时,我通常建议该项目使用GregoriaCalendar来处理日期。原因是格里高利安历法是任何其他历法实例的事实标准,例如朱利安历法等。它是大多数国家公认的历法,并正确处理闰年等。除此之外,我建议应用程序将其日期存储为UTC,以便您可以轻松执行日期计算,例如查找两个日期

操作和存储日期的最佳实践是什么,例如在企业java应用程序中使用GregoriaCalendar


寻找反馈,我将把所有优秀的答案整合成其他人可以使用的最佳实践。

为了开始讨论,以下是我的经验:

在为典型的三层Java企业项目创建标准时,我通常建议该项目使用GregoriaCalendar来处理日期。原因是格里高利安历法是任何其他历法实例的事实标准,例如朱利安历法等。它是大多数国家公认的历法,并正确处理闰年等。除此之外,我建议应用程序将其日期存储为UTC,以便您可以轻松执行日期计算,例如查找两个日期之间的差异(例如,如果将其存储为EST,则必须考虑日光节约时间)。然后,可以将日期本地化为您需要向用户显示的任何时区,例如,如果您是美国东海岸的一家公司,并且希望在EST中显示您的时间信息,则可以将日期本地化为EST

(与JDK 100%互操作)

Joda Time为Java日期和时间类提供了高质量的替代品。该设计允许使用多个日历系统,同时还提供了一个简单的API

这是一条路要走。为什么?

  • 它有一个比标准日期/时间API更强大、更直观的界面
  • 日期/时间格式没有线程问题。java.text.SimpleDataFormat不是线程安全的(不是很多人知道这一点!)

  • 在某个阶段,Java日期/时间API将被JSR-310所取代。我相信这将基于Joda背后的人所做的工作,因此,您将学习一种将影响新标准Java API的API。

    最佳实践通常是准确地不是根据繁重的日期对象进行思考,而是存储一个时间点。这通常是通过存储一个不受角落情况或潜在解析问题影响的值来实现的。为了做到这一点,人们通常存储从我们称之为历元(1970-01-01)的固定点开始经过的毫秒(或秒)数。这是非常常见的,任何Java API都将始终允许您将任何类型的日期转换为以毫秒表示的自纪元以来的时间

    那是储存用的。例如,如果需要,您还可以存储用户的首选时区

    以毫秒为单位的日期,如:

    System.out.println( System.currentTimeMillis() );
    1264875453
    
    当它显示给最终用户时,它不是很有用,这是理所当然的

    这就是为什么您使用示例Joda time将其转换为一些用户友好的格式,然后再将其显示给最终用户

    您要求提供最佳实践,以下是我的看法:将“日期”对象存储在DB中而不是以毫秒为单位的时间,使用浮点数表示货币金额是正确的

    这通常是一种巨大的代码气味

    所以Java中的Joda time是操纵日期的方法,是的。但是乔达是去商店买约会的方式吗当然不是

    UTC 在时区而不是任何时区中思考、工作和存储数据。将UTC视为一个真实的时间,所有其他时区都只是变化。因此,在编写代码时,请忘记您自己的时区。在UTC中执行业务逻辑、日志记录、数据存储和数据交换。我建议每个程序员在他们的办公桌上保留第二个时钟设置为UTC

    java.time 现代的方式是上课

    上述项目为java.time类提供了灵感,该项目现在处于维护模式,团队建议迁移到java.time类

    该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

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

    从哪里获得java.time类

    • 后来
      • 内置的
      • 标准JavaAPI的一部分,带有捆绑实现
      • Java9添加了一些次要功能和修复
      • 大部分java.time功能都在中向后移植到Java6和Java7
      • 该项目专门针对Android采用了Three Ten Backport(如上所述)
    该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如、、和

    ISO 8601 将日期时间值序列化为文本时,请使用标准

    例如,UTC中的日期时间是
    2016-10-17T01:24:35Z
    ,其中
    Z
    Zulu
    的缩写,表示UTC。对于其他情况,小时和分钟的偏移显示在末尾,例如
    2016-01-23T12:34:56+05:30
    。java.time类扩展了此标准格式,将时区名称(如果已知)附加到方括号中,例如
    2016-01-23T12:34:56+05:30[Asia/Kolkata]

    该标准还有许多其他方便的格式,包括、和

    数据库 对于数据库存储,对日期时间值使用日期时间类型,例如主要是
    日期
    时间
    ,以及带时区的
    时间戳

    让你的孩子来做这个重担。驱动程序处理Java如何处理数据的内部结构和数据库如何处理数据的内部结构之间的中介和调整的细节。但是一定要使用示例数据进行练习,以了解驱动程序和数据库的行为。SQL标准对日期时间处理的定义很少,因此行为差异很大,令人惊讶的是

    如果使用JDBC
    Instant instant = myResultSet.getObject( … );
    myPreparedStatement.setObject( … , instant );
    
    Instant instant = myResultSet.getTimestamp( … ).toInstant();
    myPreparedStatement.setObject( … , java.sql.Timestamp.from( instant ) );
    
    Instant instant = Instant.now();
    
    String output = instant.toString();
    
    ZoneOffset offset = ZoneOffset.ofHoursMinutes( 5 , 30 );
    OffsetDateTime odt = instant.atOffset( offset );
    
    ZoneId z = ZoneId.of( "Asia/Kolkata" );
    ZonedDateTime zdt = instant.atZone( z );
    
    Instant instant = zdt.toInstant();
    
    Locale l = Locale.CANADA_FRENCH ; 
    DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
    String output = zdt.format( f );