JavaScript - nhận ngày đầu tuần kể từ ngày hiện tại


161

Tôi cần cách nhanh nhất để có được ngày đầu tuần. Ví dụ: hôm nay là ngày 11 tháng 11 và thứ năm; và tôi muốn ngày đầu tiên của tuần này, đó là ngày 8 tháng 11 và thứ Hai. Tôi cần phương pháp nhanh nhất cho chức năng bản đồ MongoDB, có ý tưởng nào không?


Nếu mỗi một chút tốc độ là rất quan trọng, bạn có thể muốn kiểm tra hiệu suất câu trả lời của tôi. Tôi đang có hiệu suất tốt hơn một chút với trình duyệt của tôi (ngoại trừ IE, hỗ trợ CMS). Tất nhiên, bạn sẽ cần kiểm tra nó với MongoDB. Khi chức năng được thông qua một ngày là thứ Hai, nó sẽ còn nhanh hơn nữa, vì nó chỉ trả về ngày ban đầu chưa sửa đổi.
dùng113716

Tôi gặp vấn đề tương tự và vì đối tượng ngày javascript có rất nhiều lỗi tôi đang sử dụng hiện nay datejs.com (ở đây code.google.com/p/datejs ), một thư viện sửa hành vi bỏ lỡ của ngày gốc.
lolol

Tiêu đề câu hỏi yêu cầu cho ngày đầu tuần trong khi mô tả câu hỏi yêu cầu ngày thứ Hai tuần trước. Đây thực sự là hai câu hỏi khác nhau. Kiểm tra câu trả lời của tôi mà giải quyết cả hai một cách chính xác.
Louis Ameline

Câu trả lời:


322

Sử dụng getDayphương pháp của các đối tượng Date, bạn có thể biết số ngày trong tuần (là 0 = Chủ nhật, 1 = Thứ hai, v.v.).

Sau đó, bạn có thể trừ số ngày đó cộng với một, ví dụ:

function getMonday(d) {
  d = new Date(d);
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

getMonday(new Date()); // Mon Nov 08 2010

3
Chức năng này có lỗi không? - nếu ngày được đề cập là Thứ Năm ngày 2, ngày = 4, diff = 2 - 4 + 1 = -1 và kết quả của setDate sẽ là 'ngày trước ngày cuối cùng của tháng trước' (xem phần này ).
Izhaki

2
@Izhaki bạn có ý gì? Đối với ngày 2 tháng 5, hàm trả về ngày 29 tháng 4, đúng.
meze

14
Nếu Chủ nhật là ngày đầu tuần, hãy sử dụng:diff = d.getDate() - day;
cfree

2
Cảm ơn mã @SMS. Tôi đã thực hiện một bước ngoặt nhỏ để có được chính xác 0 giờ của ngày đầu tuần. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi

3
Nhân tiện, d.setDate có thể thay đổi, nó tự thay đổi "d"
Ayyash

53

Không chắc làm thế nào nó so sánh hiệu suất, nhưng điều này hoạt động.

var today = new Date();
var day = today.getDay() || 7; // Get current day number, converting Sun. to 7
if( day !== 1 )                // Only manipulate the date if it isn't Mon.
    today.setHours(-24 * (day - 1));   // Set the hours to day number minus 1
                                         //   multiplied by negative 24
alert(today); // will be Monday

Hoặc như một chức năng:

# modifies _date_
function setToMonday( date ) {
    var day = date.getDay() || 7;  
    if( day !== 1 ) 
        date.setHours(-24 * (day - 1)); 
    return date;
}

setToMonday(new Date());

4
Đây nên là câu trả lời, nó là người duy nhất trả lời câu hỏi. Những người khác đang có lỗi hoặc giới thiệu bạn đến thư viện của bên thứ ba.
OverMars 7/03/2015

Thật tuyệt khi nó làm việc cho tôi! Bằng cách thực hiện một số điều chỉnh, tôi sẽ có được cả hai, thứ Hai và thứ Sáu trong tuần kể từ một ngày nhất định!
alexventuraio

10
Điều này thật tuyệt vời ngoại trừ chức năng này nên được gọi là "setToMonday" vì nó sửa đổi đối tượng ngày được truyền vào. GetMonday, sẽ trả về một Ngày mới là ngày thứ hai dựa trên ngày được truyền vào. Một sự khác biệt tinh tế, nhưng một điều đã bắt gặp tôi sau khi sử dụng Chức năng này. Cách khắc phục dễ nhất là đặt date = new Date(date);dòng đầu tiên trong hàm getMonday.
Shane

Điều này thật tuyệt. Một phương thức getSunday thậm chí còn dễ dàng hơn! Cảm ơn nhiều!
JesusIsMyDriver.dll

4
Câu trả lời này là sai vì không phải tất cả các ngày đều có 24h vì tiết kiệm vào ban ngày. Nó có thể thay đổi giờ trong ngày của bạn một cách bất ngờ hoặc thậm chí trả lại ngày sai trong những dịp nhất định.
Louis Ameline

13

Hãy xem Date.js

Date.today().previous().monday()

1
hoặc có thểDate.parse('last monday');
Anurag

Tôi cần nó cho cơ sở dữ liệu MongoDB. Vì vậy, tôi không thể tham khảo date.js, nhưng cảm ơn vì đoạn mã của bạn.
VÀO

1
À, tôi không biết bạn có thể thực thi JS trực tiếp trong MongoDB. Điều đó khá hấp dẫn. Đã cho rằng bạn đang sử dụng JS để chuẩn bị dữ liệu truy vấn.
Matt

Giống như jQuery, không quan tâm đến việc kéo xuống toàn bộ thư viện (dù nhỏ đến đâu) để có quyền truy cập vào một chức năng đơn giản.
Người đàn ông Muffin

Không phải là một giải pháp tốt, bởi vì có những quốc gia, ngày đầu tiên trong tuần của họ là chủ nhật.
Stefan Brendle

11

Câu trả lời của CMS là đúng nhưng giả định rằng Thứ Hai là ngày đầu tiên trong tuần.
Câu trả lời của Chandler Zwolle là đúng nhưng nghịch với nguyên mẫu Date.
Các câu trả lời khác chơi với giờ / phút / giây / mili giây là sai.

Hàm bên dưới là chính xác và lấy ngày làm tham số đầu tiên và ngày đầu tiên trong tuần mong muốn làm tham số thứ hai (0 cho Chủ nhật, 1 cho Thứ Hai, v.v.). Lưu ý: giờ, phút và giây được đặt thành 0 để bắt đầu ngày mới.

function firstDayOfWeek(dateObject, firstDayOfWeekIndex) {

    const dayOfWeek = dateObject.getDay(),
        firstDayOfWeek = new Date(dateObject),
        diff = dayOfWeek >= firstDayOfWeekIndex ?
            dayOfWeek - firstDayOfWeekIndex :
            6 - dayOfWeek

    firstDayOfWeek.setDate(dateObject.getDate() - diff)
    firstDayOfWeek.setHours(0,0,0,0)

    return firstDayOfWeek
}

// August 18th was a Saturday
let lastMonday = firstDayOfWeek(new Date('August 18, 2018 03:24:00'), 1)

// outputs something like "Mon Aug 13 2018 00:00:00 GMT+0200"
// (may vary according to your time zone)
document.write(lastMonday)


8
var dt = new Date(); // current date of week
var currentWeekDay = dt.getDay();
var lessDays = currentWeekDay == 0 ? 6 : currentWeekDay - 1;
var wkStart = new Date(new Date(dt).setDate(dt.getDate() - lessDays));
var wkEnd = new Date(new Date(wkStart).setDate(wkStart.getDate() + 6));

Điều này sẽ hoạt động tốt.


4

Tôi đang sử dụng cái này

function get_next_week_start() {
   var now = new Date();
   var next_week_start = new Date(now.getFullYear(), now.getMonth(), now.getDate()+(8 - now.getDay()));
   return next_week_start;
}

3

Hàm này sử dụng thời gian tính bằng mili giây hiện tại để trừ đi tuần hiện tại và sau đó trừ thêm một tuần nữa nếu ngày hiện tại là vào thứ hai (tính javascript từ chủ nhật).

function getMonday(fromDate) {
    // length of one day i milliseconds
  var dayLength = 24 * 60 * 60 * 1000;

  // Get the current date (without time)
    var currentDate = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate());

  // Get the current date's millisecond for this week
  var currentWeekDayMillisecond = ((currentDate.getDay()) * dayLength);

  // subtract the current date with the current date's millisecond for this week
  var monday = new Date(currentDate.getTime() - currentWeekDayMillisecond + dayLength);

  if (monday > currentDate) {
    // It is sunday, so we need to go back further
    monday = new Date(monday.getTime() - (dayLength * 7));
  }

  return monday;
}

Tôi đã thử nghiệm nó khi tuần kéo dài từ tháng này sang tháng khác (và cả năm), và nó dường như hoạt động đúng.


3

Chào buổi tối,

Tôi thích chỉ có một phương thức mở rộng đơn giản:

Date.prototype.startOfWeek = function (pStartOfWeek) {
    var mDifference = this.getDay() - pStartOfWeek;

    if (mDifference < 0) {
        mDifference += 7;
    }

    return new Date(this.addDays(mDifference * -1));
}

Bạn sẽ nhận thấy điều này thực sự sử dụng một phương thức mở rộng khác mà tôi sử dụng:

Date.prototype.addDays = function (pDays) {
    var mDate = new Date(this.valueOf());
    mDate.setDate(mDate.getDate() + pDays);
    return mDate;
};

Bây giờ, nếu tuần của bạn bắt đầu vào Chủ nhật, hãy chuyển vào "0" cho tham số pStartOfWeek, như vậy:

var mThisSunday = new Date().startOfWeek(0);

Tương tự, nếu tuần của bạn bắt đầu vào thứ Hai, hãy chuyển vào "1" cho tham số pStartOfWeek:

var mThisMonday = new Date().startOfWeek(1);

Trân trọng,


2

Ngày đầu tiên trong tuần

Để có được ngày của ngày đầu tuần kể từ hôm nay, bạn có thể sử dụng một cái gì đó như vậy:

function getUpcomingSunday() {
  const date = new Date();
  const today = date.getDate();
  const dayOfTheWeek = date.getDay();
  const newDate = date.setDate(today - dayOfTheWeek + 7);
  return new Date(newDate);
}

console.log(getUpcomingSunday());

Hoặc để có được ngày cuối tuần kể từ hôm nay:

function getLastSunday() {
  const date = new Date();
  const today = date.getDate();
  const dayOfTheWeek = date.getDay();
  const newDate = date.setDate(today - (dayOfTheWeek || 7));
  return new Date(newDate);
}

console.log(getLastSunday());

* Tùy thuộc vào múi giờ của bạn, đầu tuần không phải bắt đầu vào Chủ nhật, nó có thể bắt đầu vào Thứ Sáu, Thứ Bảy, Thứ Hai hoặc bất kỳ ngày nào khác mà máy của bạn được đặt. Những phương pháp đó sẽ giải thích cho điều đó.

* Bạn cũng có thể định dạng nó bằng toISOStringphương thức như vậy:getLastSunday().toISOString()


1

setDate () có vấn đề với ranh giới tháng được ghi chú trong các bình luận ở trên. Một cách giải quyết rõ ràng là tìm sự khác biệt ngày bằng cách sử dụng dấu thời gian epoch thay vì các phương thức (phản trực quan đáng ngạc nhiên) trên đối tượng Date. I E

function getPreviousMonday(fromDate) {
    var dayMillisecs = 24 * 60 * 60 * 1000;

    // Get Date object truncated to date.
    var d = new Date(new Date(fromDate || Date()).toISOString().slice(0, 10));

    // If today is Sunday (day 0) subtract an extra 7 days.
    var dayDiff = d.getDay() === 0 ? 7 : 0;

    // Get date diff in millisecs to avoid setDate() bugs with month boundaries.
    var mondayMillisecs = d.getTime() - (d.getDay() + dayDiff) * dayMillisecs;

    // Return date as YYYY-MM-DD string.
    return new Date(mondayMillisecs).toISOString().slice(0, 10);
}

1

Đây là giải pháp của tôi:

function getWeekDates(){
    var day_milliseconds = 24*60*60*1000;
    var dates = [];
    var current_date = new Date();
    var monday = new Date(current_date.getTime()-(current_date.getDay()-1)*day_milliseconds);
    var sunday = new Date(monday.getTime()+6*day_milliseconds);
    dates.push(monday);
    for(var i = 1; i < 6; i++){
        dates.push(new Date(monday.getTime()+i*day_milliseconds));
    }
    dates.push(sunday);
    return dates;
}

Bây giờ bạn có thể chọn ngày bằng chỉ mục mảng trả về.


0

Một ví dụ về phép tính chỉ tính toán, không có bất kỳ Datehàm nào .

const date = new Date();
const ts = +date;

const mondayTS = ts - ts % (60 * 60 * 24 * (7-4) * 1000);

const monday = new Date(mondayTS);
console.log(monday.toISOString(), 'Day:', monday.getDay());

const formatTS = v => new Date(v).toISOString();
const adjust = (v, d = 1) => v - v % (d * 1000);

const d = new Date('2020-04-22T21:48:17.468Z');
const ts = +d; // 1587592097468

const test = v => console.log(formatTS(adjust(ts, v)));

test();                     // 2020-04-22T21:48:17.000Z
test(60);                   // 2020-04-22T21:48:00.000Z
test(60 * 60);              // 2020-04-22T21:00:00.000Z
test(60 * 60 * 24);         // 2020-04-22T00:00:00.000Z
test(60 * 60 * 24 * (7-4)); // 2020-04-20T00:00:00.000Z, monday

// So, what does `(7-4)` mean?
// 7 - days number in the week
// 4 - shifting for the weekday number of the first second of the 1970 year, the first time stamp second.
//     new Date(0)          ---> 1970-01-01T00:00:00.000Z
//     new Date(0).getDay() ---> 4


0

một phiên bản tổng quát hơn về điều này ... điều này sẽ cung cấp cho bạn bất kỳ ngày nào trong tuần hiện tại dựa trên ngày bạn chỉ định.

//returns the relative day in the week 0 = Sunday, 1 = Monday ... 6 = Saturday
function getRelativeDayInWeek(d,dy) {
  d = new Date(d);
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:dy); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

var monday = getRelativeDayInWeek(new Date(),1);
var friday = getRelativeDayInWeek(new Date(),5);

console.log(monday);
console.log(friday);


-1

Kiểm tra: khoảnh khắc

Thí dụ:

moment().day(-7); // last Sunday (0 - 7)
moment().day(7); // next Sunday (0 + 7)
moment().day(10); // next Wednesday (3 + 7)
moment().day(24); // 3 Wednesdays from now (3 + 7 + 7 + 7)

Phần thưởng: cũng hoạt động với node.js


18
Đó không phải là một câu trả lời cho câu hỏi của OP. Anh ấy có một ngày, nói 08/07/14 (d / m / y). Anh ấy muốn có được ngày đầu tiên của tuần này (đối với địa phương của tôi, đây sẽ là thứ Hai vừa qua, hoặc ngày hôm qua) Một câu trả lời cho câu hỏi của anh ấy trong giây lát sẽ làmoment().startOf('week')
Jeroen Pelgrims

Lưu ý rằng moment().startOf("week")có thể đưa ra ngày của Chủ nhật trước, tùy thuộc vào cài đặt ngôn ngữ. Trong trường hợp đó, sử dụng moment().startOf('isoWeek')thay thế: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder

Tài liệu PS trên startOf(): Momentjs.com/docs/#/manipulation/start-of
Harm te Molder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.