Простой javascript date math ... не совсем - PullRequest
14 голосов
/ 15 июня 2011

Я пытаюсь создать простой сценарий, который дает мне следующую дату переработки, основанную на двухнедельном графике, начинающемся с 6 июля 2011 года. Итак, я создал эту простую функцию ...

    function getNextDate(startDate) {
        if (today <= startDate) {
            return startDate;
        }
        // calculate the day since the start date.
        var totalDays = Math.ceil((today.getTime()-startDate.getTime())/(one_day));
        // check to see if this day falls on a recycle day 
        var bumpDays = totalDays%14;  // mod 14 -- pickup up every 14 days...
        // pickup is today
        if (bumpDays == 0) {
            return today;
        }
        // return the closest day which is in 14 days, less the # of days since the last
        // pick up..
        var ms =  today.getTime() + ((14- bumpDays) * one_day);
        return new Date(ms);
    }

и может называть это как ...

 var today=new Date();
 var one_day=1000*60*60*24;  // one day in milliseconds
 var nextDate = getNextDate(new Date(2011,06,06));

пока все хорошо ... но когда я проецирую "сегодня" на 27.10.2011, я получаю вторник 08.11.2011 в качестве следующей даты вместо среды 11.09.2011 ... Фактически каждый с сегодняшнего дня по 26.10.2011 прогнозируется правильный подбор ... и каждая дата с 27.10.2011 по 28.02.2012 прогнозирует вторник, а не среду. И затем каждая дата с 29.02.2012 (високосный год) по 24.10.2012 (снова хммм октябрь) проецирует среду правильно. Что мне не хватает? Любая помощь будет принята с благодарностью ..

V

Ответы [ 3 ]

35 голосов
/ 15 июня 2011

Самый простой способ сделать это - обновить объект Date, используя setDate. Поскольку комментарии к этому ответу указывают, что это официально не является частью спецификации, но поддерживается во всех основных браузерах.

Вам следует НИКОГДА обновить объект Date, отличный от того, который вы сделали при первоначальном вызове getDate.

Пример реализации:

var incrementDate = function (date, amount) {
    var tmpDate = new Date(date);
    tmpDate.setDate(tmpDate.getDate() + amount)
    return tmpDate;
};

Если вы пытаетесь увеличить дату, используйте эту функцию. Он будет принимать как положительные, так и отрицательные значения. Это также гарантирует, что используемые объекты даты не будут изменены. Это должно предотвратить любую ошибку, которая может возникнуть, если вы не ожидаете, что обновление изменит значение объекта.


Неправильное использование:

var startDate = new Date('2013-11-01T11:00:00');
var a = new Date();
a.setDate(startDate.getDate() + 14)

Это обновит значение «date» для startDate с 14 днями на основе значения a. Поскольку значение a не совпадает с ранее определенным startDate, возможно получить неправильное значение.

4 голосов
/ 03 ноября 2012

Расширяя ответ Exellian, если вы хотите рассчитать какой-либо период в будущем (в моем случае для следующей даты выплаты), вы можете сделать простой цикл:

var today = new Date();
var basePayDate = new Date(2012, 9, 23, 0, 0, 0, 0);

while (basePayDate < today) {
    basePayDate.setDate(basePayDate.getDate()+14);
}

var nextPayDate = new Date(basePayDate.getTime());
basePayDate.setDate(nextPayDate.getDate()-14);

document.writeln("<p>Previous pay Date: " + basePayDate.toString());
document.writeln("<p>Current Date: " + today.toString());
document.writeln("<p>Next pay Date: " + nextPayDate.toString());

Это нестолкнулся со странными проблемами, предполагая, что основные службы даты работают как положено.Я должен признать, я не проверял это много лет в будущем ...

2 голосов
/ 26 октября 2011

Примечание: у меня была похожая проблема;Я хотел создать массив дат на еженедельной основе, т. Е. Дату начала 23.10.2011 и идти в течение 12 недель.Мой код был более или менее такой:

var myDate = new Date(Date.parse(document.eventForm.startDate.value));
var toDate = new Date(myDate);

var week = 60 * 60 * 24 * 7 * 1000;
var milliseconds = toDate.getTime();

dateArray[0] = myDate.format('m/d/Y');

for (var count = 1; count < numberOccurrences; count++) {
    milliseconds += week;
toDate.setTime(milliseconds);
    dateArray[count] = toDate.format('m/d/Y');
}

Поскольку я не указал время и живу в США, мое стандартное время было полночь, поэтому, когда я пересек границу летнего времени, я переехалв предыдущий день.Тьфу.Я решил это, установив мое время дня на полдень, прежде чем я сделал свой недельный расчет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...