Получить даты первого и последнего дня предыдущего месяца в c #


147

Я не могу придумать простой один или два вкладыша, которые можно было бы получить за предыдущие месяцы в первый и последний день.

Я использую LINQ-приложение для опроса, и они втиснули новое требование в.

Опрос должен включать все запросы на обслуживание за предыдущий месяц. Итак, если это 15 апреля, мне нужны все идентификаторы запросов Marches.

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

Я просто не могу думать о датах без переключателя. Если только я не слепой и не упускаю из виду внутренний метод этого.

Ответы:


313
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 - довольно дорогой вызов, поэтому лучше сначала сохранить значение в переменной. В любом случае, хороший ответ :)
Леандро Лопес,

2
@andleer, вот замечательная библиотека, которая работает так же, как вы упомянули fluentdatetime.codeplex.com
Мэтью Лок

@MatthewLock, ссылка вроде битая.
Гильермо Гутьеррес


2
Я просто хотел бы указать, что если записи хранятся с использованием полного даты и времени, этот запрос может не получить все, что начинается после 12:00 AM в последний день месяца. Вы можете решить эту проблему, изменив последнюю строку на var last = month.AddTicks (-1);
SixOThree

24

То, как я делал это раньше, - сначала получить первый день этого месяца

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

Затем вычтите день, чтобы получить конец прошлого месяца.

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);

Затем вычтите месяц, чтобы получить первый день предыдущего месяца.

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);

4
+1, но, чтобы быть педантичным, вам лучше оценить DateTime.Today один раз и сохранить в локальной переменной. Если ваш код начинает выполнение за наносекунду до полуночи, два последовательных вызова DateTime.Today могут вернуть разные значения.
Джо

Да, спасибо, все поправили, даже педантичный Исправил ошибку.
MikeW

ну пусть компилятор будет с тобой менее педантичным :)
Максим Гонтарь

1
проголосовало за сравнение по return date.AddDays(-(date.Day-1))сравнению с return new DateTime(date.Year, date.Month, 1);и производительность первых более 2000 итераций лучше (923 мс при обновлении по сравнению с 809 мс при возврате того же объекта)
Terry_Brown


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

DateTime.Today.Days -> 'System.DateTime' не содержит определения для 'дней' ...
andleer

5

Я использую этот простой однострочник:

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

Знайте, что он сохраняет время.


1
Как раз то, что я хотел, краткое выражение, которое я мог бы использовать внутри троичного. Благодарность!
Джо Баллард,

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

См. Эту ссылку http://www.codeplex.com/fluentdatetime для некоторых вдохновленных расширений DateTime.


3

Канонический вариант использования в электронной коммерции - это срок действия кредитной карты, MM / yy. Вычтите одну секунду вместо одного дня. В противном случае карта будет выглядеть просроченной на весь последний день месяца истечения срока действия.

DateTime expiration = DateTime.Parse("07/2013");
DateTime endOfTheMonthExpiration = new DateTime(
  expiration.Year, expiration.Month, 1).AddMonths(1).AddSeconds(-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

Это ответ Майка В.

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);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.