4 MINDS

Sistema para Gestão de Conhecimento

Dica em Groovy - Buscando os dias que compõem uma semana


Saudações!
Antes de mais nada, assumimos aqui que uma semana vai de segunda até domingo, ok?
O problema que temos pra hoje é esse:
  • Dado um determinado dia, preciso ter todos os dias que estão na semana desse dia. 
Situação muito comum em relatórios onde precisamos fazer consultas para saber dados da semana atual, por exemplo, estamos na quarta-feira e quero saber o fluxo de caixa dessa semana.

Com Groovy, criar esse período de dias é bastante trivial, segue abaixo:

Groovy Code
/**
* @author Alan Rodrigues
* @param java.util.Date - O dia da semana ao qual devemos nos basear
* @return java.util.Map
*  key: String monday - value: Date - o primeiro dia daquela semana
*  key: String sunday - value: Date - o último dia daquela semana
*/
Map criarSemanaDoDia(Date dia) {
    if(!dia) {
        dia = new Date()
    }
    
    def monday = dia
    def sunday = dia
        
    use(groovy.time.TimeCategory) {
        // andamos pra trás até chegar em uma segunda-feira
        while(monday[Calendar.DAY_OF_WEEK] != Calendar.MONDAY) {
            monday = monday - 1.days
        }
        monday = monday.clearTime() // zera o horário
        
        // andamos pra frente até chegar em um domingo
        while(sunday[Calendar.DAY_OF_WEEK] != Calendar.SUNDAY) {
            sunday = sunday + 1.days
        }
        sunday = sunday.clearTime()
        sunday = sunday + 23.hours + 59.minutes + 59.seconds
    }
    
    [monday: monday, sunday: sunday]
}
Teste do código com o dia atual:
Groovy Code
def map = criarSemanaDoDia()
println map // imprime [monday:Mon Dec 01 00:00:00 BRST 2014, sunday:Sun Dec 07 23:59:59 BRST 2014]
Você pode notar que utilizando a excelente groovy.time.TimeCategory e o padrão Pimp my library resolvemos esse problema de forma simples e clara com poucas linhas de código.
Se quisermos iterar por todos dias da semana, podemos fazer assim:
Groovy Code
map.monday.upto(map.sunday){
    println it
}

// imprime
// Mon Dec 01 00:00:00 BRST 2014
// Tue Dec 02 00:00:00 BRST 2014
// Wed Dec 03 00:00:00 BRST 2014
// Thu Dec 04 00:00:00 BRST 2014
// Fri Dec 05 00:00:00 BRST 2014
// Sat Dec 06 00:00:00 BRST 2014
// Sun Dec 07 00:00:00 BRST 2014


O método upto utilizado nesse contexto irá iterar pelos dias da semana:
Com Grails, poderíamos utilizar esse código para coletar consultas entre datas, por exemplo:
Groovy Code
def results = [:]
map.monday.upto(map.sunday){
    results[it] = ClasseDeDominio.executeQuery('from ClasseDeDominio where dateCreated between ? and ? ', [it, it + 1])
}
Espero que a dica tenha sido útil.
Até a próxima