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

C# DateTime 實戰寶典:週/月/季/年邊界計算、格式化與比較技巧全攻略

     編輯:關於C語言

核心類別與屬性速查

  • DateTime.Now:本地時間(含時區)
  • DateTime.UtcNow:UTC 時間(儲存/傳輸首選)
  • DateTime.Today:當地日期 00:00:00
  • DayOfWeek:列舉(Sunday=0 ~ Saturday=6)
  • DayOfYear:今年第幾天

邊界計算黃金公式集

所有公式以 DateTime dt = DateTime.Today 為基準,僅保留日期部分,避免時間誤差。

週邊界(以週日為週起始,依 .NET 預設)


// 本週起始(週日)
var weekStart = dt.AddDays(-(int)dt.DayOfWeek);
// 本週結束(週六)
var weekEnd = weekStart.AddDays(6);

// 上週起始/結束
var lastWeekStart = weekStart.AddDays(-7);
var lastWeekEnd = weekStart.AddDays(-1);

// 下週起始/結束
var nextWeekStart = weekStart.AddDays(7);
var nextWeekEnd = nextWeekStart.AddDays(6);

月邊界


// 本月第一天
var monthStart = new DateTime(dt.Year, dt.Month, 1);
// 本月最後一天
var monthEnd = monthStart.AddMonths(1).AddDays(-1);

// 上月
var lastMonthStart = monthStart.AddMonths(-1);
var lastMonthEnd = monthStart.AddDays(-1);

// 下月
var nextMonthStart = monthStart.AddMonths(1);
var nextMonthEnd = nextMonthStart.AddMonths(1).AddDays(-1);

季邊界(季度 = (Month-1)/3 + 1)


// 本季第一天
int quarter = (dt.Month - 1) / 3 + 1;
var quarterStart = new DateTime(dt.Year, (quarter - 1) * 3 + 1, 1);
// 本季最後一天
var quarterEnd = quarterStart.AddMonths(3).AddDays(-1);

// 上季
var lastQuarterStart = quarterStart.AddMonths(-3);
var lastQuarterEnd = quarterStart.AddDays(-1);

// 下季
var nextQuarterStart = quarterStart.AddMonths(3);
var nextQuarterEnd = nextQuarterStart.AddMonths(3).AddDays(-1);

年邊界


var yearStart = new DateTime(dt.Year, 1, 1);
var yearEnd = new DateTime(dt.Year, 12, 31);
var lastYearStart = yearStart.AddYears(-1);
var lastYearEnd = yearStart.AddDays(-1);
var nextYearStart = yearStart.AddYears(1);
var nextYearEnd = yearStart.AddYears(2).AddDays(-1);

ToString 格式化速查表

格式字串輸出範例用途
yyyy-MM-dd2024-03-15標準日期(資料庫、API)
yyyy-MM-012024-03-01月首日技巧
yyyy-01-012024-01-01年首日技巧
HH:mm:ss14:30:05純時間
yyyyMMddHHmmss20240315143005檔案名稱、流水號
ddd / dddd五 / 星期五星期顯示

中文化星期顯示


string[] weeks = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
string today = weeks[(int)DateTime.Today.DayOfWeek]; // "星期五"

相對日期快速計算


var now = DateTime.Now;
now.AddDays(7);    // 7 天後
now.AddDays(-7);   // 7 天前
now.AddMonths(1);  // 1 月後(自動處理月末)
now.AddYears(-1);  // 1 年前

日期比較最佳實踐

錯誤示範:字串比較


// 錯誤:字串按字元序比較,"2024-12-01" < "2024-2-01"
if (dateStr1 > dateStr2) { ... }

正確做法:DateTime 直接比較


DateTime d1 = DateTime.Parse("2024-03-15");
DateTime d2 = DateTime.Parse("2024-03-20");

if (d1 < d2) { ... }           // 早於
if (d1 == d2) { ... }          // 同一天
if (d1.Date == d2.Date) { ... } // 忽略時間比較日期

// 計算差異
TimeSpan diff = d2 - d1;
int days = diff.Days;          // 5 天
double hours = diff.TotalHours; // 120 小時

實務案例:標記「新」資料(3 天內)


public bool IsNew(DateTime publishDate)
{
    // 使用 Date 比較,忽略時間部分
    return DateTime.Today <= publishDate.Date.AddDays(3);
}

// 或使用 UTC 避免時區問題
public bool IsNewUtc(DateTime publishDateUtc)
{
    return DateTime.UtcNow.Date <= publishDateUtc.Date.AddDays(3);
}

時區與序列化陷阱

場景風險對策
資料庫儲存本地時間跨時區混亂統一儲存 UTC (DateTime.UtcNow)
JSON 序列化預設輸出本地時間無時區資訊用 DateTimeOffset 或設定 JsonSerializerOptions
跨時區使用者顯示錯誤日期前端負責轉換,後端只提供 UTC
夏令時間切換同一天出現 2 次或 0 次某小時用 TimeZoneInfo.ConvertTime 處理

進階:DateOnly / TimeOnly (.NET 6+)


// 純日期,無時間、無時區
DateOnly today = DateOnly.FromDateTime(DateTime.Today);
DateOnly expiry = today.AddMonths(12);

// 純時間
TimeOnly openTime = new TimeOnly(9, 0);
TimeOnly closeTime = new TimeOnly(18, 0);

// 組合
DateTime dt = today.ToDateTime(openTime); // 2024-03-15 09:00:00

總結

日期邊界計算核心原則:先對齊到大單位起始(年/月/季/週首日),再用 AddDays/AddMonths 微調。避免手算天數、避免字串拼湊、善用 DateOnly 表達純日期語意。掌握這些模式,報表查詢、排程觸發、業務週期判斷都能得心應手。

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