JavaScript - dapatkan hari pertama dalam seminggu dari tanggal saat ini

162

Saya membutuhkan cara tercepat untuk mendapatkan hari pertama dalam seminggu. Misalnya: hari ini tanggal 11 November, dan hari Kamis; dan saya ingin hari pertama minggu ini, yaitu 8 November, dan Senin. Saya memerlukan metode tercepat untuk fungsi peta MongoDB, ada ide?

IN
sumber
Jika setiap sedikit kecepatan sangat penting, Anda mungkin ingin menguji kinerja jawaban saya. Saya mendapatkan kinerja yang sedikit lebih baik dengan milik saya di browser (kecuali untuk IE, yang mendukung CMS). Tentu saja, Anda perlu mengujinya dengan MongoDB. Ketika fungsi melewati tanggal yang Senin, itu harus lebih cepat, karena hanya mengembalikan tanggal asli yang tidak dimodifikasi.
user113716
Saya mendapat masalah yang sama dan karena objek tanggal javascript memiliki banyak bug yang saya gunakan sekarang datejs.com (di sini code.google.com/p/datejs ), perpustakaan yang memperbaiki perilaku tidak terjawab dari tanggal asli.
lolol
Judul pertanyaan menanyakan hari pertama dalam minggu itu sementara deskripsi pertanyaan menanyakan tanggal hari Senin terakhir. Ini sebenarnya adalah dua pertanyaan yang berbeda. Periksa jawaban saya yang memecahkan keduanya dengan cara yang benar.
Louis Ameline

Jawaban:

323

Dengan menggunakan getDaymetode objek Date, Anda dapat mengetahui jumlah hari dalam seminggu (menjadi 0 = Minggu, 1 = Senin, dll).

Anda kemudian dapat mengurangi jumlah hari ditambah satu, misalnya:

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
CMS
sumber
3
Apakah fungsi ini memiliki bug? - jika tanggal yang dimaksud adalah Kamis tanggal 2, hari = 4, beda = 2 - 4 + 1 = -1, dan hasil dari setDate akan menjadi 'hari sebelum hari terakhir bulan sebelumnya' (lihat ini ).
Izhaki
2
@Izhaki apa maksudmu? Untuk 2 Mei, fungsi mengembalikan 29 April yang benar.
meze
14
Jika hari Minggu adalah hari pertama dalam seminggu, gunakan:diff = d.getDate() - day;
cfree
2
Terima kasih atas kode @SMS. Saya membuat sedikit twist untuk mendapatkan tepat 0 jam di hari pertama minggu. d.setHours(0); d.setMinutes(0); d.setSeconds(0);
Awi
3
omong-omong, d.setDate bisa berubah, itu mengubah "d" itu sendiri
Ayyash
53

Tidak yakin bagaimana ini membandingkan untuk kinerja, tetapi ini berfungsi.

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

Atau sebagai fungsi:

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

setToMonday(new Date());
pengguna113716
sumber
4
Ini seharusnya jawabannya, itu satu-satunya yang menjawab pertanyaan yang diajukan. Yang lain buggy atau merujuk Anda ke perpustakaan pihak ketiga.
OverMars
Keren itu bekerja untukku! Dengan membuat beberapa penyesuaian saya mendapatkan keduanya, Senin dan Jumat dalam seminggu dari tanggal yang ditentukan!
alexventuraio
10
Ini bagus kecuali fungsi ini harus disebut "setToMonday" karena memodifikasi objek tanggal yang dilewatkan. GetMonday, akan mengembalikan Tanggal baru yang merupakan Senin berdasarkan tanggal yang dilewati. Perbedaan yang halus, tetapi yang menarik perhatian saya setelah menggunakan fungsi ini. Perbaikan termudah adalah dengan menempatkan date = new Date(date);sebagai baris pertama dalam fungsi getMonday.
Shane
Ini luar biasa. Metode getSunday bahkan lebih mudah! Terima kasih banyak!
JesusIsMyDriver.dll
4
Jawaban ini salah karena tidak semua hari memiliki 24 jam karena penghematan siang hari. Ini dapat mengubah jam kencan Anda secara tak terduga atau bahkan mengembalikan hari yang salah pada kesempatan tertentu.
Louis Ameline
13

Lihat Date.js

Date.today().previous().monday()
Mat
sumber
1
atau mungkinDate.parse('last monday');
Anurag
Saya membutuhkannya untuk database MongoDB. Jadi saya tidak bisa mereferensikan date.js, tetapi terima kasih atas cuplikan kode Anda.
INs
1
Ah, saya tidak tahu Anda bisa mengeksekusi JS langsung di MongoDB. Itu cukup bagus. Diasumsikan Anda menggunakan JS untuk menyiapkan data kueri.
Matt
Seperti jQuery, tidak tertarik merobohkan seluruh perpustakaan (tidak peduli seberapa kecil) untuk mendapatkan akses ke satu fungsi sederhana.
The Muffin Man
Bukan solusi yang baik, karena ada negara, hari pertama dalam seminggu adalah minggu.
Stefan Brendle
11

Jawaban CMS benar tetapi menganggap bahwa Senin adalah hari pertama dalam seminggu.
Jawaban Chandler Zwolle benar tetapi mengutak-atik prototipe Date.
Jawaban lain yang diputar dengan jam / menit / detik / milidetik salah.

Fungsi di bawah ini benar dan mengambil tanggal sebagai parameter pertama dan hari pertama yang diinginkan dalam minggu sebagai parameter kedua (0 untuk hari Minggu, 1 untuk hari Senin, dll.). Catatan: jam, menit dan detik diatur ke 0 untuk memulai hari.

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)

Louis Ameline
sumber
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));

Ini akan bekerja dengan baik.

Parth Shah
sumber
4

Saya menggunakan ini

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;
}
1 naluri
sumber
3

Fungsi ini menggunakan waktu milidetik saat ini untuk mengurangi minggu ini, dan kemudian mengurangi satu minggu lagi jika tanggal saat ini adalah pada hari Senin (jumlah javascript dari minggu).

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

Saya telah mengujinya ketika rentang minggu dari satu bulan ke bulan lainnya (dan juga bertahun-tahun), dan tampaknya berfungsi dengan baik.

einord
sumber
3

Selamat malam,

Saya lebih suka hanya memiliki metode ekstensi sederhana:

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

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

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

Anda akan melihat ini sebenarnya menggunakan metode ekstensi lain yang saya gunakan:

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

Sekarang, jika minggu Anda dimulai pada hari Minggu, berikan "0" untuk parameter pStartOfWeek, seperti:

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

Demikian pula, jika minggu Anda dimulai pada hari Senin, berikan "1" untuk parameter pStartOfWeek:

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

Salam,

Chandler Zwolle
sumber
2

Hari Pertama Minggu Ini

Untuk mendapatkan tanggal hari pertama dalam seminggu mulai hari ini, Anda dapat menggunakan sesuatu seperti:

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

Atau untuk mendapatkan hari terakhir dalam seminggu dari hari ini:

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

* Bergantung pada zona waktu Anda, awal minggu tidak harus dimulai pada hari Minggu, itu bisa dimulai pada hari Jumat, Sabtu, Senin atau hari lain di mana mesin Anda diatur. Metode-metode itu akan menjelaskan hal itu.

* Anda juga dapat memformatnya menggunakan toISOStringmetode seperti ini:getLastSunday().toISOString()

Lior Elrom
sumber
1

setDate () memiliki masalah dengan batas bulan yang dicatat dalam komentar di atas. Solusi yang bersih adalah menemukan perbedaan tanggal menggunakan cap waktu zaman daripada metode (secara mengejutkan berlawanan dengan intuisi) pada objek Date. Yaitu

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);
}
jtschoonhoven
sumber
1

Ini solusinya:

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

Sekarang Anda dapat memilih tanggal dengan indeks array yang dikembalikan.

Krystian Wieczorek
sumber
0

Contoh perhitungan hanya secara matematis, tanpa Datefungsi apa pun .

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

Anton Korneychuk
sumber
0

versi yang lebih umum dari ini ... ini akan memberi Anda hari apa pun dalam minggu ini berdasarkan hari apa yang Anda tentukan.

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

Andy
sumber
-1

Lihat: moment.js

Contoh:

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)

Bonus: bekerja dengan node.js juga

pixelfreak
sumber
18
Itu bukan jawaban untuk pertanyaan OP. Dia punya kencan, katakan 08/07/14 (d / m / y). Dia ingin mendapatkan hari pertama minggu ini (untuk lokal saya ini akan menjadi hari Senin yang baru saja berlalu, atau kemarin) Jawaban untuk pertanyaannya adalahmoment().startOf('week')
Jeroen Pelgrims
Catatan yang moment().startOf("week")mungkin memberikan tanggal hari Minggu sebelumnya, tergantung pada pengaturan lokal. Dalam hal ini, gunakan moment().startOf('isoWeek')sebaliknya: runkit.com/embed/wdpi4bjwh6rt
Harm te Molder
PS Documents aktif startOf(): momentjs.com/docs/#/manipulating/start-of
Harm te Molder