Ho uno scenario in cui dato una data (DateTime
), che data più/meno x
giorni (ottenuto con DateTime.AddDays
) devono aggiungere o sottrarre x
giorni lavorativi, cioè, saltare fine settimana e festivi. Come posso farlo per farlo? Devo implementare la mia versione personale e allegarla a un calendario o qualcosa del genere?C# DateTime per aggiungere/Sottrarre giorni lavorativi
risposta
vorrei suggerire che si deve per la sua attuazione da soli, e lo farei all'interno di un metodo di estensione in questo modo:
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;
}
}
Questo codice genera un'eccezione 'ArgumentOutOfRangeException'. Inoltre non gestisce i giorni negativi. – Kev
Sì, lo so. Questo codice mostra solo il concetto maleducato e deve essere implementato in modo più sofisticato. Penso che ci siano libs pronte per l'uso su codeplex. – sprinter252
Si dovrebbe verificare se il giorno sta lavorando da soli, in quanto classe DateTime non può sapere in quali giorni sarà vacanze di quest'anno :)
Probabilmente si dovrebbe avere un database di vacanze per controllare contro, e se il valore di giorno più/meno x è uguale a un valore nel database aggiungi/sottrai un altro, poiché non tutti hanno le stesse festività.
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);
}
}
ho fatto questo recentemente:
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;
}
Avrete bisogno di controllare il comportamento per tutti i giorni, li aggiungo sempre e solo!
Mi ci è voluto un po 'di tempo per elaborare ... Ho creato un tavolo DB che inserisco in un array con i miei giorni di vacanza. All Credit to Kev (on this post) .. Ho dovuto modificarlo per funzionare come lo è per me.
Nel mio caso, se il primo giorno era un sabato, e il mio workingDayCount = -1, voglio passare giovedì (dato che la mia data non può cadere in un fine settimana o in vacanza ... deve essere un giorno lavorativo .. in questo caso il Venerdì)
codice di Kev potrebbe passare di nuovo una Domenica ... il codice qui sotto lo porterà alla giornata lavorativa precedente (di solito un Venerdì -. a meno che Venerdì è un giorno festivo, quando sarebbe passare indietro Giovedi).
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;
}
Qui è la mia semplice classe Vacanze:
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; }
}
}
Ecco come popolare la matrice:
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;
}
Ho modificato le precedenti risposte ad approcci più funzionali. Ho fornito due soluzioni di seguito, uno utilizzando IEnumerable e uno che utilizza IObservable e le estensioni reattivi
Utilizzando 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;
}
}
Utilizzando 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;
}
}
stavo cercando di aggiungere e sottrarre date saltare fine settimana e questa è la prima voce in Google. Non mi piaceva nessuna delle risposte qui quindi mi aggiungere quella che ho io stesso fatto nel caso in cui qualcuno finisce qui, come me:
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
}
Spero che questo aiuta qualcuno.
semplice soluzione è qui Provalo e godere di codifica
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);
}
}
- 1. Aggiunta giorni lavorativi alla colonna datetime
- 2. Giorni lavorativi in Python
- 3. Ottenere giorni lavorativi usando Javascript
- 4. r - trovare la differenza tra giorni lavorativi
- 5. Datetime in C# aggiungi giorni
- 6. Calcolare il numero di giorni lavorativi tra due giorni
- 7. Come impostare allarmi per i giorni lavorativi in Android
- 8. Julian giorni dalle DateTime
- 9. Come aggiungerei solo giorni lavorativi a un NSDate?
- 10. Come calcolare 8 giorni lavorativi dalla data odierna?
- 11. Trova tre giorni lavorativi precedenti da una determinata data
- 12. Calcolo giorni lavorativi in Oracle SQL (senza funzioni o procedura)
- 13. Rimuovi righe di giorni non lavorativi da dataframe panda
- 14. Il conteggio dei giorni lavorativi tra due serie
- 15. Come calcolare il conteggio dei giorni lavorativi tra due date?
- 16. python 'x giorni fa' a datetime
- 17. Data confronto data: conta la quantità di giorni lavorativi da una data?
- 18. Ottieni valore datetime a partire da X giorni?
- 19. Calcola giorni rimanenti per un compleanno?
- 20. Ottenere giorni lavorativi tra la data di inizio e di fine utilizzando i panda
- 21. Generatore di intervalli di date in Python durante i giorni lavorativi
- 22. Numero panda di giorni lavorativi tra un DatetimeIndex e un Timestamp
- 23. Aggiungere n giorni lavorativi a una determinata data ignorando le festività ei fine settimana in python
- 24. Come aggiungere il numero di giorni in postgreql datetime
- 25. Come sottrarre 30 giorni dal datetime corrente in mysql?
- 26. Analizzare il C# datetime in javascript datetime
- 27. Converti DateTime per MySQL usando C#
- 28. C++ DateTime classe
- 29. settimana dell'anno C# Datetime
- 30. DateTime Confronta C#
Come fai a sapere in quali giorni sono le vacanze? –
si assume che disponga di tali dati – Aks
È possibile estendere il metodo indicato da @Taz per includere le festività. –