开发者

Finding the nth business day of the month in Groovy

Does anyone know the b开发者_运维知识库est way to calculate the nth business day of the month in Groovy?

i.e. the 7th business day in April (4), in 2011, would be 11th April.


I wrote a quick DSL for working with days (the linked example shows working out the UK holidays)

Using that, to find (for example) the 5th weekday in September this year (2011), you can do:

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

Which prints

Wed Sep 07 00:00:00 UTC 2011

Using your example, you would do:

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

which prints (as you wanted)

Mon Apr 11 00:00:00 UTC 2011

As you probably don't have the month by name but by an integer, you could wrap the call in a function:

// 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 )

If you don't want t use that (and it is probably over-comlpex for this specific issue), you're back to using a java Calendar and rolling the date (as it does inside the workings of the dsl)


Edit

A less convoluted method might be to create a class which iterates over weekdays like so:

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

This can then be called like this to get the 7th business day by either:

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

or

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜