J'essaie d'exclure les week-ends dans mon code JavaScript. J'utilise moment.js et j'ai du mal à choisir la bonne variable pour 'jours'.
Jusqu'à présent, j'ai pensé que je devais exclure le jour 6 (samedi) et le jour 0 (dimanche) en modifiant la variable du jour de la semaine pour qu'elle compte uniquement du jour 1 au jour 5. Mais je ne sais pas comment cela change.
Mon jsfiddle est montré ici: FIDDLE
HTML:
<div id="myContent">
<input type="radio" value="types" class="syncTypes" name="syncTypes"> <td><label for="xshipping.xshipping1">Free Shipping: (<span id="fsv1" value="5">5</span> to <span id="fsv2" value="10">10</span> working days)</label> </td><br>
<div id="contacts" style="display:none;border:1px #666 solid;padding:3px;top:15px;position:relative;margin-bottom:25px;">
Contacts
</div>
<input type="radio" value="groups" class="syncTypes" name="syncTypes"> <td><label for="xshipping.xshipping2">Express Shipping: (<span id="esv1" value="3">3</span> to <span id="esv2" value="4">4</span> working days)</label> </td>
<div id="groups" style="display:none;border:1px #666 solid;padding:3px;top:15px;position:relative">
Groups
</div>
</div>
JavaScript:
var a = 5; //Free shipping between a
var b = 10;//and b
var c = 3;//Express shipping between c
var d = 4;//and d
var now = moment();
var f = "Your item will be delivered between " + now.add("days",a).format("Do MMMM") + " and " + now.add("days",b).format("Do MMMM");
var g = "Your item will be delivered between " + now.add("days".c).format("Do MMMM") + " and " + now.add("days",d).format("Do MMMM");
var h = document.getElementById('contacts');
h.innerHTML = g
var i = document.getElementById('groups');
i.innerHTML = f
$(function() {
$types = $('.syncTypes');
$contacts = $('#contacts');
$groups = $('#groups');
$types.change(function() {
$this = $(this).val();
if ($this == "types") {
$groups.slideUp(300);
$contacts.delay(200).slideDown(300);
}
else if ($this == "groups") {
$contacts.slideUp(300);
$groups.delay(200).slideDown(300);
}
});
});
Voici!
function addWeekdays(date, days) {
date = moment(date); // use a clone
while (days > 0) {
date = date.add(1, 'days');
// decrease "days" only if it's a weekday.
if (date.isoWeekday() !== 6 && date.isoWeekday() !== 7) {
days -= 1;
}
}
return date;
}
Vous l'appelez comme ça
var date = addWeekdays(moment(), 5);
J'ai utilisé .isoWeekday
au lieu de .weekday
car cela ne dépend pas de l'environnement local (.weekday(0)
peut être soit le lundi soit le dimanche).
Ne soustrayez pas les jours de la semaine, c.-à-d. addWeekdays(moment(), -3)
sinon cette fonction simple restera en boucle pour toujours!
Mise à jour de JSFiddle http://jsfiddle.net/Xt2e6/39/ (en utilisant différents momentsjs cdn)
Ces solutions en boucle d’itération ne répondaient pas à mes besoins . Elles étaient trop lentes pour un grand nombre . J'ai donc créé ma propre version:
https://github.com/leonardosantos/momentjs-business
J'espère que vous le trouverez utile.
https://github.com/andruhon/moment-weekday-calc plugin for momentJS pourrait être utile pour des tâches similaires
Cela ne résout pas le problème exact, mais il est capable de calculer des jours de semaine spécifiques dans la plage.
Usage:
moment().isoWeekdayCalc({
rangeStart: '1 Apr 2015',
rangeEnd: '31 Mar 2016',
weekdays: [1,2,3,4,5], //weekdays Mon to Fri
exclusions: ['6 Apr 2015','7 Apr 2015'] //public holidays
}) //returns 260 (260 workdays excluding two public holidays)
Je sais que cette question a été postée il y a longtemps, mais au cas où quelqu'un se cognerait dessus, voici une solution optimisée utilisant moment.js:
function getBusinessDays(startDate, endDate){
var startDateMoment = moment(startDate);
var endDateMoment = moment(endDate)
var days = Math.round(startDateMoment.diff(endDateMoment, 'days') - startDateMoment .diff(endDateMoment, 'days') / 7 * 2);
if (endDateMoment.day() === 6) {
days--;
}
if (startDateMoment.day() === 7) {
days--;
}
return days;
}
Si vous voulez une version de l'exemple de code de @ acorio performante (avec l'optimisation de @ Isantos) et pouvant traiter des nombres négatifs, utilisez ceci:
moment.fn.addWorkdays = function (days) {
var increment = days / Math.abs(days);
var date = this.clone().add(Math.floor(Math.abs(days) / 5) * 7 * increment, 'days');
var remaining = days % 5;
while(remaining != 0) {
date.add(increment, 'days');
if(date.isoWeekday() !== 6 && date.isoWeekday() !== 7)
remaining -= increment;
}
return date;
};
Voir Fiddle ici: http://jsfiddle.net/dain/5xrr79h0/
Je suggérerais d'ajouter une fonction au prototype du moment.
Quelque chose comme ça peut-être? (non testé)
nextWeekday : function () {
var day = this.clone(this);
day = day.add('days', 1);
while(day.weekday() == 0 || day.weekday() == 6){
day = day.add("days", 1);
}
return day;
},
nthWeekday : function (n) {
var day = this.clone(this);
for (var i=0;i<n;i++) {
day = day.nextWeekday();
}
return day;
},
Et lorsque vous avez terminé et rédigé certains tests, envoyez une demande de tirage pour obtenir des points bonus.
Si vous voulez une version JavaScript pure (sans compter sur Moment.js), essayez ceci ...
function addWeekdays(date, days) {
date.setDate(date.getDate());
var counter = 0;
if(days > 0 ){
while (counter < days) {
date.setDate(date.getDate() + 1 ); // Add a day to get the date tomorrow
var check = date.getDay(); // turns the date into a number (0 to 6)
if (check == 0 || check == 6) {
// Do nothing it's the weekend (0=Sun & 6=Sat)
}
else{
counter++; // It's a weekday so increase the counter
}
}
}
return date;
}
Vous l'appelez comme ça ...
var date = addWeekdays(new Date(), 3);
Cette fonction vérifie chaque jour suivant si elle tombe un samedi (jour 6) ou un dimanche (jour 0). Si la valeur est true, le compteur n'est pas encore augmenté, mais la date est augmentée ..__ Ce script convient pour de petits incréments de date d'un mois ou moins.
d1 et d2 sont des dates de moment passées en tant qu'argument à calculateBusinessDays
calculateBusinessDays(d1, d2) {
const days = d2.diff(d1, "days") + 1;
let newDay: any = d1.toDate(),
workingDays: number = 0,
sundays: number = 0,
saturdays: number = 0;
for (let i = 0; i < days; i++) {
const day = newDay.getDay();
newDay = d1.add(1, "days").toDate();
const isWeekend = ((day % 6) === 0);
if (!isWeekend) {
workingDays++;
}
else {
if (day === 6) saturdays++;
if (day === 0) sundays++;
}
}
console.log("Total Days:", days, "workingDays", workingDays, "saturdays", saturdays, "sundays", sundays);
return workingDays;
}
const calcBusinessDays = (d1, d2) => {
// Calc all days used including last day ( the +1 )
const days = d2.diff(d1, 'days') + 1;
console.log('Days:', days);
// how many full weekends occured in this time span
const weekends = Math.floor( days / 7 );
console.log('Full Weekends:', weekends);
// Subtract all the weekend days
let businessDays = days - ( weekends * 2);
// Special case for weeks less than 7
if( weekends === 0 ){
const cur = d1.clone();
for( let i =0; i < days; i++ ){
if( cur.day() === 0 || cur.day() === 6 ){
businessDays--;
}
cur.add(1, 'days')
}
} else {
// If the last day is a saturday we need to account for it
if (d2.day() === 6 ) {
console.log('Extra weekend day (Saturday)');
businessDays--;
}
// If the first day is a sunday we need to account for it
if (d1.day() === 0) {
console.log('Extra weekend day (Sunday)');
businessDays--;
}
}
console.log('Business days:', businessDays);
return businessDays;
}