在C#中获取上个月的第一天和最后一天的日期


140

我想不出一个简单的一两个班轮就能得到前几个月的第一天和最后一天。

我正在LINQ上实现一个调查Web应用程序,他们为此提出了新要求。

该调查必须包括上个月的所有服务请求。因此,如果是4月15日,则需要所有3月的请求ID。

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

没有切换,我简直想不起来日期。除非我是盲目的并且忽略了这样做的内部方法。

Answers:


303
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是一个非常昂贵的调用,因此最好先将值存储在变量中。无论如何,好的回答是:)
LeandroLópez,

2
@andleer这是一个不错的库,它的工作原理就像您提到的fluentdatetime.codeplex.com
Matthew Lock

@MatthewLock,链接似乎已断开。
GuillermoGutiérrez'13


2
我只想指出,如果条目使用完整的日期时间存储,则该查询可能无法检索该月最后一天的12:00 AM之后开始的所有内容。您可以通过将最后一行更改为var last = month.AddTicks(-1);来解决此问题。
SixOThree 2014年

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多次迭代的性能更好(923ms更新与809ms返回同一对象)
Terry_Brown 2012年


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

DateTime.Today.Days->'System.DateTime'不包含'Days'的定义...
andleer 2009年

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

有关 某些启发性的DateTime扩展,请参见此链接 http://www.codeplex.com/fluentdatetime


3

电子商务中的典型用例是信用卡到期日期,MM / yy。减去一秒而不是一天。否则,该卡将在到期月份的整个最后一天显示已过期。

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

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怎么办?
艾米B

1

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

您可以这样称呼它:

dateTimePickerFrom.Value = GetPreviousMonth(false);
dateTimePickerTo.Value = GetPreviousMonth(true);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.