web-dev-qa-db-ja.com

Moment.jsを使用して2つの日付の間の週末を除外する方法

JavaScriptコードで週末を除外しようとしています。私はmoment.jsを使用していますが、「日」に適切な変数を選択するのが困難です。

これまで、曜日変数を変更して1日目から5日目までカウントするだけで、6日目(土曜日)と0日目(日曜日)を除外する必要があると考えてきました。しかし、それがどのように変化するかはわかりません。

私のjsfiddleはここに示されています: [〜#〜] 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);
        }
    });
});
29
tman16

どうぞ!

_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;
}
_

このように呼ぶ

_var date = addWeekdays(moment(), 5);
_

ロケールに依存しないため、.isoWeekday_の代わりに_.weekday_を使用しました(.weekday(0)は月曜日または日曜日のいずれかです)。

平日、つまりaddWeekdays(moment(), -3)を減算しないでください。そうしないと、この単純な関数は永久にループします!

JSFiddleの更新 http://jsfiddle.net/Xt2e6/39/ (異なるmomentjs cdnを使用)

53
acoiro

これらの反復ループソリューションは、私のニーズに合わないでしょう。数が多い場合は遅すぎます。だから私は自分のバージョンを作りました:

https://github.com/leonardosantos/momentjs-business

お役に立てば幸いです。

23
lsantos

https://github.com/andruhon/moment-weekday-calc momentJSのプラグインは、同様のタスクに役立つ場合があります

正確な問題は解決しませんが、範囲内の特定の曜日を計算できます。

使用法:

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)
10

私はこの質問がずっと前に投稿されたことを知っていますが、誰かがこれにぶつかった場合に備えて、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;
}
4
ingbabic

(@Isantosの最適化を使用して)パフォーマンスが高く、負の数を処理できる@acorioのコードサンプルのバージョンが必要な場合は、次のコードを使用します。

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;
};

Fiddle here: http://jsfiddle.net/dain/5xrr79h0/ を参照してください。

4
dain

瞬間プロトタイプに関数を追加することをお勧めします。

たぶんこのような何か? (未テスト)

    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;
    },

そして、あなたがいくつかのテストを書き終えたら、ボーナスポイントのプルリクエストを送ります。

3
Eric Hartford

純粋なJavaScriptバージョン(Moment.jsに依存しない)が必要な場合は、これを試してください...

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;
}

このように呼ぶ...

var date = addWeekdays(new Date(), 3);

この関数は、翌日ごとに土曜日(6日目)または日曜日(0日目)に該当するかどうかを確認します。 trueの場合、カウンターは増加しませんが、日付は増加します。このスクリプトは、1か月以内などの小さな日付の増分に適しています。

1
Tremours

d1およびd2は、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;
}
1
Pekama
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;
}
0
Puzzo