ฉันจะรับ DateTime ในช่วงต้นสัปดาห์ได้อย่างไร


469

ฉันจะหาจุดเริ่มต้นของสัปดาห์ได้อย่างไร (ทั้งวันอาทิตย์และวันจันทร์) รู้เพียงเวลาปัจจุบันใน C #

สิ่งที่ต้องการ:

DateTime.Now.StartWeek(Monday);

คำตอบ:


746

ใช้วิธีการขยาย พวกเขาคือคำตอบของทุกสิ่งคุณรู้! ;)

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
}

ซึ่งสามารถใช้ดังนี้:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);

15
คุณสามารถทำให้สิ่งนี้ง่ายขึ้นดังต่อไปนี้: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Troy

13
ทรอยฉันไม่เชื่อว่ารหัสของคุณจะทำงานหากวันที่กำหนดเป็นวันอาทิตย์และวันเริ่มต้นของคุณคือวันจันทร์ มันจะกลับมา (วันอาทิตย์ + 1) แทน (วันอาทิตย์ - 6)
แอรอนฮอฟฟ์แมน

1
ไม่สามารถใช้งานได้หากdtเป็น UTC และเป็นจุดเริ่มต้นของสัปดาห์เช่น2012-09-02 16:00:00Zซึ่งอยู่Mon, 03 Sep 2012 00:00:00ในเวลาท้องถิ่น ดังนั้นจึงต้องเปลี่ยนdtเป็นเวลาท้องถิ่นหรือทำอะไรที่ฉลาดกว่านี้ นอกจากนี้ยังจะต้องส่งคืนผลลัพธ์เป็น UTC หากอินพุตเป็น UTC
แถว

1
@ row1 DateTime.Parse("2012-09-02 16:00:00Z")ส่งคืนเวลาท้องถิ่นและวิธีการนี้จะส่งกลับเวลาเดียวกันตามเวลาท้องถิ่น หากคุณใช้DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()เพื่อผ่านเวลา UTC อย่างชัดเจนวิธีนี้จะส่งคืนอย่างถูกต้อง 6 วันก่อนหน้านี้ 16 ชั่วโมงเป็นเวลา UTC มันทำงานตรงตามที่ฉันคาดหวัง
Rawling

1
บางครั้งฉันก็ต้องปิดตัวลงวันนี้ dtจะทำงานให้ฉันเมื่อฉันถอดส่วนประกอบเวลาจาก ฉันใช้int diff = dt.Date.DayOfWeek - startOfWeek;
Vincent Saelzler

80

วิธีที่เร็วที่สุดที่ฉันจะได้คือ:

var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);

หากคุณต้องการให้วันอื่น ๆ ของสัปดาห์เป็นวันที่เริ่มต้นสิ่งที่คุณต้องทำคือเพิ่มค่า DayOfWeek ไปยังจุดสิ้นสุด

var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday); 

2
คำตอบที่ง่ายที่สุดคือสิ่งที่ดีที่สุดอันนี้ใช้ได้ดี แต่วัฒนธรรมขึ้นอยู่กับมัน
Cerveser

7
ในลัตเวียสัปดาห์เริ่มต้นในวันจันทร์ .. ที่จริง .. ฉันมักจะสงสัยว่าสัปดาห์จะเริ่มต้นในวันอาทิตย์ได้อย่างไร .. ดูเหมือนจะอึดอัดใจฉัน .. ;)
0xDEAD BEEF

วิธีนี้ดี นอกจากนี้คุณสามารถเริ่มต้นสัปดาห์ได้ทุกวันโดยเพิ่ม DayOfWeek ที่คุณต้องการเริ่ม var sunday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var monday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans

7
รหัสที่เพิ่มนี้ไม่สามารถใช้งานได้สำหรับสถานการณ์ที่อธิบายโดย Threezol หากคุณต้องการให้การเริ่มต้นของสัปดาห์เป็นวันจันทร์ในวันอาทิตย์การคำนวณจะให้คุณในวันจันทร์ที่จะมาถึงไม่ใช่วันก่อนหน้า
Giovanni B

4
ใช่ .. สำหรับวันอาทิตย์จะให้ Modnay ต่อไป .. ไม่ใช่ก่อนหน้านี้: P
Ajay Aradhya

64

รายละเอียดเล็ก ๆ น้อย ๆ และตระหนักถึงวัฒนธรรม:

System.Globalization.CultureInfo ci = 
    System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
DayOfWeek today = DateTime.Now.DayOfWeek;
DateTime sow = DateTime.Now.AddDays(-(today - fdow)).Date;

4
มีข้อผิดพลาดกับสิ่งนี้: วันนี้ = วันอาทิตย์; fdow = วันจันทร์; (วันนี้ - fdow) == -1; DateTime.Now.AddDays (- (- - 1)) วันที่ == DateTime.Now.AddDays (+1) วันที่; 01-02-2010! = 25-01-2010 !!
balexandre

3
หากคุณลองทำในวันอาทิตย์โดยทั่วไปจะใช้ AddDays (0 - 1) สำหรับ en-GB ดังนั้นต้องใช้ @ Sarcastic ถ้าคำสั่ง
Chris S

3
นอกจากนี้คุณยังสามารถรับวัฒนธรรมปัจจุบันโดยใช้CultureInfo.CurrentCultureแทนที่จะดึงออกจากเธรดเช่นนั้น ดูเหมือนว่าเป็นวิธีที่แปลกในการเข้าถึง
แฮงค์

7
ปัญหาอื่น: มันเป็นอันตรายที่จะเรียกNowคุณสมบัติสองครั้ง หากเวลาปัจจุบันเกิดขึ้นผ่านเวลา 24:00 น. (หรือ 12:00 น. เที่ยงคืน) ระหว่างสองสายวันที่จะเปลี่ยนไป
Jeppe Stig Nielsen

1
สิ่งที่คำตอบนี้จริง ๆ แล้วคือ: "ภายในสัปดาห์. NET ปัจจุบัน (เริ่มในวันอาทิตย์และสิ้นสุดในวันเสาร์ตามการนับจำนวนของการแจงนับ DayOfWeek) ค้นหาวันของ. NET สัปดาห์ที่เป็นสัปดาห์แรกของสัปดาห์ ในวัฒนธรรมปัจจุบัน ". นี่อาจไม่ใช่สิ่งที่คุณต้องการ
Mathieu Renda

36

ใช้DateTime อย่างคล่องแคล่ว :

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);

29
ฉันเกลียดที่จะพึ่งพาเพียงแค่นี้ "รู้จักการพึ่งพาของคุณและฆ่าพวกมัน" ดูเหมือนจะเข้ามาในใจ :)
Esteban Araya

7
ไม่มีใครสังเกตเห็นว่า "คล่องแคล่ว" ทำงานอย่างไร เพียงแค่ดูรหัส ใช้ do ... ในขณะที่วนซ้ำ ไม่ต้องการเรียกชื่อ แต่ถ้าฉันตัดสินใจจะไม่พอใจ public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
nsimeonov

10
@snimeonov มันเป็นโอเพนซอร์ส โปรดส่งการดำเนินการที่ดีขึ้นแล้วโยนหิน
Simon

12
ใช่ราวกับว่าฉันมีเวลาทั้งหมดในโลกเพื่อแก้ไขข้อผิดพลาดทุกครั้งในซอฟต์แวร์โอเพนซอร์ซทุกแห่งในโลก ...
nsimeonov

4
ฉันต้องแสดงความคิดเห็นเพราะฉันได้รับเสียงหัวเราะขนาดใหญ่จากการร้องเรียนเกี่ยวกับการใช้ "ทำ ... ในขณะที่" วนรอบ! เฮฮา! ฉันไม่เคยได้ยินโปรแกรมเมอร์ตัวสั่นเกี่ยวกับลูปมาก่อน จะรักที่จะเห็นใบหน้าของตัวตลกนี้เมื่อ / ถ้าเขาเคยตระหนักถึงสิ่งที่รหัสของเขารวบรวมจริงๆลงไป
Josh Stodola

22

น่าเกลียด แต่อย่างน้อยก็ให้วันที่ถูกต้องกลับมา

ด้วยการเริ่มต้นของสัปดาห์ที่กำหนดโดยระบบ:

    public static DateTime FirstDateInWeek(this DateTime dt)
    {
        while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
            dt = dt.AddDays(-1);
        return dt;
    }

โดยไม่ต้อง:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }

3
นี่สมควรได้รับการโหวตมากขึ้นสำหรับความเรียบง่ายและการอ่านของมัน
ProfK

ทรัพยากรนี้ก็มีส่วนช่วยเช่น: markb.uk/… (หากคุณต้องการรับวันแรก / สุดท้ายของสัปดาห์หรือเดือน)
FranzHuber23

13

รวมคำตอบที่ปลอดภัยต่อวัฒนธรรมเข้ากับคำตอบของวิธีการขยาย:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
        return DateTime.Today.AddDays(-(DateTime.Today.DayOfWeek- fdow));
    }
}

12
ไม่ใช้ dt หรือ startOfWeek ในฟังก์ชั่นของคุณฉันเดาว่าควรใช้อันแรกแทน DateTime วันนี้
hultqvist

2
บริบทของคำถามต้องการทรัพย์สินเพิ่มเติมเพื่อใช้นอก Datetime ในลักษณะเดียวกับ. วันนี้หรือ. ตอนนี้ ฉันเห็นด้วยกับสิ่งนี้อย่างงุ่มง่าม แต่มันเป็นสิ่งที่ถูกถาม
Joel Coehoorn

7
ฉันรู้ว่านี่เป็นคำตอบเก่า แต่มันก็ผิดในหลาย ๆ ระดับ นอกจากจะเพิกเฉยต่อข้อโต้แย้งของวิธีโดยสิ้นเชิงแล้วคณิตศาสตร์จะทำให้มันเลือกวันที่ในอนาคตในหลายกรณี สิ่งนี้ควรถูกเขียนขึ้นเพื่อใช้dtแทนDateTime.Todayการห่อหุ้มคณิตศาสตร์ใน(offset + 7) % 7เพื่อให้แน่ใจว่ามีออฟเซ็ตเชิงลบเพื่อใช้การโอเวอร์โหลดเมธอดแบบพารามิเตอร์เดียวซึ่งส่งผ่านวัฒนธรรมปัจจุบันของFirstDayOfWeekการstartOfWeekโต้แย้งและอาจเป็นไปได้ (ขึ้นอยู่กับสเป็ค) ศูนย์ชดเชยให้กับการชดเชย 7 วันดังนั้น "วันอังคารที่ผ่านมา" จะไม่กลับมาในวันนี้ถ้ามันเป็นวันอังคารแล้ว
Aaronaught

10

นี่จะทำให้คุณอาทิตย์ก่อนหน้านี้ (ฉันคิดว่า):

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0);

9

นี่อาจเป็นบิตของการแฮ็ก แต่คุณสามารถส่งคุณสมบัติ. DayOfWeek ไปยัง int (เป็น enum และเนื่องจากไม่มีชนิดข้อมูลพื้นฐานเปลี่ยนเป็นค่าเริ่มต้นเป็น int) และใช้เพื่อกำหนดจุดเริ่มต้นของสัปดาห์ก่อนหน้า .

ดูเหมือนว่าสัปดาห์ที่ระบุใน enum DayOfWeek เริ่มต้นในวันอาทิตย์ดังนั้นหากเราลบ 1 จากค่านี้จะเท่ากับจำนวนวันจันทร์ก่อนหน้าวันที่ปัจจุบัน เราต้องทำแผนที่วันอาทิตย์ (0) ให้เท่ากับ 7 ด้วย 1 - 7 = -6 วันอาทิตย์จะจับคู่กับวันจันทร์ก่อนหน้า: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);

รหัสสำหรับวันอาทิตย์ที่แล้วนั้นง่ายกว่าเนื่องจากเราไม่ต้องทำการปรับเปลี่ยน: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);

9

สำหรับวันจันทร์

DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);

สำหรับวันอาทิตย์

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);

1
ฉันมีความต้องการแอปพลิเคชันอื่น แต่ฉันใช้สิ่งนี้เพื่อให้ฉันไป ฉันชอบเพราะมันง่ายที่สุดโดยไม่มีการคัดเลือกใด ๆ - ทำให้การดำเนินงานในประเภทเดียวกัน / เหมาะสม
qxotk

1
สิ่งนี้ไม่ทำงานเมื่อวันนี้เป็นวันอาทิตย์ มันให้วันจันทร์ถัดไปไม่ใช่การเริ่มต้นของสัปดาห์ปัจจุบัน
Grant J

คุณคัดลอกวันอาทิตย์หรือวันจันทร์ด้วย ฉันมี 2 คำตอบหนึ่งข้อถ้าคุณต้องการในวันจันทร์และ 2 ข้อถ้าคุณต้องการในวันอาทิตย์ ..... ฉันแค่ทดสอบมันและมันก็ใช้ได้ดีสำหรับฉัน DateTime.Now.DayOfWeek; วันอาทิตย์และผลลัพธ์ DateTime ตอนนี้เพิ่มวัน (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55 μμ} วันที่: {10/11/2019 12:00:00 πμ} วัน: 10 DayOfWeek: วันอาทิตย์วันปี: 314 ชั่วโมง: 16 ชนิด: ท้องถิ่นมิลลิวินาที: 172 นาที: 14 เดือน : 11 วินาที: 55 เห็บ: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} ปี: 2019
George Stavrou

@GrantJ คุณใช้สายอะไร ??? ฉันเพิ่งทดสอบและใช้งานได้ดี
George Stavrou

ฉันลองตัวแรกแทน DateTime ของคุณตอนนี้ด้วย DateTime แทนวันอาทิตย์ที่ 10 พฤศจิกายน 2019 มันควรให้วันจันทร์ที่ 4 พฤศจิกายน 2019 แต่จะให้วันจันทร์ที่ 11 พฤศจิกายน 2019 ฉันตั้งซอที่แสดงให้เห็นที่นี่: dotnetfiddle.net/ Jw3ZiO
สิทธิ์ J

5
using System;
using System.Globalization;

namespace MySpace
{
    public static class DateTimeExtention
    {
        // ToDo: Need to provide culturaly neutral versions.

        public static DateTime GetStartOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.Subtract(TimeSpan.FromDays((int)dt.DayOfWeek));
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 0, 0, 0, 0);
        }

        public static DateTime GetEndOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.GetStartOfWeek().AddDays(6);
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 23, 59, 59, 999);
        }

        public static DateTime GetStartOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetStartOfWeek();
        }

        public static DateTime GetEndOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetEndOfWeek();
        }
    }
}

3
ก่อนอื่นยินดีต้อนรับสู่ชุมชน :) มีคำตอบที่มีคุณภาพสูงสำหรับคำถามนี้อยู่แล้วซึ่งส่วนใหญ่โพสต์เมื่อเจ็ดปีที่แล้วเมื่อคำถามถูกถาม ในขณะที่การฝึกตอบคำถามง่าย ๆ เช่นนี้อาจคุ้มค่าที่จะใช้เพื่อเพิ่มความสามารถในการเขียนโปรแกรมของคุณ แต่การโพสต์คำตอบนี้ในสถานะปัจจุบันจะไม่เพิ่มคำถามใด ๆ หากมีอะไรแปลกใหม่เกี่ยวกับคำตอบของคุณโปรดเขียนประโยคสองสามประโยคเพื่ออธิบายว่ามันแตกต่างกันอย่างไรและทำไมจึงทำให้ดีขึ้น
MTCoster

4

รวบรวมเข้าด้วยกันด้วยโลกาภิวัตน์และอนุญาตให้ระบุวันแรกของสัปดาห์เป็นส่วนหนึ่งของการโทรที่เรามี

public static DateTime StartOfWeek ( this DateTime dt, DayOfWeek? firstDayOfWeek )
{
    DayOfWeek fdow;

    if ( firstDayOfWeek.HasValue  )
    {
        fdow = firstDayOfWeek.Value;
    }
    else
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        fdow = ci.DateTimeFormat.FirstDayOfWeek;
    }

    int diff = dt.DayOfWeek - fdow;

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

    return dt.AddDays( -1 * diff ).Date;

}


2

นี่จะทำให้คุณเที่ยงคืนในวันอาทิตย์แรกของสัปดาห์:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, t.Hour, t.Minute, t.Second);

นี่จะทำให้คุณวันจันทร์แรกของเวลาเที่ยงคืน:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek - 1, t.Hour, t.Minute, t.Second);

2

ลองกับสิ่งนี้ใน c # ด้วยรหัสนี้คุณจะได้ทั้งวันแรกและวันสุดท้ายของสัปดาห์ที่กำหนดวันอาทิตย์ที่นี่เป็นวันแรกและวันเสาร์เป็นวันสุดท้าย แต่คุณสามารถตั้งค่าทั้งสองวันตามวัฒนธรรมของคุณ

DateTime firstDate = GetFirstDateOfWeek(DateTime.Parse("05/09/2012").Date,DayOfWeek.Sunday);
DateTime lastDate = GetLastDateOfWeek(DateTime.Parse("05/09/2012").Date, DayOfWeek.Saturday);

public static DateTime GetFirstDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime firstDayInWeek = dayInWeek.Date;
    while (firstDayInWeek.DayOfWeek != firstDay)
        firstDayInWeek = firstDayInWeek.AddDays(-1);

    return firstDayInWeek;
}
public static DateTime GetLastDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime lastDayInWeek = dayInWeek.Date;
    while (lastDayInWeek.DayOfWeek != firstDay)
        lastDayInWeek = lastDayInWeek.AddDays(1);

    return lastDayInWeek;
}

2

พยายามหลายครั้ง แต่ไม่ได้แก้ปัญหาด้วยหนึ่งสัปดาห์เริ่มในวันจันทร์ทำให้ฉันถึงวันจันทร์ที่จะมาถึงในวันอาทิตย์ ดังนั้นฉันแก้ไขมันเล็กน้อยและทำให้มันทำงานกับรหัสนี้:

int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;

ดูเหมือนว่าปัญหาของ 'วันจันทร์ที่จะมาถึง' นั้นขึ้นอยู่กับวัฒนธรรม (ดูคำตอบจาก Eric และความคิดเห็นจาก Cerveser) อย่างไรก็ตามหากคุณไม่จำเป็นต้องคำนึงถึงวันอาทิตย์ (เช่นเดียวกับการนัดหมายทางธุรกิจปกติ) สูตรของคุณสามารถ ง่าย:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
เดเมียน Vogel

2

ขั้นตอนที่ 1: สร้างคลาสแบบคงที่

  public static class TIMEE
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
    public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 - (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(1 * diff).Date;
    }
}

ขั้นที่ 2: ใช้คลาสนี้เพื่อรับทั้งวันเริ่มต้นและวันสุดท้ายของสัปดาห์

 DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
        DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);

ต้องใช้(6 - (dt.DayOfWeek - startOfWeek)) % 7เวลาสิ้นสุดสัปดาห์สำหรับการทดสอบหน่วยที่ฉันเขียน
mlhDev

1

วิธีการต่อไปนี้ควรกลับ DateTime ที่คุณต้องการ ผ่านเป็นจริงสำหรับวันอาทิตย์เป็นวันแรกของสัปดาห์เท็จสำหรับวันจันทร์:

private DateTime getStartOfWeek(bool useSunday)
{
    DateTime now = DateTime.Now;
    int dayOfWeek = (int)now.DayOfWeek;

    if(!useSunday)
        dayOfWeek--;

    if(dayOfWeek < 0)
    {// day of week is Sunday and we want to use Monday as the start of the week
    // Sunday is now the seventh day of the week
        dayOfWeek = 6;
    }

    return now.AddDays(-1 * (double)dayOfWeek);
}

1

ขอบคุณสำหรับตัวอย่าง ฉันต้องการใช้ "CurrentCulture" วันแรกของสัปดาห์และสำหรับอาร์เรย์ฉันจำเป็นต้องรู้ Daynumber แน่นอน .. ดังนั้นนี่คือส่วนขยายแรกของฉัน:

public static class DateTimeExtensions
{
    //http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
    //http://stackoverflow.com/questions/1788508/calculate-date-with-monday-as-dayofweek1
    public static DateTime StartOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return dt.AddDays(-1 * diff).Date;
    }

    public static int DayNoOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return diff + 1; //Make it 1..7
    }
}

1

ดูเหมือนว่าจะไม่มีใครตอบคำถามนี้อย่างถูกต้องเลย ฉันจะวางทางออกของฉันที่นี่ในกรณีที่ใครต้องการมัน รหัสต่อไปนี้ใช้งานได้โดยไม่คำนึงว่าวันแรกของสัปดาห์คือวันจันทร์หรือวันอาทิตย์หรืออย่างอื่น

public static class DateTimeExtension
{
  public static DateTime GetFirstDayOfThisWeek(this DateTime d)
  {
    CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
    var first = (int)ci.DateTimeFormat.FirstDayOfWeek;
    var current = (int)d.DayOfWeek;

    var result = first <= current ?
      d.AddDays(-1 * (current - first)) :
      d.AddDays(first - current - 7);

    return result;
  }
}

class Program
{
  static void Main()
  {
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
    Console.WriteLine("Current culture set to en-US");
    RunTests();
    Console.WriteLine();
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("da-DK");
    Console.WriteLine("Current culture set to da-DK");
    RunTests();
    Console.ReadLine();
  }

  static void RunTests()
  {
    Console.WriteLine("Today {1}: {0}", DateTime.Today.Date.GetFirstDayOfThisWeek(), DateTime.Today.Date.ToString("yyyy-MM-dd"));
    Console.WriteLine("Saturday 2013-03-02: {0}", new DateTime(2013, 3, 2).GetFirstDayOfThisWeek());
    Console.WriteLine("Sunday 2013-03-03: {0}", new DateTime(2013, 3, 3).GetFirstDayOfThisWeek());
    Console.WriteLine("Monday 2013-03-04: {0}", new DateTime(2013, 3, 4).GetFirstDayOfThisWeek());
  }
}

1

Modulo ใน C # ทำงานได้ไม่ดีสำหรับ -1mod7 (ควรเป็น 6, c # ส่งคืน -1) ดังนั้น ... โซลูชัน "oneliner" สำหรับสิ่งนี้จะมีลักษณะเช่นนี้ :)

private static DateTime GetFirstDayOfWeek(DateTime date)
    {
        return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
    }

1

เหมือนกันในตอนท้ายของสัปดาห์ (ในรูปแบบของ @Compile คำตอบนี้):

    public static DateTime EndOfWeek(this DateTime dt)
    {
        int diff = 7 - (int)dt.DayOfWeek;

        diff = diff == 7 ? 0 : diff;

        DateTime eow = dt.AddDays(diff).Date;

        return new DateTime(eow.Year, eow.Month, eow.Day, 23, 59, 59, 999) { };
    }

0

คุณสามารถใช้ห้องสมุด Umbrella ที่ยอดเยี่ยม:

using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();

แต่พวกเขาไม่ดูเหมือนจะได้เก็บไว้จันทร์เป็นวันแรกของสัปดาห์ (ดูสถานที่ให้บริการnVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn) เพื่อให้การแก้ปัญหาก่อนหน้านี้ที่มีการแปลเป็นบิตที่ดีกว่า โชคร้าย

แก้ไข : มองคำถามนี้ให้ละเอียดยิ่งขึ้นดูเหมือนว่า Umbrella อาจใช้งานได้จริงเช่นกัน:

// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday(); 
DateTime sunday = DateTime.Now.PreviousSunday();

แม้ว่าจะเป็นเรื่องน่าสังเกตว่าถ้าคุณขอวันจันทร์ก่อนหน้านี้ในวันจันทร์มันจะให้ผลตอบแทนเจ็ดวัน แต่นี่ก็เป็นจริงเช่นกันถ้าคุณใช้BeginningOfWeekซึ่งดูเหมือนว่าจะเป็นข้อผิดพลาด :(


0

สิ่งนี้จะส่งคืนทั้งต้นสัปดาห์และวันที่สิ้นสุดของสัปดาห์:

    private string[] GetWeekRange(DateTime dateToCheck)
    {
        string[] result = new string[2];
        TimeSpan duration = new TimeSpan(0, 0, 0, 0); //One day 
        DateTime dateRangeBegin = dateToCheck;
        DateTime dateRangeEnd = DateTime.Today.Add(duration);

        dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
        dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);

        result[0] = dateRangeBegin.Date.ToString();
        result[1] = dateRangeEnd.Date.ToString();
        return result;

    }

ฉันได้โพสต์รหัสที่สมบูรณ์สำหรับการคำนวณจุดเริ่มต้น / จุดสิ้นสุดของสัปดาห์เดือนไตรมาสและปีในบล็อกของฉัน ZamirsBlog


0
    namespace DateTimeExample
    {
        using System;

        public static class DateTimeExtension
        {
            public static DateTime GetMonday(this DateTime time)
            {
                if (time.DayOfWeek != DayOfWeek.Monday)
                    return GetMonday(time.AddDays(-1)); //Recursive call

                return time;
            }
        }

        internal class Program
        {
            private static void Main()
            {
                Console.WriteLine(DateTime.Now.GetMonday());
                Console.ReadLine();
            }
        }
    } 

คุณสามารถขยายคำตอบเพื่อรวมคำอธิบายรหัสของคุณได้หรือไม่? ช่วยให้ผู้อ่านมากกว่าที่คุณคิด
gunr2171

การใช้การเรียกซ้ำเป็นการใช้งานที่แย่มาก เพียงเพราะคุณสามารถใช้การเรียกซ้ำไม่ได้หมายความว่าคุณควร มันจะช้าลงและหน่วยความจำจะเข้มข้นกว่าโซลูชั่นอื่น ๆ
mikecamimo

0

นี่คือการรวมกันของคำตอบบางส่วน มันใช้วิธีการขยายที่ช่วยให้วัฒนธรรมที่จะผ่านเข้ามาหากไม่มีใครผ่านในวัฒนธรรมปัจจุบันจะใช้ สิ่งนี้จะให้ความยืดหยุ่นสูงสุดและนำกลับมาใช้ใหม่

/// <summary>
/// Gets the date of the first day of the week for the date.
/// </summary>
/// <param name="date">The date to be used</param>
/// <param name="cultureInfo">If none is provided, the current culture is used</param>
/// <returns>The date of the beggining of the week based on the culture specifed</returns>
public static DateTime StartOfWeek(this DateTime date, CultureInfo cultureInfo=null) =>         
             date.AddDays(-1 * (7 + (date.DayOfWeek - (cultureInfo??CultureInfo.CurrentCulture).DateTimeFormat.FirstDayOfWeek)) % 7).Date;

ตัวอย่างการใช้งาน:

public static void TestFirstDayOfWeekExtension() {          
        DateTime date = DateTime.Now;
        foreach(System.Globalization.CultureInfo culture in CultureInfo.GetCultures(CultureTypes.UserCustomCulture | CultureTypes.SpecificCultures)) {
            Console.WriteLine($"{culture.EnglishName}: {date.ToShortDateString()} First Day of week: {date.StartOfWeek(culture).ToShortDateString()}");
        }
    }

0

หากคุณต้องการวันเสาร์หรือวันอาทิตย์หรือวันใด ๆ ของสัปดาห์ แต่ไม่เกินสัปดาห์ปัจจุบัน (วันเสาร์ - อาทิตย์) ฉันได้รับคุณครอบคลุมด้วยรหัสชิ้นนี้

public static DateTime GetDateInCurrentWeek(this DateTime date, DayOfWeek day)
{
    var temp = date;
    var limit = (int)date.DayOfWeek;
    var returnDate = DateTime.MinValue;

    if (date.DayOfWeek == day) return date;

    for (int i = limit; i < 6; i++)
    {
        temp = temp.AddDays(1);

        if (day == temp.DayOfWeek)
        {
            returnDate = temp;
            break;
        }
    }
    if (returnDate == DateTime.MinValue)
    {
        for (int i = limit; i > -1; i++)
        {
            date = date.AddDays(-1);

            if (day == date.DayOfWeek)
            {
                returnDate = date;
                break;
            }
        }
    }
    return returnDate;
}

0

เราชอบผู้ให้บริการรายหนึ่ง: รับความแตกต่างระหว่างวันแรกของสัปดาห์วัฒนธรรมปัจจุบันและวันปัจจุบันจากนั้นลบจำนวนวันจากวันปัจจุบัน

var weekStartDate = DateTime.Now.AddDays(-((int)now.DayOfWeek - (int)DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek));

0

ทำตามจากรวบรวมคำตอบนี้ใช้วิธีการต่อไปนี้เพื่อรับวันสำหรับวันใด ๆ ของสัปดาห์:

public static DateTime GetDayOfWeek(this DateTime dt, DayOfWeek day)
{            
    int diff = (7 + (dt.DayOfWeek - DayOfWeek.Monday)) % 7;
    var monday = dt.AddDays(-1 * diff).Date;

    switch (day)
    {
        case DayOfWeek.Tuesday:
            return monday.AddDays(1).Date;

        case DayOfWeek.Wednesday:
            return monday.AddDays(2).Date;

        case DayOfWeek.Thursday:
            return monday.AddDays(3).Date;

        case DayOfWeek.Friday:
            return monday.AddDays(4).Date;

        case DayOfWeek.Saturday:
            return monday.AddDays(5).Date;

        case DayOfWeek.Sunday:
            return monday.AddDays(6).Date;
    }

    return monday;
}

0

ลองสร้างฟังก์ชั่นที่ใช้การเรียกซ้ำ วัตถุ DateTime ของคุณคืออินพุตและฟังก์ชันส่งคืนวัตถุ DateTime ใหม่ซึ่งหมายถึงการเริ่มต้นของสัปดาห์

    DateTime WeekBeginning(DateTime input)
    {
        do
        {
            if (input.DayOfWeek.ToString() == "Monday")
                return input;
            else
                return WeekBeginning(input.AddDays(-1));
        } while (input.DayOfWeek.ToString() == "Monday");
    }

แม้ว่ารหัสนี้อาจแก้ปัญหาได้รวมถึงคำอธิบายว่าทำไมและวิธีแก้ปัญหานี้จะช่วยปรับปรุงคุณภาพการโพสต์ของคุณได้อย่างไรและอาจส่งผลให้คะแนนมากขึ้น จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่เพียงแค่คนที่ถามตอนนี้ โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
เดวิดบั๊ก

0

การคำนวณด้วยวิธีนี้ช่วยให้คุณสามารถเลือกวันในสัปดาห์ที่บ่งบอกถึงการเริ่มต้นของสัปดาห์ใหม่ (ในตัวอย่างที่ฉันเลือกวันจันทร์)

โปรดทราบว่าการคำนวณนี้สำหรับวันที่เป็นวันจันทร์จะให้วันจันทร์ปัจจุบันไม่ใช่วันก่อนหน้า

//Replace with whatever input date you want
DateTime inputDate = DateTime.Now;

//For this example, weeks start on Monday
int startOfWeek = (int)DayOfWeek.Monday;

//Calculate the number of days it has been since the start of the week
int daysSinceStartOfWeek = ((int)inputDate.DayOfWeek + 7 - startOfWeek) % 7;

DateTime previousStartOfWeek = inputDate.AddDays(-daysSinceStartOfWeek);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.