2011-01-05 26 views
12

Ho due variabili DateTime e ho bisogno di calcolare il numero di settimane tra di loro.come calcolare il numero di settimane date 2 date?

Qual è il modo più veloce (e corretto) per farlo?

+1

Numero di settimane complete? Se è così, in quale giorno inizia la settimana? O numero di giorni di differenza/7? – Ani

+2

Come si definisce * corretto *? Puoi dare alcuni esempi sul risultato atteso per input diversi? –

+0

Si prega di controllare, http://stackoverflow.com/questions/13970641/count-the-number-of-inclusive-dates-covered-by-a-date-period – shankbond

risposta

29

Uso TimeSpan:

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

Non vedo dove TimeSpan viene utilizzato in questo esempio, mi manca qualcosa? –

+1

@Aeron - Il risultato della sottrazione delle date tra loro è un 'TimeSpan'. – Oded

+0

C'è un errore di 1 giorno con il metodo sopra. Sembra che non includa entrambe le date. Considera Data 1 come 1 agosto 2016 e seconda data come 2 agosto 2016. Dopo la sottrazione, ottieni 1 giorno ma in realtà ci sono due giorni. – shankbond

3

si potrebbe provare la seguente:

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

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

E se si desidera differenza esatta della frazione anche allora invece di:

int totalWeeks = tt.Days/7; 

uso:

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

darà il numero di settimane

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

grazie per queste convalide! –

0

Si potrebbe provare qualcosa di simile:

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

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

Potrebbe essere necessario arrotondare il risultato alto o in basso a seconda del vostro requisito esatto ma che dovrebbe fare il trucco.

0

Non funzionerà se si prova a dividere in intero. Devi dividere per raddoppiare.

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

UPDATE: Prova questa libreria: http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET L'autore è andato parecchio per capire tutti questi dettagli.

Non vedo una risposta che definisce realmente cosa sia una settimana.

Ecco il trabocchetto, non tutte le settimane sono uguali. Alcuni contano il lunedì mentre altri contano il giovedì.

Prendi questo mese per esempio. Se voglio contare il numero di settimane nel mese di agosto 2012 Ho potuto fare qualcosa di simile:

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

Per prima cosa, .TotalDays ci dà una doppia: settimane == 4,2857 ...

Potremmo giro, ma a volte conterà oltre. Altre volte non sarai all'altezza.

Le settimane di conteggio di solito si basano sulla definizione di quando una settimana inizia e finisce. Con gli oggetti DateTime troveremo che ogni settimana inizia di lunedì.

Lo standard ISO8601 ampiamente utilizzato definisce una settimana a partire da giovedì. Quindi il numero di settimane tra due date dipende da quanti giovedì si verificano.

implementare qualcosa di simile utilizzando la classe 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); 
     } 

Questo dovrebbe dare risultati più affidabili.Dovrai considerare che questo esempio presuppone che contiamo settimane nello stesso anno. Con un po 'di lavoro extra, si potrebbe aiutare il calcolo far fronte con intervalli di date che abbracciano diversi anni:

[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); 
} 

Questo ancora non è perfetto, ma è più vicino. Il punto è che non è così semplice come si tende a farlo se si vuole ottenere un conteggio reale di qualcosa come una "settimana" che è davvero più una determinazione specifica locale rispetto ad alcune espressioni scientifiche standard come 1 + 1 = 2. Prendendo il numero totale di giorni e dividendo per 7 è ambiguo come dire che tutti i "giorni lavorativi" sono da 9 a 5 ...

Ecco un esempio migliore. È comunque possibile utilizzare il refactoring, naturalmente, ma gestisce gli intervalli di date nello stesso anno e si estende per più anni come estensione della classe 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; 
} 
Problemi correlati