2009-02-26 107 views
118

Tôi không thể nghĩ ra một hoặc hai lớp dễ dàng có thể nhận được những tháng trước ngày đầu tiên và ngày cuối cùng.Lấy ngày tháng đầu tiên và ngày cuối cùng của tháng trước đó trong C#

Tôi LINQ-ifying một ứng dụng web khảo sát, và họ vắt một yêu cầu mới trong.

Cuộc khảo sát phải bao gồm tất cả các yêu cầu dịch vụ trong tháng trước. Vì vậy, nếu đó là ngày 15 tháng 4, tôi cần tất cả các id yêu cầu của Marches.

var RequestIds = (from r in rdc.request 
        where r.dteCreated >= LastMonthsFirstDate && 
        r.dteCreated <= LastMonthsLastDate 
        select r.intRequestId); 

Tôi không thể nghĩ ngày dễ dàng mà không cần chuyển đổi. Trừ khi tôi bị mù và nhìn vào một phương pháp nội bộ để làm điều đó.

Trả lời

254
var today = DateTime.Today; 
var month = new DateTime(today.Year, today.Month, 1);  
var first = month.AddMonths(-1); 
var last = month.AddDays(-1); 

In-line chúng nếu bạn thực sự cần một hoặc hai dòng.

+2

IIRC DateTime.Today là một cuộc gọi khá đắt tiền, vì vậy bạn nên lưu trữ giá trị trong biến trước tiên. Tốt câu trả lời anyway :) –

+1

Làm thế nào điều này sẽ làm việc vào ngày 01 tháng 1? –

+8

Hoạt động tốt với ngày 1 tháng 1, vừa được thử nghiệm ... –

21

Con đường tôi đã làm điều này trong quá khứ là lần đầu tiên có được ngày đầu tiên của tháng này

dFirstDayOfThisMonth = DateTime.Today.AddDays(- (DateTime.Today.Day - 1)); 

Sau đó trừ đi một ngày để có được cuối tháng trước

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1); 

Sau đó, trừ một tháng để có được ngày đầu tiên của tháng trước

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1); 
+0

ròng 2.0, Today.Days không hoạt động. –

+0

DateTime.Today.Day bạn có nghĩa là –

+3

+1, nhưng để được pedantic, bạn tốt hơn đánh giá DateTime.Today một lần và lưu trữ trong một biến địa phương. Nếu mã của bạn bắt đầu thực hiện một nano giây trước nửa đêm, hai cuộc gọi liên tiếp đến DateTime.Today có thể trả về các giá trị khác nhau. – Joe

8
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day); 
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day); 
+0

DateTime.Today.Days -> 'System.DateTime' không chứa định nghĩa cho 'Ngày' ... – andleer

+1

DateTime .Today.Day bạn có nghĩa là –

1
DateTime now = DateTime.Now; 
int prevMonth = now.AddMonths(-1).Month; 
int year = now.AddMonths(-1).Year; 
int daysInPrevMonth = DateTime.DaysInMonth(year, prevMonth); 
DateTime firstDayPrevMonth = new DateTime(year, prevMonth, 1); 
DateTime lastDayPrevMonth = new DateTime(year, prevMonth, daysInPrevMonth); 
Console.WriteLine("{0} {1}", firstDayPrevMonth.ToShortDateString(), 
    lastDayPrevMonth.ToShortDateString()); 
+1

Điều gì sẽ xảy ra nếu DateTime.Now mang lại lợi nhuận 2009-01-31 vào cuộc gọi đầu tiên và 2009-02-01 trong cuộc gọi thứ hai? –

+0

Đó sẽ là kết thúc của DateTime.Now :) chỉnh sửa. cảm ơn. –

0

Nếu có bất kỳ cơ hội mà datetimes của bạn không phải là ngày lịch chặt chẽ, bạn nên xem xét sử dụng so sánh trừ ENDDATE ... này sẽ khiến bạn không bỏ lỡ bất kỳ yêu cầu được tạo ra trong ngày Jan 31.

DateTime now = DateTime.Now; 
DateTime thisMonth = new DateTime(now.Year, now.Month, 1); 
DateTime lastMonth = thisMonth.AddMonths(-1); 

var RequestIds = rdc.request 
    .Where(r => lastMonth <= r.dteCreated) 
    .Where(r => r.dteCreated < thisMonth) 
    .Select(r => r.intRequestId); 
4

cách tiếp cận Một sử dụng phương pháp khuyến nông:

class Program 
{ 
    static void Main(string[] args) 
    { 
     DateTime t = DateTime.Now; 

     DateTime p = t.PreviousMonthFirstDay(); 
     Console.WriteLine(p.ToShortDateString()); 

     p = t.PreviousMonthLastDay(); 
     Console.WriteLine(p.ToShortDateString()); 


     Console.ReadKey(); 
    } 
} 


public static class Helpers 
{ 
    public static DateTime PreviousMonthFirstDay(this DateTime currentDate) 
    { 
     DateTime d = currentDate.PreviousMonthLastDay(); 

     return new DateTime(d.Year, d.Month, 1); 
    } 

    public static DateTime PreviousMonthLastDay(this DateTime currentDate) 
    { 
     return new DateTime(currentDate.Year, currentDate.Month, 1).AddDays(-1); 
    } 
} 

Xem liên kết này http://www.codeplex.com/fluentdatetime cho một số phần mở rộng DateTime được lấy cảm hứng.

1

EDIT: Đây không phải là cách để làm điều đó!
Nếu hôm nay.Month - 1 = 0, như trong tháng 1, điều này sẽ ném một ngoại lệ. Đây rõ ràng là một trường hợp thông minh giúp bạn gặp rắc rối!

Một chút đơn giản hơn accepted answer:

var today = DateTime.Today 
var first = new DateTime(today.Year, today.Month - 1, 1); 
var last = new DateTime(today.Year, today.Month, 1).AddDays(-1); 

Tiết kiệm thêm một sự sáng tạo DateTime.

2

Các trường hợp sử dụng kinh điển trong thương mại điện tử là ngày hết hạn thẻ tín dụng, MM/yy. Trừ một giây thay vì một ngày. Nếu không, thẻ sẽ hết hạn cho toàn bộ ngày cuối cùng của tháng hết hạn.

DateTime expiration = DateTime.Parse("07/2013"); 
DateTime endOfTheMonthExpiration = new DateTime(
    expiration.Year, expiration.Month, 1).AddMonths(1).AddSeconds(-1); 
3

tôi sử dụng này đơn giản một-liner:

public static DateTime GetLastDayOfPreviousMonth(this DateTime date) 
{ 
    return date.AddDays(-date.Day); 
} 

Hãy nhận biết, rằng nó vẫn giữ được thời gian.

+0

Chỉ là những gì tôi muốn, biểu hiện ngắn gọn mà tôi có thể sử dụng bên trong một bộ ba. Cảm ơn! –

1

Đây là một mất về câu trả lời Mike W:

internal static DateTime GetPreviousMonth(bool returnLastDayOfMonth) 
{ 
    DateTime firstDayOfThisMonth = DateTime.Today.AddDays(- (DateTime.Today.Day - 1)); 
    DateTime lastDayOfLastMonth = firstDayOfThisMonth.AddDays (-1); 
    if (returnLastDayOfMonth) return lastDayOfLastMonth; 
    return firstDayOfThisMonth.AddMonths(-1); 
} 

Bạn có thể gọi nó như vậy:

dateTimePickerFrom.Value = GetPreviousMonth(false); 
dateTimePickerTo.Value = GetPreviousMonth(true); 
Các vấn đề liên quan