2011-02-03 53 views
13

Điều tôi muốn làm là tạo một lịch đơn giản và tôi muốn tìm ngày đầu tiên của tuần đầu tiên của một tháng cụ thể. Lịch của tôi là thứ Hai -> Lịch chủ nhật và mã sau hoạt động, nhưng bạn có thể thấy nó không đẹp. Bất cứ ai có bất kỳ ý tưởng tốt hơn về làm thế nào để có được ngày đầu tiên trong lịch.Tìm ngày đầu tiên của lịch

var now = new DateTime(Year, Month, 1); 
now = now.AddDays(1-(int)now.DayOfWeek); 
now = now.Day > 15 ? now : now.AddDays(-7); 

Lịch sẽ kết thúc như thế này:

| < |  Jan 2011  | > | 
------------------------------------ 
| Mo | Tu | We | Th | Fr | Sa | Su | 
|[27]| 28 | 29 | 30 | 31 | 01 | 02 | 
| 03 | 04 | 05 | 06 | 07 | 08 | 09 | 
| .. | .. | .. | .. | .. | .. | .. | 
| .. | .. | .. | .. | .. | .. | .. | 
| 31 | 01 | 02 | 03 | 04 | 05 | 06 | 

Và trong "hình ảnh" đó là [27] Ngày mà tôi đang cố gắng để tìm.

Solution (Tìm thấy tôi tốt hơn/sạch hơn để lặp sau đó tính toán):

public DateTime FirstDay() 
    { 
     var date = new DateTime(Date.Year, Date.Month, 1); 
     while (true) 
     { 
      if (date.DayOfWeek == DayOfWeek.Monday) 
       return date; 
      date = date.AddDays(-1); 
     } 
     return date; 
    } 

    public DateTime LastDay() 
    { 
     var date = new DateTime(Date.Year, Date.Month, 
           DateTime.DaysInMonth(Date.Year, Date.Month)); 
     while (true) 
     { 
      if (date.DayOfWeek == DayOfWeek.Sunday) 
       return date; 
      date = date.AddDays(1); 
     } 
     return date; 
    } 

/BR Andreas

+4

+1, cho nghệ thuật ASCII. –

+0

+1 #wow, Thực ra tôi đã tạo một Lịch tương tự trong ứng dụng giao diện điều khiển với C trong trường Cao đẳng của tôi. –

Trả lời

9

Tôi sẽ làm điều này. Thật dễ hiểu:

var firstDayOfMonth = new DateTime(year, month, 1); 
DateTime startOfCalendar = 
    FirstDayOfWeekOnOrBefore(
     firstDayOfMonth, 
     DayOfWeek.Monday 
    ); 

public static DateTime FirstDayOfWeekOnOrBefore(
    DateTime date, 
    DayOfWeek dayOfWeek 
) { 
    while(date.DayOfWeek != dayOfWeek) { 
     date = date.AddDays(-1); 
    } 
    return date; 
} 

Ngoài ra, nếu bạn muốn thay đổi lịch để bắt đầu một thứ khác ngoài Thứ Hai, bây giờ là tầm thường. Một giải pháp sử dụng số học modulo sẽ không thể bảo trì được.

+0

tại sao điều này phức tạp đến vậy? các giải pháp đơn giản hơn nhiều tồn tại – user492238

+0

@ user492238 IMO mã này đơn giản hơn giải pháp của bạn (và của tôi). Vòng lặp kết thúc sau khi tối đa 7 lần lặp lại, do đó hiệu suất cũng tốt. – CodesInChaos

4

Bạn có thể sử dụng modulo để tính toán số ngày phụ mà không có một tuyên bố có điều kiện:

DateTime firstOfMonth=new DateTime(year,month,1); 
var weekDay=firstOfMonth.DayOfWeek; 
int fillerDays=((int)weekDay+6)%7; 
DateTime firstDayInCalendar=firstOfMonth.AddDays(-fillerDays); 
+0

Đẹp. Tôi không biết rằng có thể cast DayOfWeek thành int.Tôi luôn thấy nó hiển thị chuỗi ngày: "Thứ Hai". –

+0

@DougS Đó là một enum, và bạn có thể cast bất kỳ enum vào loại tích phân cơ bản. – CodesInChaos

+0

@ CodesInChaos: Tốt để biết. Cảm ơn! –

1

Bạn có thể thử giả ngày đầu tiên này ur đề cập đến là Thứ Hai

DateTime dt = new DateTime(2011, 2, 2); 
Console.WriteLine(dt.AddDays((8 - (int)dt.DayOfWeek) % 7)); 
+0

Nhưng tại sao? Nó không ngay lập tức dễ hiểu. Có mã rõ ràng hơn có thể được nắm bắt ngay lập tức. Bạn sẽ đánh giá cao viết nó trong ba tháng khi bạn cần phải duy trì một cái gì đó, hoặc trời cấm, sửa chữa một lỗi khó chịu trong nó bởi vì nó không rõ ràng. – jason

-1

UPDATE: Sau khi mã có một lỗi! Sử dụng số học modulo, để bù lại tình huống, .NET bắt đầu tuần chủ nhật! Xem các giải pháp khác ở đây (không có giải pháp nào có chức năng bổ sung).

Nếu bạn cần phải tìm ra "27" (tức là ngày đầu tiên cho màn hình hiển thị của một tháng) chỉ cần sử dụng này:

DateTime monthStart = new DateTime(year, month, 1); 
DateTime monthDisplayStart = monthStart.AddDays(-((int)monthStart.DayOfWeek - 1)); 
+0

whats the downvote cho? – user492238

+1

Tôi không phải là người bỏ phiếu xuống, nhưng tôi nghi ngờ rằng mã của bạn không hoạt động trong một ngày có thể vì .net thấy Chủ nhật là ngày đầu tiên trong tuần và Thứ Hai OP. – CodesInChaos

+0

Mã này có lỗi, ý nghĩa của nó không rõ ràng ngay lập tức và không thể duy trì được. – jason

1

Tôi không giống như vòng lặp while, bởi vì họ là tốn kém khi sử dụng với LINQ
Hope người khác có thể tái sử dụng mã này: (nếu bạn đang ở Mỹ, sau đó chỉ cần xóa [+ 6)% 7)] trong hai dòng)

/// <summary> 
    /// Expands the month. 
    /// | < |  Jan 2011  | > | 
    /// ------------------------------------ 
    /// | Mo | Tu | We | Th | Fr | Sa | Su | 
    /// |[27]| 28 | 29 | 30 | 31 | 01 | 02 | 
    /// | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 
    /// | .. | .. | .. | .. | .. | .. | .. | 
    /// | .. | .. | .. | .. | .. | .. | .. | 
    /// | 31 | 01 | 02 | 03 | 04 | 05 | 06 | 
    /// </summary> 
    /// <param name="start">Some day in the month of interest, the start date is updated to become the date of firstDayInCalendar</param> 
    /// <returns>The number of days to show. This value is either (28, 35 or 42)</returns> 
    public static int ExpandMonth(ref DateTime start) 
    { 
     DateTime first = new DateTime(start.Year, start.Month, 1); 
     DateTime last = new DateTime(start.Year, start.Month, DateTime.DaysInMonth(start.Year, start.Month)); 
     start = first.AddDays(-((int)first.DayOfWeek + 6) % 7); 
     last = last.AddDays(7 - ((int)last.DayOfWeek + 6) % 7); 
     return last.Subtract(start).Days; 
    } 

// Thomas

0

Tôi thấy mình cần phải làm điều này khá thường xuyên, vì vậy tôi đã tạo ra phương pháp mở rộng sau đây.

public static DateTime FirstDateOfCalendarMonth(this DateTime dt, DayOfWeek firstDayOfWeek = DayOfWeek.Sunday) 
{ 
    dt = new DateTime(dt.Year, dt.Month, 1); 
    while (dt.DayOfWeek != firstDayOfWeek){ 
    dt = dt.AddDays(-1); 
    } 
    return dt; 
} 

Sử dụng nó như thế này

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth(); 

Nó mặc định đến chủ nhật như dayOfWeek đầu tiên, nhưng bạn có thể vượt qua nó bất cứ điều gì dayOfWeek bạn thích, như thế này:

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth(DayOfWeek.Monday); 
Các vấn đề liên quan