简体   繁体   English

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

[英]How can I find the most recent month end date with Joda time?

Say a month end date is the date in a month which is the last non-weekend and non-holiday day in that month. 假设一个月结束日期是一个月中的日期,即该月中的最后一个非周末和非假日日期。 How can I find the most recent past month end date with Joda time? 如何在Joda时间找到最近一个月的结束日期? For example, the answer for today would be Friday 28th May because that was May's month end and May was the most recent month to end. 例如,今天的答案将是5月28日星期五,因为那是五月的月末,而五月是最近一个月的结束。

DateTime.dayOfMonth.getMaximumValue() gives the last day of the month. DateTime.dayOfMonth.getMaximumValue()给出了该月的最后一天。 Get the weekday of that day to check whether it is in the weekend. 获取当天的工作日以检查是否在周末。

Generally speaking: 一般来说:

  • Find current month 查找当前月份
  • Go back a month 回去一个月
  • Start from last day of that month: 从该月的最后一天开始:
    • If it's neither a weekend nor a holiday, that's the end date 如果既不是周末也不是假期,那就是结束日期
    • Otherwise, go back a day and repeat 否则,回去一天再重复一次

Or maybe it's: 或许它是:

  • Start from today: 从今天开始:
    • If it's neither... 如果不是......

This isn't the most efficient, but it's cheap to cache the value once you compute it, because it'll be valid for a whole month. 这不是最有效的,但是一旦你计算它就缓存它是很便宜的,因为它将在一个月内有效。 You can easily compute "all" month end dates and store it in a lookup table too. 您可以轻松计算“所有”月末日期并将其存储在查找表中。 You definitely want to compute when the next one will be, because that's when the current cached value expires. 你肯定想要计算下一个时间,因为那是当前缓存值到期的时候。


Example

Here's a snippet I quickly concocted: 这是我快速炮制的一个片段:

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);
   }
}

Today ( 2010-06-14 12:04:57Z ), this prints "2010-05-26T12:00:42.702Z" . 今天( 2010-06-14 12:04:57Z ),打印出"2010-05-26T12:00:42.702Z" Note that isWeekendOrHoliday is just a stub for an actual implementation. 请注意, isWeekendOrHoliday只是实际实现的存根。 I'd imagine that the real test will be rather complicated (the holiday part), and may be worth a question on its own. 我认为真正的测试将是相当复杂的(假期部分),并且可能值得一个问题。

Based on your question and comments, you are trying to solve problem like this: 根据您的问题和评论,您正试图解决这样的问题:

  1. if today is a working day, then return the last working day of last month 如果今天是工作日,那么返回上个月的最后一个工作日
  2. if today is not a working day, then: 如果今天不是工作日,那么:
    1. if the most recent working day is the last day of the month, return the most recent working day 如果最近的工作日是该月的最后一天,则返回最近的工作日
    2. else return the last working day of last month 否则返回上个月的最后一个工作日

Here is an implementation with financial scheduling library Lamma ( http://lamma.io ). 这是财务调度库Lamma( http://lamma.io )的实现。 The method Date.backward(Calendar) is used to find the most recent working day. Date.backward(Calendar)方法用于查找最近的工作日。

If you really want do implement in Joda, then you basically need to implement Date.pastMonthEnd() and Date.backward(Calendar) by yourself. 如果你真的想在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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM