【问题标题】:What is a smarter way to check if a Joda-Time DateTime object does not represent the last day of the year?检查 Joda-Time DateTime 对象是否不代表一年中的最后一天的更聪明的方法是什么?
【发布时间】:2016-11-22 13:41:14
【问题描述】:

我正在使用Joda-Time,我想检查特定日期是否不是一年中的最后一天(换句话说,日期不应该是 31/12/XXXX)。它应该适用于任何一年。

为了实现这个检查,我做了这样的事情:

DateTime dataSecondoMovimento = new DateTime(mappaQuote.get(2).getDatariferimentoprezzo());

if(!(dataSecondoMovimento.getMonthOfYear() == 12 && dataSecondoMovimento.getDayOfMonth() == 31)) {
    System.out.println("It is not the end of year !!!");
}

所以基本上我正在检查月份是否不是 12 月以及日期是否不是 31(两者都必须为真,因为它不是一年中的最后一天)。我认为这应该可以正常工作。

我的问题:Joda-Time 是否提供了一种更简洁的方法?是否存在检查特定日期是否为一年中最后一天的方法?

【问题讨论】:

  • 恕我直言,你的方式是最实用的。我唯一想到的是dataSecondoMovimento.plusDays(1).getDayOfYear() == 1,它更短但几乎没有更有效:)
  • !(month() == 12 && day() == 31) 似乎也不那么直观。 month() != 12 && day() != 31 乍一看更直观。然后我就把它考虑到它自己的方法中来阅读if(isLastDayOfYear(date))

标签: java date datetime jodatime


【解决方案1】:

恕我直言,你的方法很实用。

我唯一想到的是

dataSecondoMovimento.plusDays(1).getDayOfYear() == 1

这更短,但几乎没有更有效

P.S.:我发现这种方法有一个小好处 - 它适用于在最后一个没有 12 个月或 31 天的非公历的不太可能的情况!

【讨论】:

    【解决方案2】:

    DateTime.Property

    如果你想要一些代码接近你用自然语言表达问题的方式,你可以编写一个方法来访问名为dayOfYearDateTime.Property 来询问最大值,这意味着一年的最后一天.

    private boolean isLastDayOfYear(DateTime dateTime) {
        return dateTime.dayOfYear().get() == dateTime.dayOfYear().getMaximumValue();
    }
    

    然后:

    if (!isLastDayOfYear(dataSecondoMovimento)) {
        System.out.println("It is not the end of year !!!");
    }
    

    【讨论】:

      【解决方案3】:

      另一种简单的方法是在您的日期中添加一天,然后检查年份是否已更改:

      DateTime dataSecondoMovimentoPlusOneDay = dataSecondoMovimento.plusDays(1);
      
      boolean yearChanged = dataSecondoMovimento.getYear() != dataSecondoMovimentoPlusOneDay.getYear();
      

      【讨论】:

        【解决方案4】:

        tl;博士

        MonthDay.from( zdt ).equals( 
            MonthDay.of( 
                Month.DECEMBER , 
                Month.DECEMBER.maxLength() 
            )
        )
        

        java.time

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

        其中包括 MonthDay 类,用于表示没有年份的月份中的某天。我们知道一年中的最后一天总是 12 月 31 日。我们为该值设置了一个常数。为了防止愚蠢的错误,我们要求提供月份的长度,而不是硬编码31

        static final public MonthDay MONTHDAY_END_OF_YEAR = MonthDay.of( Month.DECEMBER , Month.DECEMBER.maxLength() );
        

        在 java.time 中与 Joda-Time DateTime 等效的类是 ZonedDateTime

        ZoneId z = ZoneId.of( "America/Montreal" );
        ZonedDateTime zdt = ZonedDateTime.now( z );
        

        询问MonthDay

        MonthDay md = MonthDay.from( zdt );
        

        比较我们的常数。

        Boolean isLastDay = md.equals( MONTHDAY_END_OF_YEAR );
        

        TemporalAdjuster

        顺便说一句,有一个TemporalAdjuster 用于获取一年中的最后一天:TemporalAdjusters.lastDayOfYear()(注意复数“s”)。

        ZoneId z = ZoneId.of( "America/Montreal" );
        ZonedDateTime zdtNow = ZonedDateTime.now( z );
        ZonedDateTime zdtLastDayOfYear = zdtNow.with( TemporalAdjusters.lastDayOfYear() ) ;
        MonthDay mdYearEnd = MonthDay.from( zdtLastDayOfYear );
        

        转储到控制台。

        System.out.println( "zdtNow: " + zdtNow );
        System.out.println( "zdtLastDayOfYear: " + zdtLastDayOfYear );
        System.out.println( "mdYearEnd: " + mdYearEnd );
        

        zdtNow: 2016-11-26T15:44:06.449-05:00[美国/蒙特利尔]

        zdtLastDayOfYear:2016-12-31T15:44:06.449-05:00[美国/蒙特利尔]

        mdYearEnd:--12-31

        live code in IdeOne.com


        关于java.time

        java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

        Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

        要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

        从哪里获得 java.time 类?

        ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

        【讨论】:

          【解决方案5】:

          目前 Joda Time 没有直接实现 getLastDayOfYear(),我们必须使用逻辑方式来处理一年中的最后一天,您可以尝试一种方式,也可以使用以下替代方式

           public int getDayOfYear() { //This is library method
              return getChronology().dayOfYear().get(getMillis());
          }
          
          if(!getDayOfYear() <=365 ||!getDayOfYear() <=366) { //Considering leap year
          System.out.println("It is not the end of year !!!");
          }
          

          【讨论】:

          • 什么?但它不适用于非闰年!例如,此代码将在 2015 年 12 月 31 日写下“这不是年底”。
          • 已修改,现在应该适用于闰年和非闰年
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-03
          • 1970-01-01
          • 1970-01-01
          • 2021-08-17
          • 2010-12-02
          相关资源
          最近更新 更多