CodeGym /課程 /C# SELF /計算與日期時間的輔助類別

計算與日期時間的輔助類別

C# SELF
等級 15 , 課堂 4
開放

1. 處理日期和時間的基本任務

處理日期和時間常常讓人有點小慌(有時候還不只一點),就算是老手也一樣。你得比較日期、算區間、加減天/月/年、算年齡、判斷星期幾,還有一堆其他的需求。

這些都是任務追蹤器、行事曆、會員或訂閱管理、財務計算、統計報表,還有面試題(像是「算兩個日期之間有幾個工作日」)的經典需求。

C#.NET 裡,這些都有內建的 class 跟 method。重點是——大部分計算都可以用物件導向、超安全又直覺的 API 來搞定。

2. TimeSpan 結構——量時間區間

一切都從 TimeSpan 結構開始。這就是一段「時間片段」:比如 5 天、3 小時、7 分 21 秒。

怎麼建立 TimeSpan

你可以「相減」兩個日期,也可以直接 new 一個:

// 兩個日期的差一定是 TimeSpan!
DateTime start = new DateTime(2025, 5, 1, 7, 0, 0);
DateTime end = new DateTime(2025, 5, 2, 11, 30, 0);

TimeSpan duration = end - start; // 超神奇!
Console.WriteLine(duration); // 1.04:30:00(1 天 4 小時 30 分)

你也可以直接用 constructor 的參數建立 TimeSpan

TimeSpan span = new TimeSpan(2, 14, 18, 0); // 2 天 14 小時 18 分 0 秒
Console.WriteLine(span); // 2.14:18:00

另一種寫法是用 static method,通常更直觀:

TimeSpan fiveMinutes = TimeSpan.FromMinutes(5);
TimeSpan twoHours = TimeSpan.FromHours(2);
TimeSpan oneWeek = TimeSpan.FromDays(7);

TimeSpan 有哪些屬性?

屬性 說明
Days
天數(整數)
Hours
小時部分
Minutes
分鐘部分
Seconds
秒數部分
TotalDays
總天數(小數)
TotalHours
總小時數(小數)
TotalMinutes
總分鐘數(小數)
TotalSeconds
總秒數(小數)
Console.WriteLine($"天數: {duration.Days}, 總小時: {duration.TotalHours}");

怎麼把 TimeSpan 加到日期上/或減掉?

DateTime now = DateTime.Now;
DateTime future = now.Add(duration); // now 加上 duration
DateTime past = now.Subtract(TimeSpan.FromDays(10)); // 減掉 10 天

Console.WriteLine(future);
Console.WriteLine(past);

3. 日期計算機:算兩個日期的差

這個技能幾乎隨時都用得到。比如有人想知道離放假還有多久,有人想知道免費期什麼時候結束。

DateTime today = DateTime.Today;
DateTime vacation = new DateTime(2025, 8, 1);
TimeSpan untilVacation = vacation - today;

Console.WriteLine($"距離放假還有 {untilVacation.Days} 天!");

注意:如果你減的是純「日期」(用 DateTime.DateDateTime.Today),結果一定是整數天。如果有一個有時間,結果就會是小數。


int days = (vacation - today).TotalDays; // 編譯錯誤! TotalDays 是 double

如果你要整數,就用 .Days 或強制轉型 (int)TotalDays

4. 加減時間:AddDaysAddMonthsAddHours ...

C# 不用你自己算每個月幾天、閏年什麼的。直接用就好:

DateTime orderDate = new DateTime(2024, 4, 20);
DateTime deliveryDate = orderDate.AddDays(14); // 兩週後

Console.WriteLine($"商品會在 {deliveryDate.ToShortDateString()} 送到");
方法 加什麼(負數就是減)
AddDays(double)
天(支援小數,比如 1.5 天)
AddMonths(int)
月(自動處理每月天數)
AddYears(int)
年(連閏年都算進去)
AddHours(double)
小時
AddMinutes(double)
分鐘
AddSeconds(double)
DateTime birthday = new DateTime(2000, 2, 29);
DateTime nextYear = birthday.AddYears(1); // 2001-02-28(不是 29,因為 2001 不是閏年)
Console.WriteLine(nextYear.ToShortDateString()); // 28.02.2001

記得:所有這些方法都會 回傳新的日期實例,原本的日期不會變!

var dt = DateTime.Now;
dt.AddDays(5); // 這不會改變 dt!
dt = dt.AddDays(5); // 這才會

5. 計算輔助方法

算星期幾

大部分情況你可以用 .DayOfWeek 屬性:

DateTime examDate = new DateTime(2025, 6, 19);
DayOfWeek day = examDate.DayOfWeek;
Console.WriteLine(day); // Wednesday

你也可以轉成整數:

int number = (int)day; // Sunday == 0, Monday == 1, 以此類推

判斷「今天」、「昨天」、「明天」

最簡單的比較:

DateTime date = new DateTime(2025, 6, 18);

if (date.Date == DateTime.Today)
    Console.WriteLine("今天!");
else if (date.Date == DateTime.Today.AddDays(-1))
    Console.WriteLine("昨天!");
else if (date.Date == DateTime.Today.AddDays(1))
    Console.WriteLine("明天!");

計算年齡

最常見的需求之一——正確算出一個人的年齡。直接減年份不一定對:

public static int CalculateAge(DateTime birthDate, DateTime currentDate)
{
    int age = currentDate.Year - birthDate.Year;
    
    // 如果今年生日還沒到
    if (currentDate.Month < birthDate.Month || 
        (currentDate.Month == birthDate.Month && currentDate.Day < birthDate.Day))
    {
        age--;
    }
    
    return age;
}

// 用法
DateTime birth = new DateTime(1990, 8, 15);
DateTime today = DateTime.Today;
int age = CalculateAge(birth, today);
Console.WriteLine($"年齡: {age} 歲");

計算工作日

很常要算兩個日期之間有幾個工作日(不含週末):

public static int CountWorkingDays(DateTime startDate, DateTime endDate)
{
    int workingDays = 0;
    DateTime current = startDate;
    
    while (current <= endDate)
    {
        if (current.DayOfWeek != DayOfWeek.Saturday && 
            current.DayOfWeek != DayOfWeek.Sunday)
        {
            workingDays++;
        }
        current = current.AddDays(1);
    }
    
    return workingDays;
}

6. 主要類別的關聯

graph TD
    A(DateTime) --減法--> B(TimeSpan)
    A2(DateTime) --AddDays, AddMonths--> A
    A --ToLocalTime/ToUniversalTime--> C(DateTimeOffset)
    D(DateOnly) --ToDateTime--> A
    E(TimeOnly) --ToTimeSpan--> B
    A --DayOfWeek, Day, Month, Year--> F(數值屬性)
    B(TimeSpan) --TotalDays, TotalHours, ...--> G(區間屬性)

7. 快速查表:如果你想要...

需求 用什麼 範例
知道兩個日期的差
TimeSpan duration = d2 - d1
(d2 - d1).Days
加兩週到日期
date.AddDays(14)
date.AddDays(14)
算年齡
.Year
跟月份/天數判斷
見上面章節
只要日期
DateOnly
DateOnly.FromDateTime(DateTime.Now)
只要時間
TimeOnly
TimeOnly.FromDateTime(DateTime.Now)
比較日期
<
>
==
.CompareTo()
if (d1 < d2) ...
轉換時區
DateTimeOffset + ToOffset
dto.ToOffset(TimeSpan.FromHours(3))
知道一年中的第幾週
Calendar.GetWeekOfYear()
見官方文件
知道星期幾
date.DayOfWeek
算工作日
DayOfWeek
判斷的迴圈
見上面章節
1
問卷/小測驗
日期處理,等級 15,課堂 4
未開放
日期處理
日期、時間與時區的操作
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION