Отримати дати першого та останнього дня попереднього місяця в c #


140

Я не можу придумати простий один-два лайнера, який отримав би попередні місяці перший і останній день.

Я LINQ, якщо слухаю веб-додаток для опитування, і вони висунули нову вимогу.

Обстеження повинно включати всі запити на обслуговування за попередній місяць. Тож якщо це 15 квітня, мені потрібні всі ідентифікатори запитів на Марші.

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 є досить дорогим дзвінком, тому краще спочатку зберігати значення у змінній. Гарна відповідь все одно :)
Леандро Лопес,

2
@andleer ось приємна бібліотека, яка працює так, як ви згадали fluentdatetime.codeplex.com
Matthew Lock

@MatthewLock, схоже, посилання порушено.
Гільєрмо Гутьеррес


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

23

Те, що я робив це в минулому, - це перший день першого місяця

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' не містить визначення для 'Days' ...
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

Канонічним випадком використання в електронній комерції є дати закінчення терміну дії кредитної картки, ММ / рік. Віднімайте одну секунду замість одного дня. Інакше картка з’явиться закінченою за весь останній день місяця закінчення терміну дії.

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 на другий дзвінок?
Емі Б

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.