.NET

27 jan, 2012

DateDiff com intervalos escolhidos por você

Publicidade

Olá, caro leitor! Hoje eu gostaria de informar e mostrar como pegar o intervalo de uma data em ano, mês, semanas, dias, horas, minutos, segundos, milisegundos e quarto de tempo. 

Existem vários sistemas, ou aplicativos, que precisam calcular esse tipo de intervalo pelas datas cadastradas e, para minimizar o problema com intervalos, o melhor é criar um método específico que faz o cálculo.

Para começar a construir o método, o primeiro passo pensado foi criar uma classe estática. O retorno deve ser do tipo long, e deve-se enviar um intervalo, com a data inicial e a final.

public static long DateDiff(DateInterval intervalo, DateTime dtInicial, DateTime dtFinal)

Para esse parâmetro de intervalo, foi necessário criar “enum” específico. Você pode gerar outros, se necessário.

public enum DateInterval
{
Day,
DayOfYear,
Hour,
Minute,
Month,
Quarter,
Second,
Weekday,
Year,
Milliseconds
}

Definido o “enum” no início da classe, basta criar o método fazendo as verificações.

public static long DateDiff(DateInterval intervalo, DateTime dtInicial, DateTime dtFinal)
{
if (intervalo == DateInterval.Year)
return dtFinal.Year - dtInicial.Year;
if (intervalo == DateInterval.Month)
return (dtFinal.Month - dtInicial.Month) + (12 * (dtFinal.Year - dtInicial.Year));
TimeSpan ts = dtFinal - dtInicial;

if (intervalo == DateInterval.Day || interval == DateInterval.DayOfYear)
return Round(ts.TotalDays);
if (intervalo == DateInterval.Hour)
return Round(ts.TotalHours);
if (intervalo == DateInterval.Minute)
return Round(ts.TotalMinutes);
if (intervalo == DateInterval.Second)
return Round(ts.TotalSeconds);
if (intervalo == DateInterval.Milliseconds)
return Round(ts.TotalMilliseconds);
if (intervalo == DateInterval.Weekday )
return Round(ts.TotalDays / 7.0);
if (intervalo == DateInterval.Quarter)
{
double d1Quarter = GetYearQuarter(dtInicial.Month);
double d2Quarter = GetYearQuarter(dtFinal.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dtFinal.Year - dtInicial.Year));
return Round(d1 + d2);
}
return 0;
}     

Note que, no decorrer do método, algumas verificações de intervalo foram feitas como ano, mês e os outros colocados no “enum”. Para cada um existe um cálculo específico e inteligente para se obter um melhor funcionamento.

Todo intervalo que precisava ser verificado foi colocado no sistema. Talvez eu precise colocar mais alguns, ou você não precise de todos eles.

No caso de acrescentar outro tipo de intervalo no “enum”, basta adicionar no método e o mesmo não será verificado. Se nenhum intervalo for informado, o retorno é 0.

O cálculo mais difícil é o do quarter, ou um quarto de tempo.

if (intervalo == DateInterval.Quarter)
{
double d1Quarter = GetYearQuarter(dtInicial.Month);
double d2Quarter = GetYearQuarter(dtFinal.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dtFinal.Year - dtInicial.Year));
return Round(d1 + d2);
}

Existe outro método sendo chamado de dentro do quarter, o chamado GetYearQuarter, que pega um quarto do ano.

public static int GetYearQuarter(int month)
{
if (month <= 3)
return 1;
if (month <= 6)
return 2;
if (month <= 9)
return 3;
return 4;
}

Segue todo o código para não ter problemas no momento de uso como guia.

Primeiro passo: gerar enum.

public enum DateInterval
{
Day,
DayOfYear,
Hour,
Minute,
Month,
Quarter,
Second,
Weekday,
Year,
Milliseconds
}

Segundo passo: gerar método quarter.

public static int GetYearQuarter(int month)
{
if (month <= 3)
return 1;
if (month <= 6)
return 2;
if (month <= 9)
return 3;
return 4;
}

Terceiro passo: método Datediff.

public static long DateDiff(DateInterval intervalo, DateTime dtInicial, DateTime dtFinal)
{
if (intervalo == DateInterval.Year)
return dtFinal.Year - dtInicial.Year;
if (intervalo == DateInterval.Month)
return (dtFinal.Month - dtInicial.Month) + (12 * (dtFinal.Year - dtInicial.Year));
TimeSpan ts = dtFinal - dtInicial;

if (intervalo == DateInterval.Day || interval == DateInterval.DayOfYear)
return Round(ts.TotalDays);
if (intervalo == DateInterval.Hour)
return Round(ts.TotalHours);
if (intervalo == DateInterval.Minute)
return Round(ts.TotalMinutes);
if (intervalo == DateInterval.Second)
return Round(ts.TotalSeconds);
if (intervalo == DateInterval.Milliseconds)
return Round(ts.TotalMilliseconds);
if (intervalo == DateInterval.Weekday )
return Round(ts.TotalDays / 7.0);
if (intervalo == DateInterval.Quarter)
{
double d1Quarter = GetYearQuarter(dtInicial.Month);
double d2Quarter = GetYearQuarter(dtFinal.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dtFinal.Year - dtInicial.Year));
return Round(d1 + d2);
}
return 0;
}

Espero ter ajudado e qualquer dúvida pode entrar em contato, ou deixar nos comentários.