2010-07-29 39 views
44

Tôi có một số DateTime Ngày bắt đầu và Ngày kết thúc.Lặp lại mỗi ngày giữa Ngày bắt đầu và Ngày kết thúc

Làm thế nào tôi có thể, không phân biệt thời gian, lặp lại mỗi ngày giữa hai ngày đó?

Ví dụ: StartDate là 7/20/2010 5:10:32 PM và ngày kết thúc là 7/29/2010 1:59:12 AM.

Tôi muốn có thể lặp qua 7/20, 7/21, 7/22 .. 7/29.

+0

Hãy xem ở đây: http://stackoverflow.com/questions/533767/how-do-you-iterate-through-every-day-of-the-year –

Trả lời

112
for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1)) 
{ 
    ... 
} 

.Date là để đảm bảo bạn có ngày cuối cùng, như trong ví dụ.

+0

Tôi nghĩ bạn muốn 'date.Date <= EndDate.Date' để bạn nhận được ngày cuối cùng. –

+2

Điều này đi vào một vòng lặp vô hạn, phương thức AddDays không thay đổi ngày tháng, nhưng trả về một cá thể DateTime mới. Thay vào đó hãy sử dụng ngày tháng = Ngày thay thế (1). – corvuscorax

+0

@Dean: Cảm ơn, đã xem nhận xét của bạn sau khi thay đổi. –

0
DateTime date = DateTime.Now; 
DateTime endDate = date.AddDays(10); 

while (date < endDate) 
{ 
    Console.WriteLine(date); 
    date = date.AddDays(1); 
} 
3

Bạn phải cẩn thận về ngày kết thúc. Ví dụ: trong

Ví dụ: StartDate là 7/20/2010 5:10:32 PM và EndDate là 7/29/2010 1:59:12 SA.
Tôi muốn có thể lặp qua 7/20, 7/21, 7/22 .. 7/29.

date < endDate sẽ không bao gồm 7/29 bao giờ hết. Khi bạn thêm 1 ngày đến 7/28 5:10 chiều - nó sẽ trở thành 7/29 5:10 PM cao hơn 7/29 2 giờ sáng.

Nếu đó không phải là những gì bạn muốn sau đó tôi muốn nói bạn làm

for (DateTime date = start.Date; date <= end.Date; date += TimeSpan.FromDays(1)) 
{ 
    Console.WriteLine(date.ToString()); 
} 

hoặc một cái gì đó về việc đó.

11

Một phương pháp thay thế có thể tái sử dụng nhiều hơn là viết một phương pháp mở rộng trên DateTime và trả về một IEnumerable.

Ví dụ, bạn có thể định nghĩa một lớp:

public static class MyExtensions 
{ 
    public static IEnumerable EachDay(this DateTime start, DateTime end) 
    { 
     // Remove time info from start date (we only care about day). 
     DateTime currentDay = new DateTime(start.Year, start.Month, start.Day); 
     while (currentDay <= end) 
     { 
      yield return currentDay; 
      currentDay = currentDay.AddDays(1); 
     } 
    } 
} 

Bây giờ trong mã gọi bạn có thể làm như sau:

DateTime start = DateTime.Now; 
DateTime end = start.AddDays(20); 
foreach (var day in start.EachDay(end)) 
{ 
    ... 
} 

Một ưu điểm khác để tiếp cận này là nó làm cho nó tầm thường để thêm EveryWeek, EachMonth, vv. Sau đó, tất cả sẽ được truy cập trên DateTime.

+1

Bạn có thể xóa thông tin thời gian khỏi ngày có DateTime.Date: https://msdn.microsoft.com/en-us/library/system.datetime.date(v=vs.110).aspx – Oswin

+1

tại sao bạn không làm nó an toàn không? IEnumerable ? – duedl0r

0

Các vòng của @Yuriy Faktorovich, @healsjnr và @mho sẽ ném System.ArgumentOutOfRangeException: The added or subtracted value results in an un-representable DateTime ngoại lệ nếu EndDate == DateTime.MaxValue. Để ngăn chặn điều này, thêm một kiểm tra thêm ở phần cuối của vòng lặp

for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1)) 
{ 
    ... 
    if (date.Date == DateTime.MaxValue.Date) 
    { 
     break; 
    } 
} 

(Tôi đã có thể đăng này như một bình luận cho câu trả lời @Yuriy Faktorovich, nhưng tôi thiếu uy tín)

Các vấn đề liên quan