C# 使用给定的DateTime对象获取一个月的第一天和最后一天

C# 使用给定的DateTime对象获取一个月的第一天和最后一天,c#,.net,winforms,datetime,C#,.net,Winforms,Datetime,我想得到给定日期所在月份的第一天和最后一天。日期来自UI字段中的值 如果我使用时间选择器,我可以说 var maxDay = dtpAttendance.MaxDate.Day; 但我试图从DateTime对象中获取它。所以如果我有这个 DateTime dt = DateTime.today; 如何从dt中获取月的第一天和最后一天?结构只存储一个值,而不存储值的范围MinValue和MaxValue是静态字段,用于保存DateTime结构实例的可能值范围。这些字段是静态的,与DateTim

我想得到给定日期所在月份的第一天和最后一天。日期来自UI字段中的值

如果我使用时间选择器,我可以说

var maxDay = dtpAttendance.MaxDate.Day;
但我试图从DateTime对象中获取它。所以如果我有这个

DateTime dt = DateTime.today;
如何从
dt
中获取月的第一天和最后一天?

结构只存储一个值,而不存储值的范围
MinValue
MaxValue
是静态字段,用于保存
DateTime
结构实例的可能值范围。这些字段是静态的,与
DateTime
的特定实例无关。它们与
DateTime
类型本身有关

建议如下:

更新:获取月份范围:

DateTime date = ...
var firstDayOfMonth = new DateTime(date.Year, date.Month, 1);
var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);

使用.Net API获取月份范围(另一种方式):


这更像是对@Sergey和@Steffen答案的长篇评论。过去我自己也写过类似的代码,所以我决定检查最重要的是什么,同时记住清晰性也很重要

结果 以下是1000万次迭代的测试运行结果示例:

2257毫秒,用于每月第一天的添加方法()
每月第一天2406 ms\u新方法()
每月最后一天的6342 ms\u添加方法()
4037毫秒,用于每月的最后一天\u添加方法WithDaysInMonth()
每月最后一天的4160毫秒\u新方法()
每月最后一天的4212毫秒\u使用ReuseOfExtMethod()的新方法
2491毫秒,用于每月最后一天的特殊情况()
代码 我使用(在C#程序模式下)在启用编译器优化的情况下运行测试。以下是为清晰和方便起见作为扩展方法考虑的测试代码:

public static class DateTimeDayOfMonthExtensions
{
    public static DateTime FirstDayOfMonth_AddMethod(this DateTime value)
    {
        return value.Date.AddDays(1 - value.Day);
    }
    
    public static DateTime FirstDayOfMonth_NewMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, 1);
    }
    
    public static DateTime LastDayOfMonth_AddMethod(this DateTime value)
    {
        return value.FirstDayOfMonth_AddMethod().AddMonths(1).AddDays(-1);
    }
    
    public static DateTime LastDayOfMonth_AddMethodWithDaysInMonth(this DateTime value)
    {
        return value.Date.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - value.Day);
    }
    
    public static DateTime LastDayOfMonth_SpecialCase(this DateTime value)
    {
        return value.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - 1);
    }
    
    public static int DaysInMonth(this DateTime value)
    {
        return DateTime.DaysInMonth(value.Year, value.Month);
    }
    
    public static DateTime LastDayOfMonth_NewMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, DateTime.DaysInMonth(value.Year, value.Month));
    }

    public static DateTime LastDayOfMonth_NewMethodWithReuseOfExtMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, value.DaysInMonth());
    }
}

void Main()
{
    Random rnd = new Random();
    DateTime[] sampleData = new DateTime[10000000];
    
    for(int i = 0; i < sampleData.Length; i++) {
        sampleData[i] = new DateTime(1970, 1, 1).AddDays(rnd.Next(0, 365 * 50));
    }
    
    GC.Collect();
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].FirstDayOfMonth_AddMethod();
    }
    string.Format("{0} ms for FirstDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();
    
    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].FirstDayOfMonth_NewMethod();
    }
    string.Format("{0} ms for FirstDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();
    
    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_AddMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_AddMethodWithDaysInMonth();
    }
    string.Format("{0} ms for LastDayOfMonth_AddMethodWithDaysInMonth()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_NewMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_NewMethodWithReuseOfExtMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()", sw.ElapsedMilliseconds).Dump();

    for(int i = 0; i < sampleData.Length; i++) {
        sampleData[i] = sampleData[i].FirstDayOfMonth_AddMethod();
    }
    
    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_SpecialCase();
    }
    string.Format("{0} ms for LastDayOfMonth_SpecialCase()", sw.ElapsedMilliseconds).Dump();
    
}
如果你已经走到了这一步,谢谢你的时间!这很有趣。如果您对这些算法有任何其他建议,请发表意见。

简单易行

Begin = new DateTime(DateTime.Now.Year, DateTime.Now.Month,1).ToShortDateString();
End = new DataFim.Text = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)).ToShortDateString();

在这里,您可以为当前月份的第一天添加一个月,而不是从该天删除一天

DateTime now = DateTime.Now;
var startDate = new DateTime(now.Year, now.Month, 1);
var endDate = startDate.AddMonths(1).AddDays(-1);
月的最后一天
”实际上是“
下个月*的第一天,减去1”。所以我使用的是,不需要“DaysInMonth”方法:

注: 我之所以在这里使用
AddMinutes(-1)
,而不是
AddDays(-1)
,是因为通常您需要这些日期函数来报告某个日期段,并且当您为某个期间生成报告时,“结束日期”实际上应该类似于2015年10月31日23:59:59
,这样您的报告才能正常工作-包括当月最后一天的所有数据

也就是说,你实际上在这里得到了“这个月的最后时刻”。不是最后一天


好了,我现在就闭嘴。

这里接受的答案没有考虑DateTime实例的类型。例如,如果您的原始DateTime实例是UTC类型,那么通过创建新的DateTime实例,您将创建一个未知类型的实例,然后根据服务器设置将其视为本地时间。因此,获取当月第一个和最后一个日期的更合适方法是:

var now = DateTime.UtcNow;
var first = now.Date.AddDays(-(now.Date.Day - 1));
var last = first.AddMonths(1).AddTicks(-1);

这样就保留了DateTime实例的原始类型。

如果您只关心日期

var firstDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind);
var lastDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind).AddMonths(1).AddDays(-1);
如果你想节省时间

var firstDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind);
var lastDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind).AddMonths(1).AddDays(-1);
试试这个:

string strDate = DateTime.Now.ToString("MM/01/yyyy");
波斯文化

PersianCalendar pc = new PersianCalendar();            

var today = pc.GetDayOfMonth(DateTime.Now);
var firstDayOfMonth = pc.GetDayOfMonth(DateTime.Now.AddDays(-(today-1)));
var lastDayOfMonth = pc.GetDayOfMonth(DateTime.Now.AddMonths(1).AddDays(-today));            
Console.WriteLine("First day "+ firstDayOfMonth);
Console.WriteLine("Last day " + lastDayOfMonth);
我在我的脚本中使用了这个(对我来说很有用),但是我需要一个完整的日期,而不需要将它修改为只包含日期而不包含时间

public DateTime GetLastDayOfTheMonth()
{
    int daysFromNow = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month) - (int)DateTime.Now.Day;
    return DateTime.Now.AddDays(daysFromNow);
}
你能做到

DateTime dt = DateTime.Now; 
DateTime firstDayOfMonth = new DateTime(dt.Year, date.Month, 1);
DateTime lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);

试试这个。它基本上计算在日期时间上经过的天数。现在,然后从中减去一天,并使用新值查找当前月份的第一天。从那里,它使用
DateTime
并使用
.AddMonths(-1)
获取上个月的第一个月

int NumberofDays = DateTime.Now.Day;
int FirstDay = NumberofDays - 1;
int LastDay = NumberofDays + 1;
DateTime FirstofThisMonth = DateTime.Now.AddDays(-FirstDay);
DateTime LastDayOfLastMonth = DateTime.Now.AddDays(-LastDay);
DateTime CheckLastMonth = FirstofThisMonth.AddMonths(-1);
获取上个月的最后一天基本上是一样的,只是它将一个月的天数加一,然后从
DateTime.Now.AddDays
中减去该值,得到上个月的最后一天

int NumberofDays = DateTime.Now.Day;
int FirstDay = NumberofDays - 1;
int LastDay = NumberofDays + 1;
DateTime FirstofThisMonth = DateTime.Now.AddDays(-FirstDay);
DateTime LastDayOfLastMonth = DateTime.Now.AddDays(-LastDay);
DateTime CheckLastMonth = FirstofThisMonth.AddMonths(-1);

您可以在获取当月第一天时尝试此操作

DateTime.Now.AddDays(-(DateTime.Now.Day-1))
并给它赋值

像这样:

dateEndEdit.EditValue = DateTime.Now;
dateStartEdit.EditValue = DateTime.Now.AddDays(-(DateTime.Now.Day-1));

不清楚你在问什么。
\u Date
变量中存储了一个值。你想从这个值中得到什么“最小值和最大值”呢?它被否决了,因为人们想知道你为什么要这样想,你会在哪里使用这样的东西。你没有告诉我们任何关于你最初发行的东西。最好问问你想做什么?不是那样的你想怎么做?也许其他用法能正确地建议您。@Chathuranga您知道任何月份的最短日期是什么吗。。。。但问题是本月的最后一天是什么。。你可以这样。。在当前日期加上1个月,从该日期减去1天。。现在你将得到你当前月份的最后一天,通常避免只回答代码。考虑添加<代码>描述< /代码>,这有助于解释代码。谢谢你的努力太少了。它很有用!谢谢@DionV被人欣赏真是太好了!当你很匆忙的时候,简短的回答是很好的,但是我认为一些更深入的分析通常是有用的。你错过了另一个选择:
LastDayOfMonth\u AddMethod\u SpecialCase
(或者类似的东西)。预计每月第一天作为参数,我认为最快的应该是
LastDayOfMonth\u AddMethod
所做的事情!所以这将非常简单:
returnvalue.AddMonths(1.AddDays(-1)
谢谢@Andrew,以下是我使用它得到的结果:每月最后一天2835毫秒\u SpecialCase(),和;4685毫秒,用于月的最后一天\u添加方法\u SpecialCase()。这在考虑结构创建时间时可能是有意义的,DateTime的内部表示可能使添加天数成为一个简单的操作,而添加月份则成为一个更复杂的算法。我知道我在这里很挑剔,但不应该
lastDayofMonth
be
firstDayOfMonth.AddMonths(1).AddSeconds(-1)
?@KarlGjertsen你不够挑剔:)完美的解决方案是
AddTicks(-1)
,但如果我们不在乎时间的话
DateTime dt = DateTime.Now; 
DateTime firstDayOfMonth = new DateTime(dt.Year, date.Month, 1);
DateTime lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
int NumberofDays = DateTime.Now.Day;
int FirstDay = NumberofDays - 1;
int LastDay = NumberofDays + 1;
DateTime FirstofThisMonth = DateTime.Now.AddDays(-FirstDay);
DateTime LastDayOfLastMonth = DateTime.Now.AddDays(-LastDay);
DateTime CheckLastMonth = FirstofThisMonth.AddMonths(-1);
DateTime.Now.AddDays(-(DateTime.Now.Day-1))
dateEndEdit.EditValue = DateTime.Now;
dateStartEdit.EditValue = DateTime.Now.AddDays(-(DateTime.Now.Day-1));