ASP.NET adalah seperangkat teknologi web. C # adalah bahasa. Anda benar-benar perlu memikirkan hal ini dalam hal .NET. Sekarang, untuk "Selasa depan" - apakah itu "Selasa pertama setelah hari ini"? Jika itu hari Senin dan seseorang berkata "sampai jumpa hari Selasa depan" saya akan berharap itu berarti waktu 8 hari daripada 1. Bagaimana kalau hari ini adalah hari Selasa? Jam berapa hari yang Anda butuhkan?
Jon Skeet
Jika hari ini selasa, Anda ingin mencari tahu kapan hari selasa berikutnya? Atau hari ini hari Senin, Anda ingin mencari selasa kedua dari hari Senin?
API Panda
Selasa terdekat menuju hari yang paling khusus.
brenjt
2
@ brenjtL: Dan jika sudah hari Selasa?
Jon Skeet
Jika sudah hari Selasa maka hari yang sama
brenjt
Jawaban:
371
Seperti yang saya sebutkan di komentar, ada berbagai hal yang dapat Anda maksud dengan "Selasa depan", tetapi kode ini memberi Anda "Selasa berikutnya untuk terjadi, atau hari ini jika sudah Selasa":
DateTime today =DateTime.Today;// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) today.DayOfWeek+7)%7;DateTime nextTuesday = today.AddDays(daysUntilTuesday);
Jika Anda ingin memberi "waktu seminggu" jika sudah Selasa, Anda dapat menggunakan:
// This finds the next Monday (or today if it's Monday) and then adds a day... so the// result is in the range [1-7]int daysUntilTuesday =(((int)DayOfWeek.Monday-(int) today.DayOfWeek+7)%7)+1;
... atau Anda dapat menggunakan rumus asli, tetapi mulai besok:
DateTime tomorrow =DateTime.Today.AddDays(1);// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) tomorrow.DayOfWeek+7)%7;DateTime nextTuesday = tomorrow.AddDays(daysUntilTuesday);
EDIT: Hanya untuk menjadikan ini menyenangkan dan serbaguna:
publicstaticDateTimeGetNextWeekday(DateTime start,DayOfWeek day){// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysToAdd =((int) day -(int) start.DayOfWeek+7)%7;return start.AddDays(daysToAdd);}
Jadi untuk mendapatkan nilai untuk "hari ini atau dalam 6 hari ke depan":
Wow, saya hanya ingin tahu bagaimana saya bisa mendapatkan hari ke-til sampai selasa berikutnya dan Anda kemudian memperbarui jawaban Anda dengan contoh yang bagus. Terima kasih
brenjt
Sulit untuk memilih jawaban yang benar. Tapi milikmu tampaknya paling fleksibel dan kau membuatnya mudah dimengerti. Terima kasih atas bantuannya.
brenjt
1
@ brenjt: Sebenarnya saya akan mengatakan bahwa Sven lebih fleksibel, karena Anda dapat menentukan hari dalam seminggu, tapi ini panggilan Anda :) (Saya sekarang telah mengedit milik saya untuk memberikan versi yang lebih umum.)
Jon Skeet
1
The +7)%7solusi adalah cukup bagus meskipun. Meskipun alasan saya tidak menggunakannya adalah karena itu sedikit optimasi mikro dan terlalu mudah salah (serta mengorbankan beberapa keterbacaan), tentu saja.
Sven
Unit test: [TestMethod] public void ShouldGetNextSaturday () {var now = DateTime.Now; var test = GetNextWeekday (DateTime.Today, DayOfWeek.Saturday); Assert.IsTrue (now.Day <test.Day, "Hari bulan yang diharapkan tidak ada di sini."); Assert.IsTrue (test.DayOfWeek == DayOfWeek.Saturday, "Hari minggu yang diharapkan tidak ada di sini."); Assert.IsTrue ((test.Day - now.Day) <7, "Interval hari yang diharapkan tidak ada di sini."); }
rasx
67
Ini harus melakukan trik:
staticDateTimeGetNextWeekday(DayOfWeek day){DateTime result =DateTime.Now.AddDays(1);while( result.DayOfWeek!= day )
result = result.AddDays(1);return result;}
Respons yang bagus, jika hari ini adalah Selasa (yang mana ha) akankah ini kembali hari ini atau selasa berikutnya
brenjt
3
Ini akan kembali Selasa depan. Jika Anda ingin mengembalikannya hari ini, hapus saja .AddDays(1)dari baris pertama, dengan begitu ia akan memeriksa DateTime.Nowsendiri.
Sven
7
Ada solusi yang kurang verbose dan lebih pintar / elegan untuk masalah ini, tetapi fungsi C # berikut bekerja dengan sangat baik untuk sejumlah situasi.
/// <summary>/// Find the closest weekday to the given date/// </summary>/// <param name="includeStartDate">if the supplied date is on the specified day of the week, return that date or continue to the next date</param>/// <param name="searchForward">search forward or backward from the supplied date. if a null parameter is given, the closest weekday (ie in either direction) is returned</param>publicstaticDateTimeClosestWeekDay(thisDateTime date,DayOfWeek weekday,bool includeStartDate =true,bool? searchForward=true){if(!searchForward.HasValue&&!includeStartDate){thrownewArgumentException("if searching in both directions, start date must be a valid result");}var day = date.DayOfWeek;intadd=((int)weekday -(int)day);if(searchForward.HasValue){if(add<0&& searchForward.Value){add+=7;}elseif(add>0&&!searchForward.Value){add-=7;}elseif(add==0&&!includeStartDate){add= searchForward.Value?7:-7;}}elseif(add<-3){add+=7;}elseif(add>3){add-=7;}return date.AddDays(add);}
Satu-satunya jawaban yang menerapkan ekstensi ke DateTime. Sementara solusi lain semuanya berfungsi, menjadikannya sebagai metode ekstensi menghasilkan kode yang paling mudah digunakan.
Jika hari ini adalah hari Senin, jawaban yang Anda berikan akan menghasilkan satu minggu dari hari Selasa, bukan besok.
Tony
5
@ Jon Skeet jawaban yang bagus.
Untuk Hari sebelumnya:
privateDateTimeGetPrevWeekday(DateTime start,DayOfWeek day){// The (... - 7) % 7 ensures we end up with a value in the range [0, 6]int daysToRemove =((int) day -(int) start.DayOfWeek-7)%7;return start.AddDays(daysToRemove);}
Perhatikan bahwa solusi ini melibatkan angka negatif yang diberikan kepada operator modulo. The Wikipedia artikel tentang operator Modulo mengatakan bahwa "Ketika baik atau n adalah negatif, definisi naif rusak dan bahasa pemrograman berbeda dalam bagaimana nilai-nilai ini didefinisikan." Meskipun ini mungkin bekerja di C #, solusi matematis yang lebih 'solid' untuk mendapatkan hasil yang sama akan menukar DayOfWeeknilai - nilai seperti ini:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Sampel yang sangat sederhana untuk memasukkan atau mengecualikan tanggal saat ini, Anda menentukan tanggal dan hari minggu Anda tertarik.
publicstaticclassDateTimeExtensions{/// <summary>/// Gets the next date./// </summary>/// <param name="date">The date to inspected.</param>/// <param name="dayOfWeek">The day of week you want to get.</param>/// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>/// <returns></returns>publicstaticDateTimeGetNextDate(thisDateTime date,DayOfWeek dayOfWeek,bool exclDate =true){//note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today//eg: date - Today = 0 - 1 = -1, so have to move it forwardvar diff = dayOfWeek - date.DayOfWeek;var ddiff = date.Date.Subtract(DateTime.Today).Days+ diff;//note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in//note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on dateif(ddiff <0|| ddiff >=(exclDate ?6:7)&& diff <0)
diff +=7;//note: now we can get safe values between 0 - 6, especially if past dates is being used
diff = diff %7;//note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
diff += diff ==0& exclDate ?7:0;return date.AddDays(diff);}}
beberapa kasus uji
[TestMethod]publicvoidTestNextDate(){var date =newDateTime(2013,7,15);var start = date;//testing same month - forwardOnlyAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//16Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//17Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//18Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//19Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Saturday));//20Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Sunday));//21Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Monday));//22//testing same month - include dateAssert.AreEqual(start = date, date.GetNextDate(DayOfWeek.Monday,false));//15Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday,false));//16Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday,false));//17//testing month change - forwardOnly
date =newDateTime(2013,7,29);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//30Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//2013/09/01-month increasedAssert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//02//testing year change
date =newDateTime(2013,12,30);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//2014/01/01 - year increasedAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//02}
Saya telah membuat perubahan tambahan dari jawaban awal setelah beberapa pengujian ekstensif. Ini sekarang akan menghitung dengan aman hari berikutnya berdasarkan tanggal yang digunakan, masa lalu, sekarang dan masa depan. Semua contoh sebelumnya di mana hebat, tetapi gagal dalam kondisi tertentu. Saya tidak menjadikannya pernyataan satu baris, sehingga komentar tambahan dapat dibuat untuk apa yang dilakukan perhitungan. Kasus positif oleh Jon Skeet sangat bagus, meskipun kasus yang saya miliki adalah pindah 1 hari kembali dari kencan, tetapi masih lebih besar dari Hari ini, dan bagaimana jika pindah ke hari ini atau kemarin ... ini menyelesaikannya.
AJB
1
Ini bisa menjadi perpanjangan juga, itu semua tergantung
publicstaticclassDateTimeExtensions{publicstaticIEnumerable<DateTime>Next(thisDateTime date,DayOfWeek day){// This loop feels expensive and useless, but the point is IEnumerablewhile(true){if(date.DayOfWeek== day){yieldreturn date;}
date = date.AddDays(1);}}}
Pemakaian
var today =DateTime.Today;foreach(var monday in today.Next(DayOfWeek.Monday)){Console.WriteLine(monday);Console.ReadKey();}
Jawaban:
Seperti yang saya sebutkan di komentar, ada berbagai hal yang dapat Anda maksud dengan "Selasa depan", tetapi kode ini memberi Anda "Selasa berikutnya untuk terjadi, atau hari ini jika sudah Selasa":
Jika Anda ingin memberi "waktu seminggu" jika sudah Selasa, Anda dapat menggunakan:
... atau Anda dapat menggunakan rumus asli, tetapi mulai besok:
EDIT: Hanya untuk menjadikan ini menyenangkan dan serbaguna:
Jadi untuk mendapatkan nilai untuk "hari ini atau dalam 6 hari ke depan":
Untuk mendapatkan nilai "Selasa berikutnya tidak termasuk hari ini":
sumber
+7)%7
solusi adalah cukup bagus meskipun. Meskipun alasan saya tidak menggunakannya adalah karena itu sedikit optimasi mikro dan terlalu mudah salah (serta mengorbankan beberapa keterbacaan), tentu saja.Ini harus melakukan trik:
sumber
.AddDays(1)
dari baris pertama, dengan begitu ia akan memeriksaDateTime.Now
sendiri.Ada solusi yang kurang verbose dan lebih pintar / elegan untuk masalah ini, tetapi fungsi C # berikut bekerja dengan sangat baik untuk sejumlah situasi.
sumber
sumber
@ Jon Skeet jawaban yang bagus.
Untuk Hari sebelumnya:
Terima kasih!!
sumber
DayOfWeek
nilai - nilai seperti ini:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
sumber
Sampel yang sangat sederhana untuk memasukkan atau mengecualikan tanggal saat ini, Anda menentukan tanggal dan hari minggu Anda tertarik.
beberapa kasus uji
sumber
Ini bisa menjadi perpanjangan juga, itu semua tergantung
Pemakaian
sumber
Sekarang dalam rasa oneliner - jika Anda perlu mengirimkannya sebagai parameter ke beberapa mekanisme.
Dalam kasus khusus ini:
sumber
Versi C Tujuan:
sumber