2016-04-25 12 views
0

Ich versuche, eine Liste der Daten auf den folgenden Bedingungen zu generieren:Generieren Liste der Daten der folgenden Arbeitswoche

  • Wenn heute Mittwoch ist und nach 06.00 OR ist es nach Mittwoch, dann generiere die nächste Arbeitswoche.

  • Else generieren die aktuelle Arbeitswoche.

Die Arbeitswoche wird als Montag-Freitag definiert.

So weit von googeln und zieht zwei Antworten von hier, habe ich diese Erweiterung, die mir die nächsten auftretenden bestimmten Tag auf den aktuellen Tag basiert gibt:

public static DateTime Next(this DateTime dt, DayOfWeek startoOfWeek) 
{ 
    var start = (int)dt.DayOfWeek; 
    var target = (int)startoOfWeek; 
    if (target <= start) 
    { 
     target += 7; 
    } 
    return dt.AddDays(target - start); 
} 

Gezogen von: How to get the date of the next Sunday?

Und ich auch haben die folgenden Arbeitstage als:

var daysOfWeek = Enum.GetValues(typeof(DayOfWeek)) 
      .OfType<DayOfWeek>() 
      .Skip(1) 
      .TakeWhile(day => day != DayOfWeek.Saturday) 
      .ToList(); 

ich gehe, es zu testen so:

foreach (var day in daysOfWeek) 
{ 
    Debug.WriteLine(DateTime.Now.Next(day).Date.ToString(CultureInfo.CurrentCulture)); 
} 

Seit heute Sonntag ist 4/24/16, ich habe die richtige Ausgabe für die nächste Woche:

> 4/25/2016 0:00:00 
> 4/26/2016 0:00:00 
> 4/27/2016 0:00:00 
> 4/28/2016 0:00:00 
> 4/29/2016 0:00:00 

Aber wenn heute waren sagen Mittwoch 4/27/16, dann bekomme ich:

> 5/2/2016 0:00:00 
> 5/3/2016 0:00:00 
> 5/4/2016 0:00:00 
> 4/28/2016 0:00:00 
> 4/29/2016 0:00:00 

ich bin immer näher, aber ich frage mich, ob es einen einfacheren Weg, als das, was ich bereits getan haben oder wenn es eine Antwort gibt bereits.

+0

Sie dies nicht tun scheinen die Zeitkomponente zu berücksichtigen –

Antwort

0

Das mag wie Overkill erscheinen, aber ich würde es in kleine Funktionen aufteilen. Erstens, für jedes Datum, an einem Wochentag, was ist die vorherige Instanz dieses Wochentags, einschließlich des aktuellen Datums? (Übersetzung - ein Datum gegeben, was ist das Datum des vorherigen Montag, einschließlich dieses Datums, wenn es ein Montag ist?)

Dann, für ein bestimmtes Datum und eine Anzahl von Tagen, was ist der Bereich der Daten?

public static class DateFunctions 
{ 
    public static DateTime GetPreviousInstanceOfWeekDay(DateTime forDate, 
     DayOfWeek dayOfWeek) 
    { 
     return forDate.DayOfWeek >= dayOfWeek 
      ? forDate.AddDays(dayOfWeek - forDate.DayOfWeek).Date 
      : forDate.AddDays(-(7-(dayOfWeek - forDate.DayOfWeek))).Date; 
    } 

    public static IEnumerable<DateTime> GetDateRange(DateTime startDate, int length) 
    { 
     return Enumerable.Range(0, length - 1).Select(x => startDate.Date.AddDays(x)); 
    } 
} 

Der Hauptgrund ist, dass dies die Art von Dingen, die ich nicht erwarten, direkt beim ersten Versuch zu bekommen, und der einfachste Weg, mit einigen Unit-Tests zu überprüfen ist.

[TestMethod] 
public void ReturnsPreviousMondayForGivenThursday() 
{ 
    var monday = DateFunctions.GetPreviousInstanceOfWeekDay(DateTime.Parse("4/21/2016"), 
     DayOfWeek.Monday); 
    Assert.AreEqual(DateTime.Parse("4/18/2016"), monday); 
} 

[TestMethod] 
public void ReturnsPreviousSaturdayForGivenSunday() 
{ 
    var saturday = DateFunctions.GetPreviousInstanceOfWeekDay(DateTime.Parse("4/17/2016"), 
     DayOfWeek.Saturday); 
    Assert.AreEqual(DateTime.Parse("4/16/2016"), saturday); 
} 

[TestMethod] 
public void ReturnsSundayForGivenSunday() 
{ 
    var sunday = DateFunctions.GetPreviousInstanceOfWeekDay(DateTime.Parse("4/24/2016"), 
     DayOfWeek.Sunday); 
    Assert.AreEqual(DateTime.Parse("4/24/2016"), sunday); 
} 

, die auch den Mittwoch/06.00 Scheck getrennt von allen übrigen hält. Diese Funktion kombiniert nur die anderen Funktionen, und die einzige neue Sache, die sie einführt, ist die Logik, um zu überprüfen, ob sie fünf Tage zurückgeben soll, beginnend mit dem vorherigen Montag oder mit dem nächsten Montag. (Ich könnte das sogar in eine separate Funktion bringen. Ein paar zusätzliche Zeilen Code und ein oder zwei Unit-Tests sind großartig für den Seelenfrieden.)

public static IEnumerable<DateTime> GetWeekDaysForCurrentOrNextWeek(DateTime forDate) 
{ 
    //Badly named variable. It's late. 
    var getStartForWeek = forDate.AddHours(6).DayOfWeek > DayOfWeek.Wednesday 
     ? forDate.AddDays(7) : forDate; 
    return 
     DateFunctions.GetDateRange(
     GetPreviousInstanceOfWeekDay(getStartForWeek, DayOfWeek.Monday), 5); 
} 
0

für mich Dies funktioniert:

public static DateTime GetStartOfWorkWeek(this DateTime now) 
{ 
    var monday = now.AddDays(1 - (int)now.DayOfWeek).Date; 
    if (now.Subtract(monday).TotalHours >= 66.0) 
    // 66.0 hours from Midnight Mon to 6pm Wed 
    { 
     monday = monday.AddDays(7.0); 
    } 
    return monday; 
} 

Wenn ich diesen Code ausführen:

var now1 = new DateTime(2016, 4, 27, 17, 59, 0); 
var now2 = new DateTime(2016, 4, 27, 18, 0, 0); 

var monday1 = now1.GetStartOfWorkWeek(); 
var monday2 = now2.GetStartOfWorkWeek(); 

... ich diese Werte erhalten:

 
now1 
2016/04/27 17:59 Wednesday 

monday1 
2016/04/25 00:00 Monday 

now2 
2016/04/27 18:00 Wednesday 

monday2 
2016/05/02 00:00 Monday 
Verwandte Themen