Dapatkan tanggal hari pertama dan terakhir bulan sebelumnya di c #

140

Saya tidak bisa memikirkan satu atau dua liner mudah yang akan mendapatkan bulan-bulan sebelumnya hari pertama dan hari terakhir.

Saya LINQ-ifying aplikasi web survei, dan mereka memeras persyaratan baru di.

Survei harus mencakup semua permintaan layanan untuk bulan sebelumnya. Jadi jika tanggal 15 April, saya membutuhkan semua id permintaan Marches.

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

Aku hanya tidak bisa memikirkan tanggal dengan mudah tanpa saklar. Kecuali saya buta dan mengabaikan metode internal untuk melakukannya.

Jeremy Boyd
sumber

Jawaban:

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

Sejajarkan mereka jika Anda benar-benar membutuhkan satu atau dua baris.

andleer
sumber
2
IIRC DateTime.Today adalah panggilan yang cukup mahal, jadi Anda lebih baik menyimpan nilai dalam variabel terlebih dahulu. Baik jawaban pula :)
Leandro López
2
@andleer inilah perpustakaan yang bagus yang berfungsi seperti yang Anda sebutkan fluentdatetime.codeplex.com
Matthew Lock
@ MatthewLock, tautannya tampaknya rusak.
Guillermo Gutiérrez
1
@ guillegr123 sekarang di github github.com/FluentDateTime/FluentDateTime dan Nuget nuget.org/packages/FluentDateTime
Matthew Lock
2
Saya hanya ingin menunjukkan bahwa jika entri disimpan menggunakan a datetime penuh kueri ini mungkin gagal untuk mengambil yang dimulai setelah pukul 12:00 pada hari terakhir bulan itu. Anda bisa menyelesaikan ini dengan mengubah baris terakhir untuk membaca var last = month.AddTicks (-1);
SixOThree
23

Cara saya melakukan ini di masa lalu adalah pertama kali mendapatkan hari pertama bulan ini

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

Kemudian kurangi satu hari untuk mengakhiri bulan lalu

dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);

Kemudian kurangi satu bulan untuk mendapatkan hari pertama bulan sebelumnya

dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);
MikeW
sumber
4
+1, tetapi untuk menjadi luar biasa, Anda lebih baik mengevaluasi DateTime.Hari ini sekali dan menyimpan dalam variabel lokal. Jika kode Anda mulai menjalankan nanodetik sebelum tengah malam, dua panggilan berurutan ke DateTime. Hari ini dapat mengembalikan nilai yang berbeda.
Joe
Ya, terima kasih, kalian semua benar, bahkan yang bertele-tele Memperbaiki kesalahan.
MikeW
baik membiarkan compiler kurang bertele-tele untuk Anda :)
Maksym Gontar
1
terbalik seperti membandingkan return date.AddDays(-(date.Day-1))versus return new DateTime(date.Year, date.Month, 1);dan kinerja iterasi pertama lebih dari 2000 lebih baik (923ms baru versus 809ms mengembalikan objek yang sama)
Terry_Brown
9
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day);
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day);
Franci Penov
sumber
DateTime.Today.Days -> 'System.DateTime' tidak mengandung definisi untuk 'Days' ...
andleer
5

Saya menggunakan one-liner sederhana ini:

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

Ketahuilah, bahwa itu masih ada waktu.


sumber
1
Seperti yang saya inginkan, ekspresi singkat yang bisa saya gunakan di dalam ternary. Terima kasih!
Joe Ballard
4

Pendekatan menggunakan metode ekstensi:

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

Lihat tautan ini http://www.codeplex.com/fluentdatetime untuk beberapa ekstensi DateTime yang diilhami.

rp.
sumber
3

Kasus penggunaan kanonik dalam e-commerce adalah tanggal kedaluwarsa kartu kredit, MM / yy. Kurangi satu detik, bukan satu hari. Kalau tidak, kartu akan kedaluwarsa untuk seluruh hari terakhir dari bulan kedaluwarsa.

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

Jika ada kemungkinan bahwa data Anda bukan tanggal kalender yang ketat, Anda harus mempertimbangkan untuk menggunakan perbandingan pengecualian tanggal ... Ini akan mencegah Anda dari kehilangan permintaan yang dibuat pada tanggal 31 Januari.

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);
Amy B
sumber
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());
Maksym Gontar
sumber
1
Bagaimana jika DateTime. Sekarang menghasilkan 2009-01-31 pada panggilan pertama dan 2009-02-01 pada panggilan kedua?
Amy B
1

Ini adalah jawaban 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);
}

Anda bisa menyebutnya seperti ini:

dateTimePickerFrom.Value = GetPreviousMonth(false);
dateTimePickerTo.Value = GetPreviousMonth(true);
B. Clay Shannon
sumber