Java最佳方式/推荐数据结构,用于表示一个月中的日期,例如,1月1日

时间:2017-05-18 10:05:46

标签: java date

通常有代表一个月的任务,例如

  

一月

,或一个月中的日期,例如

  1月1日

,以通用方式,不指定年份。

警告:捕获的数据(例如,用户选择或其他类型的输入)通常需要存储在DB-SLQ或NoSQ中。然后将其用于报告,例如,使用日期范围聚合。

关于哪种Java数据类型最适合上述场景,是否有任何共识/建议?

我看到以下3个选项:

  1. 使用Java Date,在“0th”年内,例如,1970年1月1日,然后 使用日期操作仅提取必填字段(DAY, MONTH),并删除所有其余部分。 Joda或Java8等库 在这里派上用场保存到DB在这里很简单,尽管如此 程序开销可能非常高。
  2. 使用人为的数据类型(例如ENUM)列出所有月份,或者使用一个月的数值并提供映射,然后进一步解析和敲击以捕获一个月中的一天。映射到DB字段并不困难。
  3. 使用字符串,例如“01月1日”。看起来很简单。
  4. 第2和第3版的编程密集程度可能较低,但另外一个缺点是,在报告中使用此类日期可能很笨拙,因为按时间段汇总并不简单。

    有关上述内容的任何建议/想法吗?

    编辑:

    看起来选项#1是最好的(最灵活,阻力最小,最容易持久化,最适合后续报告)。新的Java库使数据操作和字段提取变得相对轻松。

3 个答案:

答案 0 :(得分:6)

java.time.MonthDay提供了现成的课程,因此您无需创建自己的课程。它还可以与其他java.time功能一起使用,因此这可能是您最好的选择。坚持也应该相当容易。

MonthDay birthday = MonthDay.of(Month.JANUARY, 11);

答案 1 :(得分:2)

自从Java 8以来,您考虑的3个选项已经存在于Month enum

Month month = Month.valueOf("July".toUpperCase());
System.out.println(month);
System.out.println(Month.AUGUST);

答案 2 :(得分:2)

描述java.time类MonthMonthDay的另外两个答案是正确的,并且是明智的。类似的是YearMonth

研究类文档以找到一些方便的方法。例如,Month::getDisplayName本地化了月份的名称。另一个例子,您可以通过将一年传递给方法LocalDate来获取MonthDay的{​​{1}}日期。

避免在java.time包之外找到麻烦的旧日期时间类。这些旧类现在已经遗留下来,完全由java.time类取代。

ISO 8601

对于此类日期时间值的文本表示,请查看ISO 8601标准定义的多种格式。

对于月 - 日,格式为atYear。例如,1月23日是:

  

- 01-23

这些ISO 8601对于系统之间的数据交换特别有用。

在解析/生成字符串时,java.time类默认使用这些标准格式。

--MM-DD

为了向用户展示,您的受众可能会阅读ISO 8601格式。如果没有,您可以从java.time对象生成字符串。使用DateTimeFormatter

MonthDay md = MonthDay.parse( "--01-23" ) ;
String output = md.toString() ;  // --01-23
  

janv。 23

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM dd" , Locale.CANADA_FRENCH ) ; String output = md.format( f );

  

一月23

使用对象,而不是字符串&整数

尽可能使用java.time类中的对象而不是粗字符串和纯粹的整数。

几个月来,请勿使用1-12号码。使用Locale.US而不是3月份的3。使用Month.MARCH生成的04 July对象,而不是7月4日的MonthDay

传递方法参数等对象,而不是传递字符串或数字。使用这些java.time类型在组成类时定义成员字段。

使用这些对象可以带来以下好处:

  • Type-safety
    (避免意外使用"星期二"作为一个月的字符串)
  • 确保有效值
    (没有错误的MonthDay.of( Month.JULY , 4 )月)
  • 使您的代码更具自我记录性,更易于阅读。

JDBC

为了与数据库交换数据,符合JDBC 4.2的JDBC驱动程序可以直接使用java.time类型。拨打:

  • 13
  • PreparedStatement::setObject

不需要使用java.sql类型而不是字符串来获取和存储日期时间值。

至于你的字符串和检索月日值的具体问题,我们遇到了一个问题,因为标准的SQL没有定义这样的类型。我将使用text或varchar类型来存储上面讨论的ISO 8601格式的七个字符的字符串:ResultSet::getObject。调用--MM-DD方法MonthDayparse

这些标准格式在按字母顺序排序时按时间顺序设计。因此,对数据库中的ResultSet进行排序可以很好地查询一系列月 - 日值。