Làm thế nào tôi có thể nhận được DateTime cho sự bắt đầu của tuần?


469

Làm cách nào để tôi tìm thấy đầu tuần (cả Chủ nhật và Thứ Hai) chỉ biết thời gian hiện tại trong C #?

Cái gì đó như:

DateTime.Now.StartWeek(Monday);

Câu trả lời:


746

Sử dụng một phương pháp mở rộng. Chúng là câu trả lời cho mọi thứ, bạn biết đấy! ;)

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

Có thể được sử dụng như sau:

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

15
Bạn có thể đơn giản hóa việc này như sau: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Troy

13
Troy, tôi không tin rằng mã của bạn hoạt động nếu ngày đã cho là Chủ nhật và đầu tuần của bạn là Thứ Hai. Nó sẽ trở lại (Chủ nhật + 1) thay vì (Chủ nhật - 6)
Aaron Hoffman

1
Điều này không có tác dụng nếu dtlà UTC và đã là sự bắt đầu của tuần ví dụ 2012-09-02 16:00:00Zđó là Mon, 03 Sep 2012 00:00:00theo giờ địa phương. Vì vậy, nó cần phải chuyển đổi dtsang giờ địa phương hoặc làm một cái gì đó thông minh hơn một chút. Nó cũng cần trả về kết quả là UTC nếu đầu vào là UTC.
hàng1

1
@ row1 DateTime.Parse("2012-09-02 16:00:00Z")trả về tương đương giờ địa phương và phương thức này trả về chính xác cùng thời gian, như một giờ địa phương. Nếu bạn sử dụng DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()để vượt qua thời gian UTC một cách rõ ràng, phương pháp này trả về chính xác 6 ngày, sớm hơn 16 giờ, dưới dạng thời gian UTC. Nó hoạt động chính xác như tôi mong đợi.
Rawling

1
Điều này đôi khi sẽ được tắt cho tôi một ngày. Nó làm việc cho tôi khi tôi tước thành phần thời gian dt. Tôi đã sử dụngint diff = dt.Date.DayOfWeek - startOfWeek;
Vincent Saelzler

80

Cách nhanh nhất tôi có thể đưa ra là:

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

Nếu bạn muốn bất kỳ ngày nào khác trong tuần là ngày bắt đầu của bạn, tất cả những gì bạn cần làm là thêm giá trị DayOfWeek vào cuối

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
câu trả lời đơn giản nhất là tốt nhất, câu trả lời này hoạt động tốt, nhưng văn hóa phụ thuộc
Cerveser

7
Ở Latvia tuần bắt đầu vào thứ Hai .. Thật ra .. tôi luôn tự hỏi làm thế nào một tuần có thể bắt đầu vào Chủ nhật .. có vẻ khó xử với tôi ..;)
0xDEAD BEEF

Giải pháp này là tốt. Ngoài ra, bạn có thể bắt đầu tuần bất kỳ ngày nào bằng cách thêm DayOfWeek bạn muốn bắt đầu. var sunday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var monday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans

7
Mã được thêm này không hoạt động cho tình huống được mô tả bởi Threezol. Nếu bạn muốn đầu tuần là thứ Hai, vào Chủ nhật, phép tính mang lại cho bạn vào thứ Hai tới chứ không phải trước đó.
Giovanni B

4
Có .. Đối với chủ nhật, nó cung cấp cho Modnay tiếp theo .. không phải trước đó: P
Ajay Aradhya

64

Một chút dài dòng và nhận thức văn hóa:

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
có lỗi với điều này: hôm nay = SUNDAY; fdow = NGÀY; (hôm nay - fdow) == -1; DateTime.Now.AddDays (- (- 1)). Date == DateTime.Now.AddDays (+1) .Date; 01/02/2012! = 25-01-2010 !!
balexandre

3
Nếu bạn thử điều này vào Chủ nhật, thì về cơ bản, nó đang thực hiện AddDays (0 - 1) cho en-GB. Vì vậy, nó cần @ Sarcastic's if statement
Chris S

3
Bạn cũng có thể có được văn hóa hiện tại bằng cách sử dụng CultureInfo.CurrentCulturethay vì kéo nó ra khỏi chuỗi như thế. Có vẻ như một cách kỳ lạ để truy cập nó.
Hank

7
Một vấn đề khác: Thật nguy hiểm khi gọi Nowtài sản hai lần. Nếu thời gian hiện tại xảy ra để vượt qua 24:00 (hoặc 12:00 nửa đêm) giữa hai cuộc gọi, ngày sẽ thay đổi.
Jeppe Stig Nielsen

1
Câu trả lời này thực sự là gì: "bên trong tuần .NET hiện tại (bắt đầu từ chủ nhật và kết thúc vào thứ bảy, theo cách đánh số của bảng liệt kê DayOfWeek), hãy tìm ngày của tuần .NET là ngày đầu tiên trong tuần trong nền văn hóa hiện tại ". Đây có lẽ không phải là những gì bạn muốn.
Mathieu

36

Sử dụng Fluent DateTime :

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

29
Tôi ghét phải phụ thuộc vào điều này. "Biết phụ thuộc của bạn và giết chúng" dường như đến với tâm trí. :)
Esteban Araya

7
Có ai để ý làm thế nào "Fluent" đang làm việc? Chỉ cần nhìn vào mã. Đó là sử dụng vòng lặp do ... while. Đừng muốn gọi nó bằng tên nhưng nếu tôi quyết định làm thì sẽ không dễ chịu gì. public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
nsimeonov

10
@nsimeonov nó là nguồn mở. xin vui lòng cung cấp một thực hiện tốt hơn thay vì ném đá.
Simon

12
Vâng, như thể tôi đã có tất cả thời gian trên thế giới để sửa từng lỗi trong mọi phần mềm nguồn mở trên thế giới ...
nsimeonov

4
Tôi đã phải bình luận vì tôi đã nhận được một tiếng cười lớn từ khiếu nại về việc sử dụng vòng lặp "làm ... trong khi"! Vui nhộn! Tôi chưa bao giờ nghe một lập trình viên khác rùng mình về một vòng lặp trước đây. Rất thích nhìn thấy khuôn mặt của chú hề này khi / nếu anh ta nhận ra những gì mã của mình thực sự biên dịch thành.
Josh Stodola

22

Xấu xí nhưng ít nhất nó cũng trả lại đúng ngày

Với đầu tuần được thiết lập bởi hệ thống:

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

Không có:

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

3
Điều này thực sự xứng đáng nhiều phiếu bầu vì sự đơn giản và dễ đọc của nó.
ProfK

Tài nguyên này cũng giúp: markb.uk/ ((Nếu bạn muốn có được ngày đầu tiên / ngày cuối cùng của một tuần hoặc tháng).
FranzHuber23

13

Hãy kết hợp câu trả lời an toàn văn hóa và câu trả lời phương pháp mở rộng:

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
không phải dt hay startOfWeek đều được sử dụng trong chức năng của bạn, tôi đoán cái đầu tiên nên được sử dụng thay vì DateTime.Today
hultqvist

2
Bối cảnh của câu hỏi là muốn một thuộc tính bổ sung sử dụng ngoài Thời gian theo cách tương tự như .Today hoặc .Now. Tôi đồng ý điều này thật khó xử, nhưng đó là những gì được yêu cầu.
Joel Coehoorn

7
Tôi biết đây là một câu trả lời cũ, nhưng nó sai ở rất nhiều cấp độ; ngoài việc hoàn toàn bỏ qua các đối số phương thức, toán học sẽ khiến nó chọn một ngày trong tương lai trong nhiều trường hợp. Điều này nên được viết để sử dụng dtthay vì DateTime.Today, để bọc toán học (offset + 7) % 7để đảm bảo bù trừ âm, sử dụng quá tải phương thức tham số duy nhất vượt qua văn hóa hiện tại FirstDayOfWeeklàm startOfWeekđối số và có thể (tùy thuộc vào thông số kỹ thuật) để ép buộc không bù vào mức bù 7 ngày, do đó "Thứ Ba tuần trước" sẽ không trở lại vào hôm nay nếu đó là Thứ Ba.
Aaronaught

10

Điều này sẽ cung cấp cho bạn vào Chủ nhật trước (tôi nghĩ):

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

9

Đây có thể là một chút hack, nhưng bạn có thể chuyển thuộc tính .DayOfWeek thành int (đó là enum và vì nó không có kiểu dữ liệu cơ bản của nó đã thay đổi thành int) và sử dụng nó để xác định đầu tuần trước .

Nó xuất hiện tuần được chỉ định trong enum DayOfWeek bắt đầu vào Chủ nhật, vì vậy nếu chúng ta trừ đi 1 từ giá trị này sẽ bằng với số ngày thứ Hai trước ngày hiện tại. Chúng ta cũng cần ánh xạ Chủ nhật (0) bằng 7, do đó, 1 - 7 = -6 Chủ nhật sẽ ánh xạ sang Thứ Hai trước: -

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

Mã cho Chủ nhật trước đơn giản hơn vì chúng tôi không phải thực hiện điều chỉnh này: -

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

9

Cho thứ hai

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

Cho chủ nhật

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

1
Tôi có một nhu cầu ứng dụng khác nhau, tuy nhiên tôi đã sử dụng điều này để đưa tôi đi. Tôi thích nó bởi vì nó là đơn giản nhất, không có bất kỳ sự phân vai nào - giữ cho các hoạt động trong cùng loại / thích hợp.
qxotk

1
Điều này không làm việc khi ngày là Chủ nhật. Nó cho thứ hai sau, không phải là bắt đầu của tuần hiện tại.
Cấp J

Bạn cũng đã sao chép vào Chủ nhật hoặc Thứ Hai. Tôi có 2 câu trả lời Một nếu bạn muốn cho thứ Hai và 2 giờ nếu bạn muốn vào Chủ nhật ..... Tôi vừa thử nó và nó hoạt động tốt với tôi. DateTime.Now.DayOfWeek; Chủ nhật và kết quả DateTime.Now.AddDays (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55} Ngày: {10/11/2019 12:00:00 πμ} Ngày: 10 DayOfWeek: Chủ nhật NgàyOfYear: 314 Giờ: 16 Loại: Millisecond địa phương: 172 Phút: 14 Tháng : 11 Thứ hai: 55 Thủ thuật: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} Năm: 2019
George Stavrou

@GrantJ Bạn đã dùng dòng nào ??? Tôi chỉ thử nghiệm và nó hoạt động tốt.
George Stavrou

Tôi đã thử cái đầu tiên, thay thế DateTime của bạn. Bây giờ bằng DateTime đại diện cho Chủ nhật ngày 10 tháng 11 năm 2019. Nó sẽ cung cấp cho Thứ Hai ngày 4 tháng 11 năm 2019 nhưng nó sẽ cho Thứ Hai ngày 11 tháng 11 năm 2019. Tôi đã thiết lập một câu đố chứng minh điều đó tại đây: dotnetfiddle.net/ Jw3ZiO
Cấp 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
Trước hết, chào mừng đến với cộng đồng :) Đã có một số câu trả lời chất lượng cao cho câu hỏi này, hầu hết trong số đó đã được đăng bảy năm trước khi câu hỏi được hỏi. Mặc dù nó có thể là một bài tập đáng giá để cố gắng trả lời các câu hỏi đơn giản như câu hỏi này để tăng thêm khả năng lập trình của bạn, nhưng việc đăng câu trả lời này ở trạng thái hiện tại không thêm bất cứ điều gì vào câu hỏi. Nếu có điều gì đó mới lạ về câu trả lời của bạn, vui lòng lấy một vài câu để giải thích nó khác nhau như thế nào và tại sao điều đó làm cho nó tốt hơn.
MTCoster

4

Kết hợp tất cả lại với Toàn cầu hóa và cho phép chỉ định ngày đầu tuần là một phần của cuộc gọi chúng tôi có

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;

}

4
var now = System.DateTime.Now;

var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;

2

Điều này sẽ cung cấp cho bạn nửa đêm vào Chủ nhật đầu tiên của tuần:

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

Điều này mang lại cho bạn thứ Hai đầu tiên vào lúc nửa đêm:

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

2

hãy thử với điều này trong c # .Với mã này, bạn có thể nhận được cả ngày đầu tiên và ngày cuối cùng của một tuần nhất định. Chủ nhật là ngày đầu tiên và thứ bảy là ngày cuối cùng nhưng bạn có thể đặt cả hai ngày theo văn hóa của mình

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

Đã thử một số nhưng không giải quyết được vấn đề với một tuần bắt đầu vào thứ Hai, dẫn đến việc cho tôi vào thứ Hai tới vào Chủ nhật. Vì vậy, tôi đã sửa đổi nó một chút và làm cho nó hoạt động với mã này:

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

Có vẻ như vấn đề của 'Thứ Hai sắp tới' phụ thuộc vào văn hóa (xem thêm câu trả lời từ Eric và nhận xét từ Cerveser.) Tuy nhiên, nếu bạn không cần tính đến Chủ nhật (như các cuộc hẹn kinh doanh thông thường), công thức của bạn có thể đơn giản hóa:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Damian Vogel

2

Bước 1: Tạo một lớp tĩnh

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

Bước 2: Sử dụng lớp này để có được cả ngày bắt đầu và ngày kết thúc trong tuần

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

Cuối tuần cần thiết (6 - (dt.DayOfWeek - startOfWeek)) % 7cho tôi so với các bài kiểm tra đơn vị tôi đã viết.
mlhDev

1

Phương thức sau sẽ trả về DateTime mà bạn muốn. Vượt qua đúng vào Chủ nhật là ngày đầu tuần, sai cho thứ Hai:

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

Cảm ơn các ví dụ. Tôi cần phải luôn luôn sử dụng "Hiện tại" trong ngày đầu tuần và đối với một mảng tôi cần biết chính xác Daynumber .. vì vậy đây là các tiện ích mở rộng đầu tiên của tôi:

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

Không ai có vẻ đã trả lời chính xác này. Tôi sẽ dán giải pháp của tôi ở đây trong trường hợp bất cứ ai cần nó. Các mã sau đây làm việc bất kể nếu ngày đầu tiên của tuần này là một thứ hai hoặc một chủ nhật hay cái gì khác.

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 trong C # hoạt động không tốt cho -1mod7 (nên là 6, c # trả về -1) vì vậy ... giải pháp "oneliner" cho việc này sẽ giống như thế này :)

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

1

Tương tự cho cuối tuần (theo kiểu của @Compile Đây là câu trả lời):

    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

Bạn có thể sử dụng thư viện ô tuyệt vời :

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

Tuy nhiên, họ làm dường như đã được lưu trữ thứ hai là ngày đầu tiên của tuần (xem tài sản nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn), do đó giải pháp cục bộ trước là một chút tốt hơn. Thật không may.

Chỉnh sửa : nhìn kỹ hơn vào câu hỏi, có vẻ như Umbrella thực sự cũng có thể hoạt động cho điều đó:

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

Mặc dù đáng lưu ý rằng nếu bạn yêu cầu Thứ Hai trước đó vào Thứ Hai, nó sẽ trả lại cho bạn bảy ngày. Nhưng điều này cũng đúng nếu bạn sử dụng BeginningOfWeek, có vẻ như là một lỗi :(.


0

Điều này sẽ trả lại cả ngày đầu tuần và ngày cuối tuần:

    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;

    }

Tôi đã đăng mã hoàn chỉnh để tính đầu / cuối tuần, tháng, quý và năm trên blog của tôi 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();
            }
        }
    } 

Bạn có thể mở rộng câu trả lời của bạn để bao gồm một lời giải thích về mã của bạn? Nó giúp người đọc nhiều hơn bạn nghĩ.
gunr2171

Sử dụng đệ quy là một thực hiện rất kém. Chỉ vì bạn có thể sử dụng thu hồi không có nghĩa là bạn nên. Nó sẽ chậm hơn và tốn nhiều bộ nhớ hơn các giải pháp khác được cung cấp ở đây.
mikecamimo

0

Dưới đây là sự kết hợp của một vài câu trả lời. Nó sử dụng một phương thức mở rộng cho phép văn hóa được truyền vào, nếu không được truyền vào, văn hóa hiện tại được sử dụng. Điều này sẽ cung cấp cho nó tính linh hoạt tối đa và tái sử dụng.

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

Cách sử dụng ví dụ:

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

nếu bạn muốn thứ bảy hoặc chủ nhật hoặc bất kỳ ngày nào trong tuần nhưng không vượt quá tuần hiện tại (Sat-Sun) tôi đã giúp bạn được bảo vệ với đoạn mã này.

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

Chúng tôi thích một lớp lót: Nhận sự khác biệt giữa ngày đầu tiên của văn hóa hiện tại và ngày hiện tại sau đó trừ đi số ngày kể từ ngày hiện tại

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

0

Tiếp theo từ Biên dịch Câu trả lời này, hãy sử dụng phương pháp sau để lấy ngày cho bất kỳ ngày nào trong tuần:

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

Cố gắng tạo một hàm sử dụng đệ quy. Đối tượng DateTime của bạn là một đầu vào và hàm trả về một đối tượng DateTime mới, là viết tắt của đầu tuần.

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

Mặc dù mã này có thể giải quyết câu hỏi, bao gồm giải thích về cách thức và lý do giải quyết vấn đề này thực sự sẽ giúp cải thiện chất lượng bài đăng của bạn và có thể dẫn đến nhiều lượt bình chọn hơn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai, không chỉ người hỏi bây giờ. Vui lòng chỉnh sửa câu trả lời của bạn để thêm giải thích và đưa ra dấu hiệu về những hạn chế và giả định được áp dụng.
David Buck

0

Tính toán theo cách này cho phép bạn chọn ngày nào trong tuần cho biết bắt đầu một tuần mới (trong ví dụ tôi chọn vào thứ Hai).

Lưu ý rằng thực hiện phép tính này cho một ngày là Thứ Hai sẽ cho Thứ Hai hiện tại chứ không phải thứ Hai trước đó.

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