【问题标题】:Java Convert Interval of Days to DatesJava将天数转换为日期
【发布时间】:2016-05-09 20:53:08
【问题描述】:

我的日期格式如下: -dd。 - dd.MM.yyyy

基于此信息,我希望从 date 到 date 收到。

伪代码中的朴素实现是:

  • 将日期分为第一部分和第二部分
  • 为第二部分创建一个 SimpleDateFormat
  • 看一下,第一部分的数字是否高于第二部分的数字。
  • 如果是:
    • 第一个日期递减月份
    • 创建起始日期,其中将包含第一部分的 dd、第二部分的递减月份和第二部分的年份。
  • 如果不是:
    • Create from date 将包含第一部分的 dd 和第二部分的月份和年份。

这个解决方案可能大部分时间都有效,但感觉相当尴尬。没有更好的办法吗?

【问题讨论】:

  • @DROY 不,不是重复的。这个问题是关于一个日期范围,而不是一个日期。此外,这个问题还增加了推断开始日期(仅作为神秘的月份)与停止日期相同的月份还是上个月的挑战。
  • 这是一个不同的问题。我知道如何处理字符串到日期的转换,我希望通过实际提出的伪代码来证明这一点,这可以解决问题。我一直在寻找的是是否有像 Interval 这样的类,它可以接受 dd 这样的格式。 - dd.MM.yyyy 并将提供从日期和到日期。

标签: java date calendar


【解决方案1】:

我建议你检查一下包裹

org.joda.time

尤其是以下类

DateTime 
Period

【讨论】:

    【解决方案2】:

    java.time

    java.time 框架内置于 Java 8 及更高版本中。大部分功能都向后移植到 Java 6 和 7 以及 Android。

    我在这里提供了一些示例代码,但未经测试 - 从未运行。应该会让你朝着正确的方向前进。

    这个问题的两个棘手部分:

    • 年份
      问题说要分配年份。对于 1 月的停止日期,开始日期却是上个月 12 月,情况并非如此。在这种情况下,您需要前一年。解决方案是让 java.time 减去一个月并为您处理一月到十二月的数学运算。
    • 月份长度
      显然,不同的月份有不同的长度,不同的天数。请记住,您不能尝试将日期31 放在四月份。如果您的输入数据始终是干净有效的,并且我们下面的算法是正确的,那么这应该不是问题。不过,我肯定会在下面的示例代码中添加一些异常捕获代码,以捕获任何形成无效日期的尝试。

    我将跳过字符串拆分部分,并假设您有第一部分的数字(日期)和第二部分的日期字符串。

    long dayOfMonth = Long.longValue( "31" );
    

    那个日期不在standard format,所以我们必须指定一个formatting patternLocalDate 表示没有时间和时区的仅日期值。

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd.MM.yyyy" );
    LocalDate stop = LocalDate.parse( "21.05.2016" , formatter );
    

    我们可以提取月份进行比较。

    LocalDate start = null;
    int d = localDate.getDayOfMonth();
    

    进行比较。

    if( dayOfMonth >=d ) { // If start is in previous month…
        start = stop.minusMonths( 1 ).withDayOfMonth( dayOfMonth );
    } else if (dayOfMonth < d ) { // If start is in same month…
        start = stop.withDayOfMonth( dayOfMonth );
    } else {
        // FIXME: handle impossible condition as error. The 'if' statements are flawed.
    }
    

    顺便说一句,这个输入数据的格式很尴尬,坦率地说,很傻。这种宝贵的“聪明”创造了额外的工作,给了混乱和错误的机会,完全没有必要,没有任何好处,让我发疯。如果您对此输入数据有任何控制权,我强烈建议您进行两种可能的更改。

    • 首先,如果在您的应用程序中交换数据,请不要使用字符串。使用对象。上面你已经看到了LocalDate 对象。你可以传递那些。或者甚至定义你自己的类LocalDateRange 来容纳一对LocalDate 对象。或者参见this Question,尤其是this Answer,它谈到了使用Google GuavaRange 来保存LocalDate 对象对。

    • 其次,当您必须将日期时间值序列化为字符串时,请使用标准的ISO 8601 格式。这样的使用很简单,因为 java.time 类在解析/生成字符串时默认使用这些格式。仅日期值应按 YYYY-MM-DD 顺序排列。 date range interval 是一对与斜杠 (SOLIDUS) 匹配的字符串,或者在斜杠不合适时使用一对连字符(例如 Unix 相关文件系统中的文件或文件夹命名)。

    【讨论】:

    • 不幸的是,输入数据超出了我的控制范围,我需要使用它们。我面临的问题是应用程序的外部边界。在应用程序内部,我已经主要使用 Joda 对象进行时间处理。这是非常好的和简洁的答案,但它实际上只是说由于要求而没有更好的方法,这是相当愚蠢的。它确实回答了原始问题,也没有回答,因此我不确定是否应该接受它作为答案。
    猜你喜欢
    • 2018-09-25
    • 2011-04-24
    • 2020-07-24
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多