J'ai besoin de trouver 2 implémentations complètes élégantes de
public static DateTime AddBusinessDays(this DateTime date, int days)
{
// code here
}
and
public static int GetBusinessDays(this DateTime start, DateTime end)
{
// code here
}
O (1) préférable (pas de boucles).
EDIT: Par jours ouvrables, j'entends les jours ouvrables (lundi, mardi, mercredi, jeudi, vendredi). Pas de vacances, juste les week-ends exclus.
J'ai déjà des solutions laides qui semblent fonctionner mais je me demande s'il existe des moyens élégants de le faire. Merci
C'est ce que j'ai écrit jusqu'à présent. Cela fonctionne dans tous les cas et fait aussi des négatifs. Encore besoin d'une implémentation GetBusinessDays
public static DateTime AddBusinessDays(this DateTime startDate,
int businessDays)
{
int direction = Math.Sign(businessDays);
if(direction == 1)
{
if(startDate.DayOfWeek == DayOfWeek.Saturday)
{
startDate = startDate.AddDays(2);
businessDays = businessDays - 1;
}
else if(startDate.DayOfWeek == DayOfWeek.Sunday)
{
startDate = startDate.AddDays(1);
businessDays = businessDays - 1;
}
}
else
{
if(startDate.DayOfWeek == DayOfWeek.Saturday)
{
startDate = startDate.AddDays(-1);
businessDays = businessDays + 1;
}
else if(startDate.DayOfWeek == DayOfWeek.Sunday)
{
startDate = startDate.AddDays(-2);
businessDays = businessDays + 1;
}
}
int initialDayOfWeek = (int)startDate.DayOfWeek;
int weeksBase = Math.Abs(businessDays / 5);
int addDays = Math.Abs(businessDays % 5);
if((direction == 1 && addDays + initialDayOfWeek > 5) ||
(direction == -1 && addDays >= initialDayOfWeek))
{
addDays += 2;
}
int totalDays = (weeksBase * 7) + addDays;
return startDate.AddDays(totalDays * direction);
}
AddBusinessDays
mise en œuvre dans la question ci-dessus (qui était en fait une réponse supprimée que j'ai proposé d'annuler; un mod a copié cette réponse à la question à la place): À mon avis, cette solution est meilleure que toutes les réponses jusqu'à présent car c'est la seule celui qui traite correctement les valeurs négatives, samedi et dimanche comme source et n'a pas besoin d'une bibliothèque tierce. (J'ai fait un petit programme pour tester les différentes solutions ici.) Je voudrais seulement ajouterif (businessDays == 0) return startDate;
au début de la méthode pour obtenir le résultat correct pour ce cas de bord également.AddBusinessDays
solution était la plus générale qui fonctionnait dans tous les cas dont j'ai besoin. Je l'ai copié dans l'un de mes projets actuels (après une légère modification et une traduction en C ++), merci pour le code :) Cela a beaucoup aidé car il est étonnamment difficile d'obtenir tous les cas limites.Réponses:
Dernière tentative pour votre première fonction:
La deuxième fonction, GetBusinessDays, peut être implémentée comme suit:
la source
en utilisant Fluent DateTime :
le code interne est le suivant
la source
J'ai créé une extension qui vous permet d'ajouter ou de soustraire des jours ouvrables. Utilisez un nombre négatif de BusinessDays pour soustraire. Je pense que c'est une solution assez élégante. Cela semble fonctionner dans tous les cas.
Exemple:
la source
Pour moi, je devais avoir une solution qui passerait les week-ends et serait négative ou positive. Mon critère était que s'il allait de l'avant et atterrissait un week-end, il devrait avancer jusqu'à lundi. S'il devait rentrer et atterrir un week-end, il devrait passer au vendredi.
Eh bien, vous avez l'idée;)
J'ai fini par écrire cette classe d'extension
Il utilise cette méthode que je pensais utile d'utiliser ailleurs ...
Si vous ne voulez pas vous en soucier, vous pouvez simplement remplacer
if (MyClass.IsBusinessDay(date))
par ifif ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))
Alors maintenant tu peux faire
ou
Voici les résultats de certains tests:
la source
la source
J'arrive en retard pour la réponse, mais j'ai fait une petite bibliothèque avec toute la personnalisation nécessaire pour faire des opérations simples les jours ouvrables ... Je la laisse ici: Gestion des jours ouvrables
la source
La seule vraie solution est de permettre à ces appels d'accéder à une table de base de données qui définit le calendrier de votre entreprise. Vous pouvez le coder pour une semaine de travail du lundi au vendredi sans trop de difficulté, mais la gestion des vacances serait un défi.
Modifié pour ajouter une solution partielle non élégante et non testée:
J'ai également violé l'exigence de non-boucle.
la source
Je ressuscite ce message car aujourd'hui je devais trouver un moyen d'exclure non seulement les samedis et dimanches en semaine, mais aussi les jours fériés. Plus précisément, j'avais besoin de gérer divers ensembles de vacances possibles, notamment:
Finalement, je suis sorti avec l'ensemble suivant de classes d'assistance / d'extensions: bien qu'elles ne soient pas d'une élégance flagrante, car elles utilisent massivement des boucles inefficaces, elles sont assez décentes pour résoudre mes problèmes pour de bon. Je laisse tomber tout le code source ici dans cet article, en espérant qu'il sera également utile à quelqu'un d'autre.
Code source
Informations d'utilisation
Le code est assez explicite, mais voici quelques exemples pour expliquer comment vous pouvez l'utiliser.
Ajoutez 10 jours ouvrables (sautez uniquement les jours de la semaine samedi et dimanche)
Ajoutez 10 jours ouvrables (sautez le samedi, le dimanche et tous les jours fériés en fonction du pays pour 2019)
Ajoutez 10 jours ouvrables (sautez le samedi, le dimanche et tous les jours fériés italiens pour 2019)
Ajoutez 10 jours ouvrables (sautez le samedi, le dimanche, tous les jours fériés italiens et les jours fériés spécifiques à Rome pour 2019)
Les fonctions et exemples de code ci-dessus sont expliqués plus en détail dans cet article de mon blog.
la source
la source
Je voulais un "AddBusinessDays" prenant en charge des nombres négatifs de jours à ajouter, et je me suis retrouvé avec ceci:
Aucune boucle n'est requise, elle devrait donc être raisonnablement rapide même pour les "gros" ajouts.
Cela fonctionne avec des jours exprimés en nombre de jours calendaires depuis l'époque, car cela est exposé par la nouvelle classe JDK8 LocalDate et je travaillais en Java. Cela devrait cependant être simple à adapter à d'autres paramètres.
Les propriétés fondamentales sont que
addDays
renvoie toujours un jour de la semaine, et que pour tousd
etn
,daysBetween(d, addDays(d, n)) == n
Notez qu'en théorie, ajouter 0 jour et soustraire 0 jour devrait être une opération différente (si votre date est un dimanche, ajouter 0 jour devrait vous amener au lundi, et soustraire 0 jour devrait vous amener au vendredi). Comme il n'y a pas de négatif 0 (en dehors de la virgule flottante!), J'ai choisi d'interpréter un argument n = 0 comme signifiant ajouter zéro jour.
la source
Je pense que cela pourrait être un moyen plus simple de GetBusinessDays:
la source
Voici mon code avec la date de départ et la date de livraison chez le client.
Bon codage.
la source
la source
la source
J'espère que cela aide quelqu'un.
la source