CodeGym /Các khóa học /C# SELF /Các kiểu hữu ích: DateOnly và TimeOnly

Các kiểu hữu ích: DateOnly và TimeOnly

C# SELF
Mức độ , Bài học
Có sẵn

1. Giới thiệu

Trước đây trong C# không có kiểu riêng chỉ cho ngày hoặc chỉ cho giờ. Vì vậy, ngay cả khi bạn chỉ cần lưu ngày — ví dụ, ngày sinh nhật — bạn vẫn phải dùng DateTime và thêm "giờ mặc định". Cách cũ để lưu chỉ ngày bằng DateTime:


DateTime birthday = new DateTime(1985, 4, 20); // 20 tháng 4 năm 1985, 00:00:00

Nhưng như vậy khá bất tiện. Bạn chỉ muốn ngày thôi mà lại có thêm cả giờ — dù là 0. Điều này có thể gây rối: ví dụ, khi so sánh ngày, chương trình có thể tính cả giờ và bạn sẽ nhận kết quả bất ngờ.

Tương tự với trường hợp ngược lại: nếu bạn chỉ làm việc với giờ (ví dụ, lịch làm việc từ 08:00 đến 17:00), bạn vẫn phải "nghĩ ra" một ngày nào đó, dù nó chẳng quan trọng gì.

Giờ đây trong .NET đã có các kiểu đặc biệt DateOnlyTimeOnly, giúp bạn không còn bị rối như trước nữa.

Kiểu mới hữu ích DateOnlyTimeOnly

  • DateOnly — chỉ ngày trên lịch, không có giờ trong ngày và không có thông tin về múi giờ.
  • TimeOnly — chỉ giờ trong ngày, không có năm, tháng, ngày và cũng không có múi giờ.

Bảng so sánh các kiểu thời gian

Kiểu Ngày Giờ Múi giờ Dùng để làm gì?
DateTime
🚫 Gần như mọi thứ (nhưng không phải lúc nào cũng tiện và an toàn)
DateTimeOffset
Khi cần cả thời điểm và múi giờ
DateOnly
🚫 🚫 Sinh nhật, ngày không cần giờ
TimeOnly
🚫 🚫 Giờ làm việc, lịch trình, các khoảng trong ngày

2. Làm việc với DateOnly

Khai báo và tạo mới

Tạo một object DateOnly — giống như bắt đầu một thói quen mới: đơn giản và nhanh! Ví dụ:

// Năm, tháng, ngày
DateOnly birthday = new DateOnly(1985, 4, 20);
Tạo ngày sinh bằng DateOnly

Bạn có thể dùng DateOnly.FromDateTime nếu đã có object DateTime:

DateTime now = DateTime.Now;
DateOnly today = DateOnly.FromDateTime(now);
// giờ today chỉ chứa ngày, phần giờ bị bỏ qua

Thuộc tính và phương thức cơ bản

  • Year, Month, Day — quen thuộc như trong DateTime.
  • .ToString() — định dạng ngày, có thể tự chọn format.
Console.WriteLine($"Ngày sinh: {birthday.Year} năm, {birthday.Month} tháng, {birthday.Day} ngày.");

Console.WriteLine(today.ToString("dd.MM.yyyy")); // Ví dụ, 30.07.2024

Toán học ngày tháng

Có thể dễ dàng cộng thêm ngày/tháng/năm:

DateOnly tomorrow = today.AddDays(1);
DateOnly nextMonth = today.AddMonths(1);

Hãy thử thay các trường kiểu DateTime chỉ lưu ngày trong app chính của bạn bằng DateOnly — bạn sẽ gần hơn với .NET hiện đại!

So sánh ngày

So sánh dùng <, >, ==:

if (birthday < today)
    Console.WriteLine("Sinh nhật đã qua năm nay hoặc lâu rồi :)");

Không còn lỗi do dư mili giây hay phút nữa.

Lấy ngày hôm nay

DateOnly currentDate = DateOnly.FromDateTime(DateTime.Now);

3. Làm việc với TimeOnly

Giờ thì làm việc với giờ mà không cần ngày — lập trình viên nào mà chưa từng gặp lịch ăn trưa chứ?

Tạo TimeOnly

TimeOnly startWork = new TimeOnly(9, 0);    // 09:00
TimeOnly endWork = new TimeOnly(17, 30);    // 17:30

Có thể lấy riêng giờ, phút, giây:

Console.WriteLine($"Ngày làm việc: từ {startWork.Hour}:{startWork.Minute:D2} đến {endWork.Hour}:{endWork.Minute:D2}");

Lấy giờ từ DateTime

DateTime now = DateTime.Now;
TimeOnly currentTime = TimeOnly.FromDateTime(now);
Console.WriteLine($"Bây giờ là {currentTime}");

Toán học thời gian

TimeOnly breakStart = startWork.AddHours(4); // nghỉ sau 4 tiếng, tức 13:00
TimeOnly breakEnd = breakStart.AddMinutes(30); // nghỉ trưa 30 phút

So sánh và kiểm tra

if (currentTime >= startWork && currentTime <= endWork)
    Console.WriteLine("Đến giờ làm rồi :)");
else
    Console.WriteLine("Có thể nghỉ ngơi.");

4. Tương tác với các kiểu khác

Chuyển đổi giữa DateOnly, TimeOnlyDateTime

Đôi khi bạn cần lấy lại DateTime (ví dụ, để lưu vào database cũ hoặc cho tương thích):


DateOnly datePart = new DateOnly(2024, 7, 30);
TimeOnly timePart = new TimeOnly(14, 15);
DateTime datetime = datePart.ToDateTime(timePart); // 2024-07-30 14:15:00

Và ngược lại:

DateTime dt = DateTime.Now;
DateOnly justDate = DateOnly.FromDateTime(dt);
TimeOnly justTime = TimeOnly.FromDateTime(dt);

Những điểm quan trọng và lỗi thường gặp

  • Nếu bạn thử parse chỉ ngày hoặc chỉ giờ bằng các hàm cũ như DateTime.Parse(), rất có thể sẽ bị lỗi hoặc ra kết quả không như mong đợi. Với trường hợp này có hàm riêng: dùng DateOnly.Parse()TimeOnly.Parse() — chúng biết cách xử lý giá trị "cắt ngắn".
  • Quan trọng: DateOnlyTimeOnly hoàn toàn không biết gì về múi giờ. Chúng chỉ là ngày hoặc giờ — không liên quan gì đến múi giờ. Nếu cần tính đến múi giờ, hãy lưu thông tin này riêng.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION