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 DateOnly và TimeOnly, giúp bạn không còn bị rối như trước nữa.
Kiểu mới hữu ích DateOnly và TimeOnly
- 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ì? |
|---|---|---|---|---|
|
✅ | ✅ | 🚫 | Gần như mọi thứ (nhưng không phải lúc nào cũng tiện và an toàn) |
|
✅ | ✅ | ✅ | Khi cần cả thời điểm và múi giờ |
|
✅ | 🚫 | 🚫 | Sinh nhật, ngày không cần giờ |
|
🚫 | ✅ | 🚫 | 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);
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, TimeOnly và DateTime
Đô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() và TimeOnly.Parse() — chúng biết cách xử lý giá trị "cắt ngắn".
- Quan trọng: DateOnly và TimeOnly 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.
GO TO FULL VERSION