C #에서 전월의 첫날과 마지막 날을 가져옵니다.


140

나는 지난 몇 달 동안 첫날과 마지막 날에 얻을 수있는 쉬운 하나 또는 두 개의 라이너를 생각할 수 없습니다.

설문 조사 웹 앱을 LINQ로 수정하고 있으며 새로운 요구 사항을 압박했습니다.

설문 조사에는 이전 달의 모든 서비스 요청이 포함되어야합니다. 따라서 4 월 15 일이면 모든 Marches 요청 ID가 필요합니다.

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

나는 스위치없이 날짜를 쉽게 생각할 수 없습니다. 내가 장님이고 그것을하는 내부 방법을 간과하지 않는 한.

답변:


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

실제로 한두 줄이 필요한 경우 인라인하십시오.


2
IIRC DateTime.Today는 매우 비싼 호출이므로 먼저 변수에 값을 저장하는 것이 좋습니다. 좋은 답변 어쨌든 :)
Leandro López

2
@andleer 여기 당신이 fluentdatetime.codeplex.com
Matthew Lock

@ MatthewLock, 링크가 끊어진 것 같습니다.
Guillermo Gutiérrez


2
전체 날짜 시간을 사용하여 항목을 저장하면이 쿼리는 해당 월 말일 오전 12시 이후에 시작하는 항목을 검색하지 못할 수 있음을 지적하고 싶습니다. 마지막 줄을 변경하여 var last = month.AddTicks (-1);
SixOThree

23

내가 과거에 이것을 한 방식은 이달의 첫날을 먼저 얻는 것입니다

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

그런 다음 하루를 빼면 지난 달이 끝납니다.

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);

그런 다음 한 달을 빼서 이전 달의 첫날을 얻습니다.

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);

4
+1이지만 pedantic하기 위해서는 DateTime.Today를 한 번 평가하고 로컬 변수에 저장하는 것이 좋습니다. 코드가 자정 전에 나노초 실행을 시작하면 DateTime.Today를 두 번 연속 호출하면 다른 값이 반환 될 수 있습니다.
Joe

그렇습니다. 감사합니다. 여러분 모두가 심지어 심지어 pedantic 오류를 수정했습니다.
MikeW

잘 컴파일러가 당신에게 덜 pedantic하자 :)
Maksym Gontar

1
비교 return date.AddDays(-(date.Day-1))와 비교하여 return new DateTime(date.Year, date.Month, 1);2000 년이 넘는 첫 반복의 성능이 향상되었습니다 (92ms는 809ms 대 동일한 객체를 반환 함)
Terry_Brown


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

DateTime.Today.Days-> 'System.DateTime'에는 'Days'에 대한 정의가 없습니다.
andleer

5

나는이 간단한 원 라이너를 사용합니다 :

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

시간이 유지된다는 점에 유의하십시오.


1
내가 원했던 것, 간결한 표현은 삼항 안에 사용할 수 있습니다. 감사!
Joe Ballard

4

확장 방법을 사용하는 접근법 :

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

영감을 얻은 DateTime 확장 프로그램에 대해서는 http://www.codeplex.com/fluentdatetime 링크를 참조하십시오 .


3

전자 상거래의 표준 사용 사례는 신용 카드 만료일 (MM / yy)입니다. 하루 대신 1 초를 뺍니다. 그렇지 않으면 카드는 만료 월의 마지막 날 전체에 만료 된 것으로 나타납니다.

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

1

날짜 시간이 달력 날짜가 엄격하지 않을 경우 종료일 제외 비교 사용을 고려해야합니다. 이렇게하면 1 월 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);

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
DateTime.Now가 첫 번째 통화에서 2009-01-31을, 두 번째 통화에서 2009-02-01을 생성하면 어떻게됩니까?
Amy B

1

이것은 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);
}

다음과 같이 호출 할 수 있습니다.

dateTimePickerFrom.Value = GetPreviousMonth(false);
dateTimePickerTo.Value = GetPreviousMonth(true);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.