如何在Joda时间找到最近一个月的结束日期?

时间:2010-06-14 11:34:51

标签: java datetime jodatime

假设月份结束日期是一个月中的日期,即该月份的最后一个非周末和非假日日期。如何在Joda时间找到最近一个月的结束日期?例如,今天的答案是5月28日星期五,因为那是五月的月末,而五月是最近一个月的结束。

3 个答案:

答案 0 :(得分:5)

DateTime.dayOfMonth.getMaximumValue()给出了该月的最后一天。获取当天的工作日,检查是否在周末。

答案 1 :(得分:3)

一般来说:

  • 查找当月
  • 回去一个月
  • 从该月的最后一天开始:
    • 如果既不是周末也不是假期,那就是结束日期
    • 否则,请回去一天重复

或者也许是:

  • 从今天开始:
    • 如果不是......

这不是最有效的,但是一旦你计算它就缓存它是很便宜的,因为它将在一个月内有效。您可以轻松计算“所有”月末日期并将其存储在查找表中。你肯定想要计算下一个的时间,因为那是当前缓存的值到期时。


实施例

这是我快速炮制的片段:

import org.joda.time.*;

public class LastMonthEnd {
   static int count = 0;
   static boolean isWeekendOrHoliday(DateTime d) {
      return (count++ < 5);
   }
   public static void main(String[] args) {
      DateTime d = new DateTime().minusMonths(1).dayOfMonth().withMaximumValue();
      while (isWeekendOrHoliday(d)) {
         d = d.minusDays(1);
      }
      System.out.println(d);
   }
}

今天(2010-06-14 12:04:57Z),会打印"2010-05-26T12:00:42.702Z"。请注意,isWeekendOrHoliday只是实际实现的存根。我想,真正的考验将会相当复杂(假期部分),并且可能值得一个问题。

答案 2 :(得分:0)

根据您的问题和评论,您正试图解决这样的问题:

  1. 如果今天是工作日,则返回上个月的最后一个工作日
  2. 如果今天不是工作日,那么:
    1. 如果最近的工作日是该月的最后一天,则返回最近的工作日
    2. 否则返回上个月的最后一个工作日
  3. 以下是财务调度库Lamma(http://lamma.io)的实现。方法Date.backward(Calendar)用于查找最近的工作日。

    如果你真的想在Joda中实现,那么你基本上需要自己实现Date.pastMonthEnd()和Date.backward(Calendar)。

    public static void main(String [] args) {
        // print 2014-05-30, because 2014-05-31 is holiday
        System.out.println(findDate(new Date(2014, 5, 31)));
    
        // print 2014-04-30
        System.out.println(findDate(new Date(2014, 5, 30)));
    
        // print 2014-04-30, because the most recent working day of 2014-05-25 is not the last working day of May
        System.out.println(findDate(new Date(2014, 5, 25)));
    }
    
    private static HolidayRule cal = weekends();   // let's use weekend calendar for now
    
    public static Date findDate(Date current) {
        if (cal.isHoliday(current)) {
            Date lastWorkingDayOfThisMonth = current.lastDayOfMonth().backward(cal);
            Date mostRecentWorkingDay = current.backward(cal);
            if (lastWorkingDayOfThisMonth.equals(mostRecentWorkingDay)) {
                return mostRecentWorkingDay;
            } else {
                return lastWorkingDayOfLastMonth(current);
            }
        } else {
            return lastWorkingDayOfLastMonth(current);
        }
    }
    
    public static Date lastWorkingDayOfLastMonth(Date d) {
        return d.lastDayOfPreviousMonth().backward(cal);
    }