2011-01-05 38 views
37

ekleyebilir veya x iş günü çıkarma, yani hafta sonları ve tatil atlamalısınız (DateTime.AddDays ile elde) bir tarih (DateTime), bu tarih artı/eksi x gün verilen senaryo var/Çıkar Çalışma Günleri ekleme. Bunu yapmak için nasıl alabilirim? Kendi versiyonumu uygulamalı ve takvime mi ekleyeyim?C# DateTime

+3

kodlama zevk burada? –

+0

, bu verilere sahip olduğumu varsayalım – Aks

+0

Tatilleri eklemek için @Taz'ın işaret ettiği yöntemi genişletebilirsiniz. –

cevap

49

sana kendi bunu uygulamak zorunda öneririm, ve bu gibi bir uzantı yöntemi içinde yapardı:

 

public static class DateTimeExtensions 
{ 
    public static DateTime AddWorkdays(this DateTime originalDate, int workDays) 
    { 
     DateTime tmpDate = originalDate; 
     while (workDays > 0) 
     { 
      tmpDate = tmpDate.AddDays(1); 
      if (tmpDate.DayOfWeek < DayOfWeek.Saturday && 
       tmpDate.DayOfWeek > DayOfWeek.Sunday && 
       !tmpDate.IsHoliday()) 
       workDays--; 
     } 
     return tmpDate; 
    } 

    public static bool IsHoliday(this DateTime originalDate) 
    { 
     // INSERT YOUR HOlIDAY-CODE HERE! 
     return false; 
    } 
} 
 
+5

Bu kod, bir 'ArgumentOutOfRangeException 'istisnası atar. Ayrıca olumsuz günleri de işlemez. – Kev

+4

Evet, bunu biliyorum. Bu kod sadece kaba kavramı gösterir ve daha sofistike uygulanmalıdır. Bence, kodeksinde kullanıma hazır lib'lar var. – sprinter252

0

Sen DateTime sınıfı tatilimi bu yıl :) Muhtemelen karşı kontrol etmek tatil Veritabanı olmalıdır

0

olacak günleri bilemez çünkü gün başınıza çalışıp çalışmadığını kontrol edin ve değeri eğer gerektiğini gün artı/eksi x, Veritabanında bir değere eşittir, diğeri de aynı bayramlara sahip olmadığından diğerine ekleme/çıkarma işlemi yapar.

40

Taz'slink dayanarak:

public static class DateTimeExtensions 
{ 
    public static DateTime AddWorkDays(this DateTime date, int workingDays) 
    { 
    int direction = workingDays < 0 ? -1 : 1; 
    DateTime newDate = date; 
    while (workingDays != 0) 
    { 
     newDate = newDate.AddDays(direction); 
     if (newDate.DayOfWeek != DayOfWeek.Saturday && 
      newDate.DayOfWeek != DayOfWeek.Sunday && 
      !newDate.IsHoliday()) 
     { 
     workingDays -= direction; 
     } 
    } 
    return newDate; 
    } 

    public static bool IsHoliday(this DateTime date) 
    { 
    // You'd load/cache from a DB or file somewhere rather than hardcode 
    DateTime[] holidays = 
    new DateTime[] { 
     new DateTime(2010,12,27), 
     new DateTime(2010,12,28), 
     new DateTime(2011,01,03), 
     new DateTime(2011,01,12), 
     new DateTime(2011,01,13) 
    }; 

    return holidays.Contains(date.Date); 
    } 
} 
7

Bunu vermedi Geçenlerde:

private DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays, ICollection<DateTime> holidays) 
{ 
    var futureDate = fromDate; 
    var daterange = Enumerable.Range(1, numberofWorkDays * 2); 
    var dateSet = daterange.Select (d => futureDate.AddDays(d)); 
    var dateSetElim = dateSet.Except(holidays).Except(dateSet.Where(s =>s.DayOfWeek == DayOfWeek.Sunday).Except(dateSet.Where (s=>s.DayOfWeek==DayOfWeek.Saturday))); 

    //zero-based array 
    futureDate = dateSetElim.ElementAt(numberofWorkDays-1); 
    return futureDate; 
} 

Sen davranışını kontrol etmek gerekir -gün günler için, sadece hepsini ekliyorum!

2

Bunu yapmak biraz zamanımı aldı ... Tatil günlerimle bir diziye girdiğim bir DB tablosu oluşturdum. All Credit to Kev (on this post) .. İşini benim için olduğu gibi değiştirmek zorundaydım.

Benim durumumda, eğer ilk gün bir cumartesiyse ve benim workDayCount = -1 ise, perşembe günü geri dönmek istiyorum (tarihim bir hafta sonu ya da bir tatile denk gelemeyeceği için ... bir iş günü olmalı .. bu durumda cuma.)

Kev'ın kodu bir Pazar günü geri dönebilir ... aşağıdaki kod, bir önceki işgününe (genellikle bir cuma) - Cuma günü tatil olmadığı sürece, Perşembe günü geri geldiğinde). İşte

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace Clarity.Utilities 
{ 
    public class Holidays 
    { 
     public int Id { get; set; } 
     public DateTime dtHoliday { get; set; } 
     public string Desc { get; set; } 
     public bool Active { get; set; } 

    } 
} 

diziyi yerleştirmek için nasıl:

private Holidays[] PopulateArrayWithDates() 
    { 
     SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConn"].ConnectionString); 
     DateTime[] dtHolidays = new DateTime[] { }; 
     string sql = @"SELECT HolDate, HolName FROM [Server].DBName.dbo.tblHolidays"; 
     SqlCommand ADDCmd = new SqlCommand(sql, con); 
     DataTable table = new DataTable(); 
     DataTable tbl = new DataTable(); 
     Utilities.Holidays[] allRecords = null; 

     using (var command = new SqlCommand(sql, con)) 
     { 
      con.Open(); 
      using (var reader = command.ExecuteReader()) 
      { 
       var list = new List<Holidays>(); 
       while (reader.Read()) 
        list.Add(new Holidays { dtHoliday = reader.GetDateTime(0), Desc = reader.GetString(1) }); 
       allRecords = list.ToArray(); 
      } 
     } 
     return allRecords; 
    } 
0

önceki cevapları daha fonksiyonel yaklaşımlar değiştirdiniz

public static DateTime AddWorkDays(this DateTime date, int workingDays, params Holidays[] bankHolidays) 
    { 
     int direction = workingDays < 0 ? -1 : 1; 
     DateTime newDate = date; 
     // If a working day count of Zero is passed, return the date passed 
     if (workingDays == 0) 
     { 

      newDate = date; 
     } 
     else 
     { 
      while (workingDays != -direction) 
      { 
       if (newDate.DayOfWeek != DayOfWeek.Saturday && 
        newDate.DayOfWeek != DayOfWeek.Sunday && 
        Array.IndexOf(bankHolidays, newDate) < 0) 
       { 
        workingDays -= direction; 
       } 
       // if the original return date falls on a weekend or holiday, this will take it to the previous/next workday, but the "if" statement keeps it from going a day too far. 

       if (workingDays != -direction) 
       { newDate = newDate.AddDays(direction); } 
      } 
     } 
     return newDate; 
    } 

İşte benim basit Tatiller sınıftır. Bir Ben hafta sonları atlama tarihleri ​​toplayıp çıkarmada arıyordu ve IEnumerable

public static class DateTimeExtensions 
{ 
    public static DateTime AddWorkDays(this DateTime date, int workingDays) 
    { 
     return date.GetDates(workingDays < 0) 
      .Where(newDate => 
       (newDate.DayOfWeek != DayOfWeek.Saturday && 
       newDate.DayOfWeek != DayOfWeek.Sunday && 
       !newDate.IsHoliday())) 
      .Take(Math.Abs(workingDays)) 
      .Last(); 
    } 

    private static IEnumerable<DateTime> GetDates(this DateTime date, bool isForward) 
    { 
     while (true) 
     { 
      date = date.AddDays(isForward ? -1 : 1); 
      yield return date; 
     } 
    } 

    public static bool IsHoliday(this DateTime date) 
    { 
     return false; 
    } 
} 
1

kullanma IObservable

public static class DateTimeExtensions 
{ 
    public static DateTime AddWorkDays(this DateTime date, int workingDays) 
    { 
     return Observable 
      .Generate 
       (date, arg => true, arg => arg.AddDays(workingDays < 0 ? -1 : 1), arg => arg) 
      .Where(newDate => 
       (newDate.DayOfWeek != DayOfWeek.Saturday && 
       newDate.DayOfWeek != DayOfWeek.Sunday && 
       !newDate.IsHoliday())) 
      .Take(Math.Abs(workingDays) + 1) 
      .LastAsync() 
      .Wait(); 
    } 

    public static bool IsHoliday(this DateTime date) 
    { 
     return false; 
    } 
} 

kullanma IObservable ve Reaktif Uzantıları

kullanarak IEnumerable ve birini kullanarak, iki çözüm aşağıda vermiş bu, Google’daki ilk girdidir.

public static DateTime AddExcludingWeekends(this DateTime dateTime, int nDays) 
{ 
    var wholeWeeks = nDays/5; //since nDays does not include weekdays every week is considered as 5 days 
    var absDays = Math.Abs(nDays); 
    var remaining = absDays % 5; //results in the number remaining days to add or substract excluding the whole weeks 
    var direction = nDays/absDays;//results in 1 if nDays is posisive or -1 if it's negative 
    while (dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday) 
    dateTime = dateTime.AddDays(direction); //If we are already in a weekend, get out of it 
    while (remaining-- > 0) 
    {//add remaining days... 
    dateTime = dateTime.AddDays(direction); 
    if (dateTime.DayOfWeek == DayOfWeek.Saturday) 
     dateTime = dateTime.AddDays(direction * 2);//...skipping weekends 
    } 
    return dateTime.AddDays(wholeWeeks * 7); //Finally add the whole weeks as 7 days, thus skipping the weekends without checking for DayOfWeek 
} 

Bu kimse yardımcı umut: Birinin benim gibi burada biter ı durumda kendimi bu hale getiren de katacak yüzden burada cevapların hiçbirinde gibi değildi.

0

basit bir çözüm Deneyin ve nasıl günler tatil olan anlarım

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     Double days= 7; 
     string s=DateTime.Now.AddDays(7).ToString("dd/MM/yyyy"); 
     DateTime dt= OrderDeliveryDate(days); 
     Console.WriteLine("dt"+dt.ToString("dd/MM/yyyy")); 


    } 

    public static DateTime OrderDeliveryDate(Double days) 
    { 

     Double count=0; 
     for(int i=0;i<days;i++) 
     { 
      if(DateTime.Now.AddDays(i).DayOfWeek.ToString() == "Saturday") 
      { 
       count= count+1; 
      } 
      else if(DateTime.Now.AddDays(i).DayOfWeek.ToString() == "Sunday") 
      { 
       count=count+1; 
      } 

     } 
     days=days+count; 
     return DateTime.Now.AddDays(days); 
    } 
}