2011-01-05 16 views
12

Tengo dos variables DateTime y necesito calcular el número de semanas entre ellas.cómo calcular el número de semanas dado 2 fechas?

¿Cuál es la forma más rápida (y correcta) de hacerlo?

+1

¿Número de semanas completas? Si es así, ¿en qué día comienza la semana? O el número de días de diferencia/7? – Ani

+2

¿Cómo se define * correcto *? ¿Puedes dar algunos ejemplos del resultado esperado para diferentes entradas? –

+0

Verifique amablemente, http://stackoverflow.com/questions/13970641/count-the-number-of-inclusive-dates-covered-by-a-date-period – shankbond

Respuesta

29

Uso TimeSpan:

int weeks = (date1 - date2).TotalDays/7; 
+0

No veo dónde se usa TimeSpan en este ejemplo, ¿me estoy perdiendo algo? –

+1

@Aeron: el resultado de restar fechas el uno del otro es un 'TimeSpan'. – Oded

+0

Hay un error de 1 día por el método anterior. Parece que no incluye ambas fechas. Considere Date1 como el 1 de agosto de 2016 y la segunda fecha como 2 de agosto de 2016. Después de restar obtendrá 1 día, pero en realidad hay dos días. – shankbond

3

puede probar con el siguiente:

DateTime d1 = new DateTime(2006,10,1); 
DateTime d2 = new DateTime(2007,10,15); 

TimeSpan tt = d2 - d1; 
int totalWeeks = tt.Days/7; 

Y si quieres diferencia exacta en la fracción también entonces en lugar de:

int totalWeeks = tt.Days/7; 

uso:

double totalWeeks = tt.TotalDays/7; 
1
(dtTo - dtFrom).TotalDays/7 

dará número de semanas

1
public static int NumberOfWeeks(DateTime dateFrom, DateTime dateTo) 
{ 
    TimeSpan Span = dateTo.Subtract(dateFrom); 

    if (Span.Days <= 7) 
    { 
     if (dateFrom.DayOfWeek > dateTo.DayOfWeek) 
     { 
     return 2; 
     } 

     return 1; 
    } 

    int Days = Span.Days - 7 + (int)dateFrom.DayOfWeek; 
    int WeekCount = 1; 
    int DayCount = 0; 

    for (WeekCount = 1; DayCount < Days; WeekCount++) 
    { 
     DayCount += 7; 
    } 

    return WeekCount; 
} 
+1

gracias por esta validación! –

0

Usted podría intentar algo como:

var d1 = new DateTime(2011, 01, 05); 
var d2 = new DateTime(2010, 01, 05); 

Console.WriteLine((d1 - d2).Days/7); 

Es posible que necesite para redondear el resultado hacia arriba o hacia abajo dependiendo de sus necesidades exactas, sino que deben Haz el truco.

0

No funcionará si intentas dividir en enteros. Debes dividir al doble.

DateTime startDateTime = new DateTime(2010, 8, 1); 
DateTime endDateTime = new DateTime(2010, 8, 28); 
double weeks = (endDateTime - startDateTime).TotalDays/7; 
3

ACTUALIZACIÓN: Pruebe esta biblioteca: http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET El autor ha ido bastante lejos para averiguar todos estos detalles.

No veo una respuesta que realmente defina lo que es una semana.

Aquí está la trampa, no todas las semanas son iguales. Algunos cuentan los lunes, mientras que otros cuentan los jueves.

Tome este mes por ejemplo. Si quiero contar el número de semanas en agosto de 2012 podría hacer algo como:

var date1 = new DateTime(2012,8,1); 
var date2 = new DateTime(2012,8,31); 
var weeks = (date1 - date2).TotalDays/7; 

Por un lado, nos da una .TotalDays dobles: semanas == 4,2857 ...

Podríamos redondo, pero a veces contará más. Otras veces te quedarás corto.

Contando semanas por lo general se basa en la definición de cuándo comienza y termina una semana. Con los objetos DateTime que encontraremos todas las semanas comienza un lunes.

El estándar ampliamente utilizado ISO8601 define una semana a partir del jueves. Entonces el número de semanas entre dos fechas depende de cuántos jueves ocurren.

implementar algo como esto utilizando la clase GregorianCalendar:

using System; 
using System.Globalization; 
using FluentAssertions; 
using NUnit.Framework; 

//...Namespace, test fixture class, etc ... 

     [Test] 
     public void GetMetricsTimesBetween_ReturnsCorrectRange() { 
      DateTime startDate = new DateTime(2012, 8, 1); 
      DateTime endDate = new DateTime(2012, 8, 31); 

      var cal = new GregorianCalendar(); 

      int startWeekNumber = cal.GetWeekOfYear(startDate, 
                CalendarWeekRule.FirstDay,          
                DayOfWeek.Thursday); 
      int endWeekNumber = cal.GetWeekOfYear(endDate, 
               CalendarWeekRule.FirstDay, 
               DayOfWeek.Thursday); 
      int numberOfWeeksInRange = endWeekNumber - startWeekNumber; 

      numberOfWeeksInRange.Should().Be(5); 
     } 

Esto debería dar resultados más fiables.Deberá considerar que este ejemplo supone que estamos contando semanas dentro del mismo año. Con un poco de trabajo extra, que podría ayudar a hacer frente a los cálculos intervalos de fechas que abarcan diferentes años:

[Test] 
public void GetCountOfWeeks() { 
    var startDate = new DateTime(2012, 12, 1); // 4 weeks here 
    var endDate = new DateTime(2014, 1, 10); // 52 in 2013 and 2 weeks in 2014 
    int numberOfWeeksInRange = 0; 

    var cal = new GregorianCalendar(); 

    for (int year = startDate.Year; year <= endDate.Year; year++) 
    { 
     int startWeekNumber = 0; 
     int endWeekNumber= 0; 

     if(year == startDate.Year) { // start date through the end of the year 
      startWeekNumber = cal.GetWeekOfYear(startDate, 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday); 

      endWeekNumber = cal.GetWeekOfYear((
            new DateTime(year + 1, 1, 1).AddDays(-1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      
     } else if(year == endDate.Year) { // start of the given year through the end date 
      startWeekNumber = cal.GetWeekOfYear((new DateTime(year, 1, 1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      

      endWeekNumber = cal.GetWeekOfYear(endDate, 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);     
     } else { // calculate the number of weeks in a full year     
      startWeekNumber = cal.GetWeekOfYear(new DateTime(year, 1, 1), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday); 

      endWeekNumber = cal.GetWeekOfYear((
            new DateTime(year + 1, 1, 1).AddDays(-1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      
     } 

     numberOfWeeksInRange += endWeekNumber - startWeekNumber; 
    } 

    numberOfWeeksInRange.Should().Be(58); 
} 

Esto todavía no es perfecto, pero es más estrecha. El punto aquí es que no es tan simple como lo hacemos si queremos obtener un conteo real de algo así como una "semana" que realmente es más una determinación específica de la localidad que alguna expresión científica estándar como 1 + 1 = 2. Tomar el número total de días y dividir por 7 es tan ambiguo como decir que todos los "días de trabajo" son de 9 a 5 ...

Aquí hay un mejor ejemplo. Todavía podría usar la refactorización, por supuesto, pero maneja los rangos de fechas tanto en el mismo año como en varios años como una extensión de la clase GregorianCalendar:

/// <summary> 
/// Returns the number of weeks between two datetimes 
/// </summary> 
/// <param name="cal"></param> 
/// <param name="startDate"></param> 
/// <param name="endDate"></param> 
/// <returns></returns> 
public static int GetWeeks(this GregorianCalendar cal, 
           CalendarWeekRule weekRule, 
           DayOfWeek dayofWeek, 
           DateTime startDate, 
           DateTime endDate) { 
    int startWeekNumber = 0; 
    int endWeekNumber = 0; 
    int numberOfWeeksInRange = 0; 

    if (startDate.Year == endDate.Year) { 
     startWeekNumber = 0; 
     endWeekNumber = 0; 
     startWeekNumber = cal.GetWeekOfYear(startDate, 
              weekRule, 
              dayofWeek); 

     endWeekNumber = cal.GetWeekOfYear(endDate, 
              weekRule, 
              dayofWeek); 

     numberOfWeeksInRange = endWeekNumber - startWeekNumber; 

    } 
    else { // calculate per year, inclusive 
     for (int year = startDate.Year; year <= endDate.Year; year++) { 
      startWeekNumber = 0; 
      endWeekNumber = 0; 

      if (year == startDate.Year) { // start date through the end of the year 
       startWeekNumber = cal.GetWeekOfYear(startDate, weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear((new DateTime(year + 1, 1, 1).AddDays(-1)), 
        weekRule, dayofWeek); 
      } 
      else if (year == endDate.Year) { // start of the given year through the end date 
       startWeekNumber = cal.GetWeekOfYear((new DateTime(year, 1, 1)), 
        weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear(endDate, 
        weekRule, dayofWeek); 
      } 
      else { // calculate the total number of weeks in this year     
       startWeekNumber = cal.GetWeekOfYear(new DateTime(year, 1, 1), 
        weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear((new DateTime(year + 1, 1, 1).AddDays(-1)), 
        weekRule, dayofWeek; 
      } 
      numberOfWeeksInRange += endWeekNumber - startWeekNumber; 
     } 
    } 

    return numberOfWeeksInRange; 
} 
Cuestiones relacionadas