首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

.NET DateTime 取得上個月第一天與最後一天:一行程式碼搞定

     編輯:ASP.NET 基礎

核心公式

// 上個月第一天 00:00:00
DateTime firstDayLastMonth = DateTime.Now.AddMonths(-1).AddDays(1 - DateTime.Now.Day);

// 上個月最後一天 23:59:59.999 (或當天 00:00:00 視需求)
DateTime lastDayLastMonth = DateTime.Now.AddDays(-DateTime.Now.Day).AddTicks(-1);
// 或者單純取日期部分
DateTime lastDayLastMonthDate = DateTime.Now.AddDays(-DateTime.Now.Day).Date;

原理圖解

  1. DateTime.Now.Day 取得今天是當月第幾天(如 15)。
  2. AddDays(-Day) 退回到「上個月最後一天」(如 4/30)。
  3. AddMonths(-1) 退回到「上個月同一天」(如 3/15),再 AddDays(1-Day) 推到「上個月第一天」(3/1)。

完整工具方法

public static class DateTimeExtensions
{
    /// 取得指定日期所在月份的第一天 00:00:00
    public static DateTime FirstDayOfMonth(this DateTime dt) => new DateTime(dt.Year, dt.Month, 1);

    /// 取得指定日期所在月份的最後一天 23:59:59.999
    public static DateTime LastDayOfMonth(this DateTime dt) => dt.FirstDayOfMonth().AddMonths(1).AddTicks(-1);

    /// 取得上個月第一天
    public static DateTime FirstDayOfLastMonth(this DateTime dt) => dt.AddMonths(-1).FirstDayOfMonth();

    /// 取得上個月最後一天
    public static DateTime LastDayOfLastMonth(this DateTime dt) => dt.AddMonths(-1).LastDayOfMonth();

    /// 取得下個月第一天
    public static DateTime FirstDayOfNextMonth(this DateTime dt) => dt.AddMonths(1).FirstDayOfMonth();

    /// 取得本月迄今範圍
    public static (DateTime Start, DateTime End) MonthToDate(this DateTime dt) 
        => (dt.FirstDayOfMonth(), dt.Date.AddDays(1).AddTicks(-1));
}

使用範例

var now = DateTime.Now;
var start = now.FirstDayOfLastMonth(); // 2024-03-01 00:00:00
var end = now.LastDayOfLastMonth();    // 2024-03-31 23:59:59.999

// SQL 查詢範圍
string sql = "SELECT * FROM Orders WHERE CreateTime >= @start AND CreateTime <= @end";
// 參數化查詢避免注入

常見陷阱與注意事項

陷阱 說明 解決
時區問題 DateTime.Now 為伺服器本地時間,跨時區部署會不一致 統一使用 DateTime.UtcNow,轉換時指定 TimeZoneInfo
月末邊界 1/31 加一個月變 2/28/29,非預期 用 FirstDayOfMonth().AddMonths(1) 而非直接 AddMonths(1)
資料庫時間精度 SQL Server datetime 精度 3.33ms,datetime2 100ns 查詢上界用 < 下個月第一天 而非 <= 最後一天 23:59:59.999
效能 頻繁計算可快取當月首尾 靜態快取 Dictionary Key=Year*100+Month

最佳實務:半開區間查詢

// 推薦:[start, nextMonthStart) 避免精度問題
DateTime start = DateTime.UtcNow.FirstDayOfLastMonth();
DateTime endExclusive = start.AddMonths(1); // 下個月第一天

// SQL
WHERE CreateTimeUtc >= @start AND CreateTimeUtc < @endExclusive

總結

利用 AddMonths(-1) 結合 Day 屬性,即可以 O(1) 時間取得上個月首尾日期。封裝為擴充方法並採用「半開區間」查詢,能避開時區、精度、閏年等常見坑,程式碼更簡潔、可讀、可維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved