在Groovy中找到本月的第n个工作日

时间:2011-08-23 15:41:56

标签: java date groovy

有没有人知道在Groovy中计算当月第n个工作日的最佳方法?

即。 2011年四月(4)的第7个工作日,即4月11日。

1 个答案:

答案 0 :(得分:6)

我写了quick DSL for working with days(链接的示例显示了英国假期)

使用它来查找(例如)今年9月(2011年)的第5个工作日,你可以这样做:

// 5th weekday in September
println new DateDSL().with {
  every.weekday.in.september( 2011 )
}[ 4 ]

打印

Wed Sep 07 00:00:00 UTC 2011

使用您的示例,您可以:

// 7th Weekday in April
println new DateDSL().with {
  every.weekday.in.april( 2011 )
}[ 6 ]

打印(如你所愿)

Mon Apr 11 00:00:00 UTC 2011

由于你可能没有名字而是一个整数,你可以将函数包装在一个函数中:

// n and month starts from 1 (for first day/month)
Date nthWeekdayInMonth( int n, int month, int year ) {
  new DateDSL().with {
    every.weekday.in."${months[month-1]}"( year )
  }[ n - 1 ]
}

println nthWeekdayInMonth( 7, 4, 2011 )

如果您不想使用它(并且它可能是针对此特定问题的过度使用),您将回到使用Java日历并滚动日期(就像它在dsl的工作中一样)


修改

一个不太复杂的方法可能是创建一个在工作日迭代的类:

class WeekdayIterator {
  private static GOOD_DAYS = [Calendar.MONDAY..Calendar.FRIDAY].flatten()
  private Calendar c = Calendar.instance
  private Date nxt
  private int month, year

  WeekdayIterator( int month, int year ) {
    c.set( year, month, 1 )
    this.month = month
    nxt = nextWeekday()
  }
  private Date nextWeekday() {
    while( c.get( Calendar.MONTH ) == month ) {
      if( c.get( Calendar.DAY_OF_WEEK ) in GOOD_DAYS ) {
        Date ret = c.time.clearTime()
        c.add( Calendar.DATE, 1 )
        return ret
      }
      c.add( Calendar.DATE, 1 )
    }
    null
  }
  Iterator iterator() {
    [ hasNext:{ nxt != null }, next:{ Date ret = nxt ; nxt = delegate.nextWeekday() ; ret } ] as Iterator
  }
}

然后可以这样调用,以便通过以下任一方式获得第7个工作日:

def weekdays = new WeekdayIterator( Calendar.APRIL, 2011 )
println weekdays.collect { it }[ 6 ]

def weekdays = new WeekdayIterator( Calendar.APRIL, 2011 )
println weekdays.iterator()[ 6 ]