Nhận ngày đầu tiên và ngày cuối cùng của tháng trước trong c #


140

Tôi không thể nghĩ ra một hoặc hai lớp lót dễ dàng sẽ có được những tháng trước vào ngày đầu tiên và ngày cuối cùng.

Tôi là LINQ-ifying một ứng dụng web khảo sát và họ đã đưa ra một yêu cầu mới.

Khảo sát phải bao gồm tất cả các yêu cầu dịch vụ cho 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 chỉ không thể nghĩ về những ngày dễ dàng mà không có một chuyển đổi. Trừ khi tôi bị mù và nhìn ra một phương pháp nội bộ để làm điều đó.

Câu trả lời:


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

Xếp hàng 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ốn kém, vì vậy trước tiên bạn nên lưu trữ giá trị trong một biến. Dù sao thì câu trả lời tốt :)
Leandro López

2
@andleer đây là một thư viện đẹp hoạt động như bạn đã đề cập đến fluentdatetime.codeplex.com
Matthew Lock

@MatthewLock, liên kết dường như bị hỏng.
Guillermo Gutiérrez


2
Tôi chỉ muốn chỉ ra rằng nếu các mục được lưu trữ bằng cách sử dụng toàn bộ thời gian thì truy vấn này có thể không truy xuất bất kỳ mục nào bắt đầu sau 12:00 AM vào ngày cuối cùng của tháng. Bạn có thể giải quyết điều này bằng cách thay đổi dòng cuối cùng để đọc var last = tháng.AddTicks (-1);
SixOThree

23

Cách tôi đã làm 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 để kết thúc tháng trước

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);

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

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);

4
+1, nhưng để mang tính mô phạm, bạn nên đánh giá DateTime.Today một lần và lưu trữ trong một biến cục bộ. Nếu mã của bạn bắt đầu thực thi 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

Vâng, cảm ơn, tất cả các bạn đều đúng, thậm chí cả lỗi mô phạm đã sửa lỗi.
MikeW

hãy để trình biên dịch bớt ngữ nghĩa với bạn :)
Maksym Gontar

1
được nâng cấp so return date.AddDays(-(date.Day-1))với so sánh return new DateTime(date.Year, date.Month, 1);và hiệu suất của hơn 2000 lần lặp đầu tiên là tốt hơn (923ms mới so với 809ms trả về cùng một đối tượng)
Terry_Brown


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

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

5

Tôi sử dụng một lớp lót đơn giản này:

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

Hãy nhận biết rằng nó giữ lại thời gian.


1
Chỉ cần những gì tôi muốn, biểu hiện súc tích tôi có thể sử dụng bên trong một con chim nhạn. Cảm ơn!
Joe Ballard

4

Một cách tiếp cận sử dụng các phương pháp mở rộ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 để biết một số tiện ích mở rộng DateTime được truyền cảm hứng.


3

Trường hợp sử dụng chính tắc trong thương mại điện tử là ngày hết hạn thẻ tín dụng, MM / yy. Trừ đi một giây thay vì một ngày. Nếu không, thẻ sẽ xuất hiện 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);

1

Nếu có bất kỳ cơ sở dữ liệu nào của bạn không phải là ngày theo lịch nghiêm ngặt, bạn nên xem xét sử dụng các so sánh loại trừ cuối ngày ... Điều này sẽ ngăn bạn bỏ lỡ bất kỳ yêu cầu nào được tạo trong ngày 31 tháng 1.

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

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. Làm thế nào mang lại 2009-01-31 cho cuộc gọi đầu tiên và 2009 / 02-01 cho cuộc gọi thứ hai?
Amy B

1

Đây là một câu trả lời của 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);
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.