Menu

C# DateTime 서식: 표준 및 사용자 지정 서식 문자열, 문화권, ISO 8601

C#에서 DateTime을 문자열로 서식화하는 방법: 표준 서식 문자열(d, D, o, s, u, t), yyyy-MM-dd HH:mm:ss 같은 사용자 지정 패턴, 전체 지정자 표, 문화권이 출력을 바꾸는 방식, "o"를 이용한 ISO 8601 왕복, mm과 MM, hh와 HH 실수를 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

DateTime.ToString(format)은 날짜를 텍스트로 바꿉니다. 서식은 표준 서식 문자열(d나 o 같은 한 글자로, 정확한 패턴은 문화권이 정함)이거나, yyyy, MM, HH 같은 지정자로 만든 사용자 지정 패턴입니다. 같은 문자열이 보간 $"{date:yyyy-MM-dd}"와 string.Format에도 동작합니다.

출력:

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

이 페이지의 예제는 모든 컴퓨터에서 출력이 같도록 CultureInfo.InvariantCulture를 넘깁니다. 넘기지 않으면 ToString은 현재 문화권을 쓰며, 이는 월 이름, 구분 기호, 심지어 달력까지 바꿀 수 있습니다.

사용자 지정 서식 지정자

사용자 지정 서식은 특정 글자가 날짜의 각 부분을 뜻하는 패턴입니다. 대소문자를 구분합니다. M은 월이고 m은 분이며, H는 24시간제 시, h는 12시간제 시입니다.

지정자의미2026-10-09 18:30:07.045의 예
yyyy연도, 4자리2026
yy연도, 2자리26
MMMM월 전체 이름October
MMM월 약어Oct
MM월, 2자리10
M월, 1~2자리10
dddd요일 전체 이름Friday
ddd요일 약어Fri
dd일, 2자리09
d일, 1~2자리(패턴 안에서)9
HH시, 00~2318
H시, 0~2318
hh시, 01~1206
h시, 1~126
mm분, 2자리30
ss초, 2자리07
fff밀리초045
fffffff틱(소수 일곱 자리)0450000
ttAM/PM 표시자PM
zzzUTC 기준 오프셋(DateTimeOffset 또는 로컬 시간)+02:00
K시간대 정보: Z, 오프셋, 또는 없음Z(UTC 값인 경우)
/문화권의 날짜 구분 기호/ 또는 . 또는 -
:문화권의 시간 구분 기호:
'text' 또는 \c리터럴 텍스트 또는 문자'at'

그 밖의 문자는 그대로 복사됩니다. 지정자가 아닌 글자도 마찬가지이며, 그래서 "YYYY-DD"는 조용히 YYYY-DD를 출력합니다. .NET에는 대문자 Y나 D 지정자가 없습니다.

글자 하나만 쓰면 사용자 지정이 아니라 표준 서식으로 읽힙니다. ToString("d")는 일(日) 숫자가 아니라 짧은 날짜 패턴입니다. 일만 원하면 ToString("%d")라고 쓰거나 Day 속성을 쓰세요.

출력:

10/09/2026
9
20261009_183007
Week of Oct 9
18h30
2026-10-09T18:30:07
YYYY-DD

표준 서식 문자열

표준 서식은 실제 패턴을 문화권이 정하는 한 글자입니다. 문화권마다 자기 관례를 자동으로 얻으므로 사용자에게 보여 주는 텍스트에 맞는 선택입니다.

출력:

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
코드이름문화권에 따라 다른가?
d / D짧은 / 긴 날짜예
t / T짧은 / 긴 시간예
f / F긴 날짜와 짧은 / 긴 시간예
g / G짧은 날짜와 짧은 / 긴 시간예
M월과 일예
Y연도와 월예
o왕복 ISO 8601, 소수 7자리, 시간대아니요
s정렬 가능한 ISO 8601, 소수 없음, 시간대 없음아니요
u범용 정렬 가능, Z로 끝남아니요
rRFC 1123, HTTP 헤더용아니요

o, s, u, r은 모든 문화권에서 같은 텍스트를 만들므로 로그, 파일 이름, 데이터 교환에 안전합니다. DateTime에서 u와 r은 값을 UTC로 변환하지 않는다는 점에 주의하세요. 값을 그대로 출력하고 UTC라고 표시하기만 하므로, 값이 로컬 시간이면 먼저 ToUniversalTime()을 호출하세요(또는 DateTime.UtcNow를 쓰세요). (DateTimeOffset에서는 변환합니다.)

문화권이 출력을 바꿉니다

표준 서식, 월과 요일 이름, /와 : 구분 기호는 모두 문화권에서 옵니다. ToString의 두 번째 인수로 문화권을 넘기세요:

출력:

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

문화권 데이터는 고정되어 있지 않습니다. Linux와 macOS의 .NET은 시스템에 설치된 ICU 라이브러리에서 이를 읽고, .NET 5부터는 Windows 10 이상의 .NET도 그렇습니다(.NET Framework는 Windows 자체의 NLS 데이터를 씁니다). 그래서 패턴이 버전과 플랫폼 사이에서 조금씩 바뀔 수 있습니다. 예를 들어 최근 ICU 릴리스는 미국 짧은 시간 서식에서 "PM" 앞에 일반 공백 대신 좁은 줄바꿈 없는 공백을 넣고, 일부는 스페인어 짧은 날짜에서 앞자리 0을 뺍니다. 표시용으로 서식화한 텍스트를 절대 파싱하지 말아야 하는 또 하나의 이유입니다.

두 가지 규칙이 나옵니다. 사람이 읽는 텍스트는 그 사람의 문화권(서버라면 서버의 문화권이 아니라 요청의 문화권)으로 서식화하고 표준 서식을 우선 쓰세요. 그러면 독일 독자는 09.10.2026을, 미국 독자는 10/9/2026을 봅니다. 프로그램이 읽는 텍스트에는 CultureInfo.InvariantCulture와 yyyy-MM-dd나 o 같은 모호하지 않은 패턴을 쓰세요. 현재 문화권으로 쓰고 다른 컴퓨터에서 파싱한 날짜는 일과 월이 뒤바뀌는 전형적인 원인입니다.

ISO 8601과 "o"를 이용한 왕복

왕복 서식 "o"는 모든 틱과 시간대 정보를 쓰므로, 텍스트를 파싱하면 Kind까지 포함해 정확히 같은 DateTime을 돌려받습니다:

출력:

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

Z 접미사는 UTC를 뜻합니다. Kind가 Unspecified인 DateTime에는 접미사가 없고, 로컬 시간이나 DateTimeOffset에는 오프셋(+02:00)이 붙습니다. Kind가 유지되도록 DateTimeStyles.RoundtripKind로 파싱하세요. JSON 직렬 변환기, 데이터베이스, JavaScript의 Date가 모두 이 형식을 읽습니다.

TimeSpan 서식화

TimeSpan에는 더 작은 고유 사용자 지정 지정자 집합이 있습니다: d(일), hh, mm, ss, fff. DateTime과 달리 :와 .을 포함한 모든 리터럴 문자는 백슬래시로 이스케이프하거나 따옴표로 감싸야 합니다:

출력:

1.03:25:09.1200000
1.03:25:09.1200000
03:25:09
1.03:25
25:09.120
27:25

TimeSpan 서식의 hh는 시간 구성 요소(0~23)이므로 27시간짜리 기간은 03으로 출력됩니다. 하루가 넘는 합계는 마지막 줄처럼 TotalHours로 계산하세요. 백슬래시 없는 elapsed.ToString("hh:mm")은 FormatException을 던집니다.

흔한 실수

  • 월에 mm 쓰기. "yyyy-mm-dd"는 가운데에 분을 출력합니다: 2026-30-09. 월은 MM입니다.
  • tt 없이 hh 쓰기. "hh:mm"은 AM이나 PM이 없는 12시간제라서 06:30이 모호합니다. 24시간제에는 HH를 쓰세요.
  • YYYY와 DD. .NET의 지정자가 아니라서 그대로 출력됩니다. yyyy와 dd를 쓰세요.
  • 데이터용 패턴에 / 쓰기. 문화권의 날짜 구분 기호입니다. 따옴표로 감싸거나 고정 문화권을 쓰세요.
  • 로그나 파일에 기본 ToString() 쓰기. 서식이 컴퓨터에 따라 달라집니다. 서식과 문화권을 넘기세요.
  • 로컬 시간에 UTC 표시 붙이기. "u", "r", 직접 쓴 'Z'는 변환하지 않으므로 먼저 변환하세요.
  • 쓸 때와 다른 패턴으로 파싱하기. 데이터용 서식 문자열은 상수 하나에 두고 ToString과 ParseExact 양쪽에서 쓰세요.

자주 묻는 질문

C#에서 DateTime을 yyyy-MM-dd 형식으로 만들려면 어떻게 하나요?

date.ToString("yyyy-MM-dd")는 2026-10-09를 줍니다. 보간 문자열에서는 $"{date:yyyy-MM-dd}"라고 씁니다. 24시간제 시간을 붙이려면 " HH:mm:ss"를 추가하세요. 텍스트가 파일이나 다른 프로그램용이라면 두 번째 인수로 CultureInfo.InvariantCulture를 넘겨 달력, 월 이름, 구분 기호가 컴퓨터에 따라 달라지지 않게 하세요.

C# 날짜 형식에서 mm과 MM의 차이는 무엇인가요?

MM은 월(01~12)이고 mm은 분(00~59)입니다. 서식은 대소문자를 구분하므로 yyyy-mm-dd는 월 자리에 분을 출력합니다. 값 하나를 슬쩍 볼 때는 놓치기 쉬운 버그입니다. 마찬가지로 HH는 24시간제 시, hh는 12시간제 시입니다.

C#에서 DateTime을 ISO 8601 형식으로 만들려면 어떻게 하나요?

왕복 서식 "o"를 쓰세요. DateTime.UtcNow.ToString("o")는 2026-10-09T18:30:07.0450000Z처럼 소수 일곱 자리와 UTC를 뜻하는 Z(로컬 시간이면 오프셋)를 줍니다. "s"는 소수와 시간대가 없는 더 짧은 정렬 가능한 형태를 주고, "yyyy-MM-ddTHH:mm:ssZ"는 흔한 사용자 지정 변형입니다.

C# 날짜 형식에서 AM과 PM은 어떻게 표시하나요?

12시간제에는 hh나 h를, AM/PM 표시자에는 tt를 씁니다: date.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-US"))는 6:30 PM을 줍니다. 표시자는 문화권에서 오며 일부 문화권에는 없으므로, AM과 PM이 필요하면 문화권을 명시적으로 넘기세요.

날짜 형식에 슬래시 대신 점이 나오는 이유는 무엇인가요?

서식 문자열에서 /는 슬래시 문자가 아니라 문화권의 날짜 구분 기호이고, :는 문화권의 시간 구분 기호입니다. 독일어 컴퓨터에서 dd/MM/yyyy는 09.10.2026을 출력합니다. 문자를 따옴표로 감싸 강제하거나(dd'/'MM'/'yyyy), CultureInfo.InvariantCulture로 서식화하세요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기