Получить даты первого и последнего дня предыдущего месяца в 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.