Отримати дати першого та останнього дня попереднього місяця в 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.