2011-06-15 31 views
14

Tôi đang cố gắng tạo một tập lệnh đơn giản cung cấp cho tôi ngày tái chế tiếp theo dựa trên lịch trình hai tuần một lần bắt đầu từ ngày 6 tháng 7 năm 2011. Vì vậy, tôi đã tạo chức năng đơn giản này .. .Toán ngày tháng javascript đơn giản ... không thực sự

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

và có thể gọi nó như thế ...

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

cho đến nay rất tốt ... nhưng khi tôi dự án "ngày nay" đến 2011/10/27, tôi nhận được thứ Ba 11/8/2011 là ngày kế tiếp thay vì thứ tư 11/9/2011 ... Thực tế mỗi ngày từ nay đến hết ngày 26/10/2011 dự án đón đúng ... và mỗi ngày từ ngày 27/10/2011 đến hết ngày 2/28/2012 dự án thứ ba và không phải là thứ tư. Và sau đó mỗi ngày từ ngày 29/2/2012 (năm nhuận) đến ngày 24/10/2012 (hmmm tháng 10 một lần nữa) dự án thứ tư chính xác. Tôi đang thiếu gì? Bất kỳ trợ giúp sẽ được đánh giá cao ..

V

+1

Không nên có sàn nhà? Bởi vì bạn sử dụng 2011-06-06 1: 00u totalDays sẽ là 1 và lượt đón tiếp theo sẽ là 13 ngày không 14 ngày, do đó, một ngày thứ ba. – Gerben

+0

Có vẻ lạ. Tôi nhận được ngày chính xác với 'one_day = 1000 * 60 * 60 * 24; hôm nay = ngày mới (2011,8,27); nextDate = getNextDate (ngày mới (2011,6,6)); ', và nextDate là' Wed Sep 28 2011 00:00:00 GMT + ', đó là đúng? Thử nghiệm trên FF4. – Raze

+0

startDate luôn là ngày mới (2011,06,06) - vì vậy nó không được di chuyển – user799301

Trả lời

34

Cách dễ nhất để làm điều này là cập nhật các đối tượng sử dụng DatesetDate. Khi nhận xét cho câu trả lời này cho biết đây không phải là một phần chính thức của thông số kỹ thuật, nhưng nó được hỗ trợ trên tất cả các trình duyệt chính.

Bạn nên KHÔNG BAO GIỜ cập nhật đối tượng Date khác với đối tượng bạn đã thực hiện cuộc gọi ban đầu getDate.

mẫu thực hiện:

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

Nếu bạn đang cố gắng để tăng một ngày, xin vui lòng sử dụng chức năng này. Nó sẽ chấp nhận cả giá trị dương và âm. Nó cũng đảm bảo rằng các đối tượng ngày được sử dụng không thay đổi. Điều này sẽ ngăn chặn bất kỳ lỗi nào có thể xảy ra nếu bạn không mong đợi cập nhật thay đổi giá trị của đối tượng.


sử dụng không đúng:

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

này sẽ cập nhật "ngày" giá trị cho startDate với 14 ngày theo nguyên tắc giá trị của a. Bởi vì giá trị của a không giống với giá trị được xác định trước đây startDate, có thể có giá trị sai.

+1

Không dễ tìm tài liệu đảm bảo rằng điều này sẽ làm việc trong trường hợp chung (thêm số ngày tùy ý). – nobar

+7

Đây là một quá trình suy nghĩ rất nguy hiểm. Hãy tưởng tượng 'startDate' là vào ngày 1 của tháng, và hôm nay là ngày 31. Bạn muốn có một ngày trở lại từ ngày bắt đầu 7 ngày. a.setDate (startDate.getDate() - 7) sẽ đủ, phải không? Không quá nhanh. 'a' hiện là 7 ngày trước khi bắt đầu tháng * hiện tại *, không phải 7 ngày trước 'startDate'. Xem xét nơi trang này xuất hiện trong kết quả của Google, điều này hoàn toàn quan trọng để hiểu. Tôi đang sửa vấn đề như vậy ngay bây giờ và mạnh mẽ nghi ngờ nhà thầu của chúng tôi đã tìm thấy trang này và tuân theo logic chính xác đó. – 10gistic

+0

Hmm, tôi không bao giờ dự định điều này sẽ được sử dụng theo cách bạn mô tả. Chỉ cho __updating__ một giá trị ngày tháng. Tôi sẽ thay đổi câu trả lời của tôi để phản ánh vấn đề. – Exelian

2

Lưu ý: Tôi gặp sự cố tương tự; Tôi muốn tạo ra một loạt các ngày trên cơ sở hàng tuần, tức là, ngày bắt đầu 10/23/2011 và đi trong 12 tuần. Mã của tôi là nhiều hay ít này:

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

Bởi vì tôi đã không xác định thời gian và tôi sống ở Mỹ, thời gian mặc định của tôi là nửa đêm, vì vậy khi tôi vượt qua biên giới thời gian tiết kiệm ánh sáng ban ngày, tôi chuyển vào ngày hôm trước. Kinh quá. Tôi giải quyết nó bằng cách thiết lập thời gian của tôi trong ngày đến trưa trước khi tôi đã tính toán tuần của tôi.

4

Mở rộng về câu trả lời Exellian, nếu bạn muốn tính toán bất kỳ thời gian trong tương lai (trong trường hợp của tôi, cho ngày trả sau), bạn có thể làm một vòng lặp đơn giản:

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()); 

này sẽ không đạt vấn đề kỳ lạ, giả định các dịch vụ ngày lõi hoạt động như mong đợi. Tôi phải thừa nhận, tôi đã không thử nghiệm nó trong nhiều năm trong tương lai ...

Các vấn đề liên quan