Нахождение n-го рабочего дня месяца в Groovy - PullRequest
3 голосов
/ 23 августа 2011

Кто-нибудь знает, как лучше рассчитать n-й рабочий день месяца в Groovy?

, т. Е. 7-й рабочий день в апреле (4) в 2011 году будет 11 апреля.

1 Ответ

6 голосов
/ 24 августа 2011

Я написал быстрый DSL для работы с днями (связанный пример показывает разработку выходных дней в Великобритании)

Используя это, чтобы найти (например) 5-й день недели в сентябре этого года (2011), вы можете сделать:

// 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 ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...