DateTime.ToString(format) biến một ngày thành văn bản. Định dạng có thể là chuỗi định dạng chuẩn (một chữ cái như d hoặc o, có mẫu cụ thể do culture quyết định) hoặc một mẫu tùy chỉnh ghép từ các ký hiệu định dạng (format specifier) như yyyy, MM và HH. Các chuỗi này cũng dùng được trong chuỗi nội suy, $"{date:yyyy-MM-dd}", và trong string.Format.
Đầu ra:
2026-10-09
2026-10-09 18:30:07
09/10/2026
Oct 9, 2026
Friday, October 9
6:30 PM
18:30:07.045
Shipped 2026-10-09 at 18:30
Các ví dụ trên trang này truyền CultureInfo.InvariantCulture để đầu ra giống nhau trên mọi máy; nếu không có nó, ToString dùng culture hiện tại, có thể làm thay đổi tên tháng, dấu phân cách và thậm chí cả lịch.
Ký hiệu định dạng tùy chỉnh
Định dạng tùy chỉnh là một mẫu trong đó một số chữ cái đại diện cho các phần của ngày. Chúng phân biệt chữ hoa chữ thường: M là tháng còn m là phút, H là giờ dạng 24 giờ còn h là giờ dạng 12 giờ.
| Ký hiệu | Ý nghĩa | Ví dụ với 2026-10-09 18:30:07.045 |
|---|---|---|
yyyy | Năm, 4 chữ số | 2026 |
yy | Năm, 2 chữ số | 26 |
MMMM | Tên tháng đầy đủ | October |
MMM | Tên tháng viết tắt | Oct |
MM | Tháng, 2 chữ số | 10 |
M | Tháng, 1 hoặc 2 chữ số | 10 |
dddd | Tên thứ đầy đủ | Friday |
ddd | Tên thứ viết tắt | Fri |
dd | Ngày trong tháng, 2 chữ số | 09 |
d | Ngày trong tháng, 1 hoặc 2 chữ số (trong một mẫu) | 9 |
HH | Giờ, từ 00 đến 23 | 18 |
H | Giờ, từ 0 đến 23 | 18 |
hh | Giờ, từ 01 đến 12 | 06 |
h | Giờ, từ 1 đến 12 | 6 |
mm | Phút, 2 chữ số | 30 |
ss | Giây, 2 chữ số | 07 |
fff | Mili giây | 045 |
fffffff | Tick (bảy chữ số phần thập phân) | 0450000 |
tt | Ký hiệu AM/PM | PM |
zzz | Độ lệch so với UTC (DateTimeOffset hoặc giờ địa phương) | +02:00 |
K | Thông tin múi giờ: Z, một độ lệch, hoặc không gì cả | Z (với giá trị UTC) |
/ | Dấu phân cách ngày của culture | / hoặc . hoặc - |
: | Dấu phân cách giờ của culture | : |
'text' hoặc \c | Văn bản hoặc ký tự nguyên văn | 'at' |
Mọi ký tự khác được giữ nguyên. Kể cả những chữ cái không phải ký hiệu định dạng, và đó là lý do "YYYY-DD" lặng lẽ in ra YYYY-DD: .NET không có ký hiệu Y hay D viết hoa.
Một chữ cái đứng riêng được hiểu là định dạng chuẩn, không phải tùy chỉnh: ToString("d") là mẫu ngày dạng ngắn, không phải số ngày. Để chỉ lấy ngày, viết ToString("%d") hoặc dùng property Day.
Đầu ra:
10/09/2026
9
20261009_183007
Week of Oct 9
18h30
2026-10-09T18:30:07
YYYY-DD
Chuỗi định dạng chuẩn
Định dạng chuẩn là các chữ cái đơn có mẫu thực tế do culture định nghĩa. Chúng là lựa chọn đúng cho văn bản hiển thị cho người dùng, vì mỗi culture tự động có quy ước riêng của mình.
Đầu ra:
d 10/09/2026
D Friday, 09 October 2026
f Friday, 09 October 2026 18:30
g 10/09/2026 18:30
G 10/09/2026 18:30:07
M October 09
Y 2026 October
t 18:30
T 18:30:07
o 2026-10-09T18:30:07.0000000Z
s 2026-10-09T18:30:07
u 2026-10-09 18:30:07Z
r Fri, 09 Oct 2026 18:30:07 GMT
en-US d: 10/9/2026, D: Friday, October 9, 2026
| Mã | Tên | Phụ thuộc culture? |
|---|---|---|
d / D | Ngày dạng ngắn / dài | Có |
t / T | Giờ dạng ngắn / dài | Có |
f / F | Ngày dạng dài với giờ dạng ngắn / dài | Có |
g / G | Ngày dạng ngắn với giờ dạng ngắn / dài | Có |
M | Tháng và ngày | Có |
Y | Năm và tháng | Có |
o | ISO 8601 round-trip, 7 chữ số phần thập phân, múi giờ | Không |
s | ISO 8601 sắp xếp được, không phần thập phân, không múi giờ | Không |
u | Dạng sắp xếp được theo giờ quốc tế, kết thúc bằng Z | Không |
r | RFC 1123, cho HTTP header | Không |
o, s, u và r cho ra cùng một văn bản ở mọi culture, nên an toàn cho log, tên tệp và trao đổi dữ liệu. Lưu ý rằng với DateTime, u và r không chuyển giá trị sang UTC; chúng in nguyên giá trị và gắn nhãn UTC, nên hãy gọi ToUniversalTime() trước (hoặc dùng DateTime.UtcNow) nếu giá trị là giờ địa phương. (Với DateTimeOffset thì chúng có chuyển đổi.)
Culture thay đổi đầu ra
Định dạng chuẩn, tên tháng và tên thứ, cùng các dấu phân cách / và : đều đến từ culture. Truyền một culture làm đối số thứ hai cho ToString:
Đầu ra:
en-US 10/9/2026
en-GB 09/10/2026
de-DE 09.10.2026
fr-FR 09/10/2026
ja-JP 2026/10/09
Freitag, 9. Oktober 2026
vendredi 9 octobre 2026
09.10.2026
09/10/2026
Dữ liệu culture không cố định. .NET trên Linux và macOS đọc nó từ thư viện ICU cài trên hệ thống, và từ .NET 5, .NET trên Windows 10 trở lên cũng vậy (.NET Framework dùng dữ liệu NLS riêng của Windows), nên một mẫu có thể thay đổi đôi chút giữa các phiên bản và nền tảng: chẳng hạn các bản ICU gần đây đặt một khoảng trắng hẹp không ngắt dòng thay vì khoảng trắng thường trước "PM" trong định dạng giờ ngắn của Mỹ, và một số bản cho ngày ngắn tiếng Tây Ban Nha không có số 0 ở đầu. Đó thêm một lý do để không bao giờ phân tích văn bản đã được định dạng để hiển thị.
Từ đó có hai quy tắc. Với văn bản dành cho người đọc, hãy định dạng theo culture của họ (trên máy chủ, đó là culture lấy từ request, không phải của máy chủ) và ưu tiên định dạng chuẩn, để người đọc Đức thấy 09.10.2026 còn người đọc Mỹ thấy 10/9/2026. Với văn bản dành cho chương trình, hãy dùng CultureInfo.InvariantCulture và một mẫu rõ ràng như yyyy-MM-dd hoặc o. Một ngày được ghi bằng culture hiện tại rồi được phân tích trên máy khác là nguồn kinh điển của lỗi đảo ngày và tháng.
ISO 8601 và round-trip với "o"
Định dạng round-trip "o" ghi đủ mọi tick cùng thông tin múi giờ, nên phân tích lại văn bản sẽ cho đúng DateTime ban đầu, kể cả Kind của nó:
Đầu ra:
2026-10-09T18:30:07.0450000Z
2026-10-09T18:30:07.0450000
2026-10-09T20:30:07.0000000+02:00
True
Utc
2026-10-09T18:30:07Z
2026-10-09 20:30 +02:00
Hậu tố Z đánh dấu UTC; DateTime có Kind là Unspecified không có hậu tố; giờ địa phương hoặc DateTimeOffset có độ lệch của nó (+02:00). Phân tích với DateTimeStyles.RoundtripKind để giữ lại Kind. Các bộ tuần tự hóa JSON, cơ sở dữ liệu và Date của JavaScript đều đọc được định dạng này.
Định dạng TimeSpan
TimeSpan có bộ ký hiệu tùy chỉnh riêng, nhỏ hơn: d (ngày), hh, mm, ss và fff. Khác với DateTime, mọi ký tự nguyên văn, kể cả : và ., phải được escape bằng dấu gạch chéo ngược hoặc đặt trong dấu nháy:
Đầu ra:
1.03:25:09.1200000
1.03:25:09.1200000
03:25:09
1.03:25
25:09.120
27:25
hh trong định dạng TimeSpan là thành phần giờ (từ 0 đến 23), nên một khoảng thời gian 27 giờ được in ra là 03. Với tổng lớn hơn một ngày, hãy tính từ TotalHours như ở dòng cuối. elapsed.ToString("hh:mm") không có dấu gạch chéo ngược sẽ ném ra FormatException.
Lỗi thường gặp
mmcho tháng."yyyy-mm-dd"in số phút ở giữa:2026-30-09. Tháng làMM.hhmà không cótt."hh:mm"là đồng hồ 12 giờ không có AM hay PM, nên 06:30 không rõ là sáng hay tối. DùngHHcho giờ dạng 24 giờ.YYYYvàDD. Không phải ký hiệu định dạng trong .NET; chúng được in nguyên văn. Dùngyyyyvàdd./trong mẫu cho dữ liệu. Đó là dấu phân cách ngày của culture. Đặt nó trong dấu nháy hoặc dùng invariant culture.ToString()mặc định trong log hoặc tệp. Định dạng phụ thuộc vào máy. Hãy truyền định dạng và culture.- Giờ địa phương bị gắn nhãn UTC.
"u","r"và'Z'viết tay không chuyển đổi; hãy chuyển đổi trước. - Phân tích bằng mẫu khác với mẫu đã dùng để ghi. Giữ chuỗi định dạng cho dữ liệu trong một hằng số và dùng nó cho cả
ToStringvàParseExact.
Câu hỏi thường gặp
Làm sao định dạng DateTime thành yyyy-MM-dd trong C#?
date.ToString("yyyy-MM-dd") cho ra 2026-10-09. Trong chuỗi nội suy, viết $"{date:yyyy-MM-dd}". Thêm " HH:mm:ss" để có giờ theo dạng 24 giờ. Truyền CultureInfo.InvariantCulture làm đối số thứ hai khi văn bản dành cho tệp hoặc chương trình khác, để lịch, tên tháng và dấu phân cách không bao giờ phụ thuộc vào máy.
mm và MM trong định dạng ngày của C# khác nhau thế nào?
MM là tháng (từ 01 đến 12) và mm là phút (từ 00 đến 59). Định dạng phân biệt chữ hoa chữ thường, nên yyyy-mm-dd in số phút vào chỗ của tháng, một lỗi dễ bỏ sót khi bạn chỉ liếc qua một giá trị. Tương tự, HH là giờ dạng 24 giờ và hh là giờ dạng 12 giờ.
Làm sao định dạng DateTime theo ISO 8601 trong C#?
Dùng định dạng round-trip "o": DateTime.UtcNow.ToString("o") cho ra 2026-10-09T18:30:07.0450000Z, với bảy chữ số phần thập phân và Z cho UTC hoặc độ lệch múi giờ cho giờ địa phương. "s" cho dạng ngắn hơn, sắp xếp được, không có phần thập phân và múi giờ, còn "yyyy-MM-ddTHH:mm:ssZ" là một biến thể tùy chỉnh thường gặp.
Làm sao hiển thị AM và PM trong định dạng ngày của C#?
Dùng hh hoặc h cho đồng hồ 12 giờ và tt cho ký hiệu AM/PM: date.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-US")) cho ra 6:30 PM. Ký hiệu này đến từ culture, và một số culture không có, nên hãy truyền culture tường minh khi bạn cần AM và PM.
Vì sao định dạng ngày của tôi hiện dấu chấm thay vì dấu gạch chéo?
Trong chuỗi định dạng, / không phải dấu gạch chéo nguyên văn mà là dấu phân cách ngày của culture, còn : là dấu phân cách giờ của culture. Trên máy cài tiếng Đức, dd/MM/yyyy in ra 09.10.2026. Đặt ký tự trong dấu nháy để ép nó, dd'/'MM'/'yyyy, hoặc định dạng với CultureInfo.InvariantCulture.