C#시작과 문법

DateTime과 날짜/시간 처리

DateTime, DateOnly, TimeSpan의 생성·연산·포맷, DateTimeOffset의 타임존 처리, 안전한 파싱 패턴을 정리합니다.

마지막 수정 2026년 3월 25일

기본 패턴

csharp
DateTime now = DateTime.Now;
DateTime utc = DateTime.UtcNow;

// 날짜 연산
DateTime tomorrow = now.AddDays(1);
TimeSpan diff = tomorrow - now;   // TimeSpan

// 포맷
string s = now.ToString("yyyy-MM-dd HH:mm:ss");

// C# 10+ — 날짜만 / 시간만
DateOnly today = DateOnly.FromDateTime(now);   // 2026-03-25
TimeOnly time  = TimeOnly.FromDateTime(now);   // 09:30:00

설명

DateTime 생성 방법

DateTime은 날짜와 시간을 함께 다루는 구조체입니다. 직접 값을 지정하려면 new DateTime(year, month, day) 을 사용하고, 현재 시각이 필요하면 DateTime.Now(로컬 시간) 또는 DateTime.UtcNow(UTC 시간)를 씁니다. DateTime.Today 는 시·분·초가 모두 0인 오늘 날짜를 반환합니다.

csharp
DateTime dt  = new DateTime(2026, 3, 25);       // 날짜만 지정
DateTime now = DateTime.Now;                     // 로컬 시간
DateTime utc = DateTime.UtcNow;                  // UTC 시간
DateTime today = DateTime.Today;                 // 오늘 00:00:00

DateOnly / TimeOnly (C# 10+)

날짜와 시간을 분리해서 다뤄야 할 때 DateOnlyTimeOnly 를 사용합니다. 생년월일처럼 시간 정보가 의미 없는 값에는 DateOnly가, 알람 시각처럼 날짜와 무관한 값에는 TimeOnly가 적합합니다. 기존 DateTime에서 변환하거나 직접 생성할 수 있습니다.

csharp
DateOnly date = new DateOnly(2026, 3, 25);
TimeOnly time = new TimeOnly(9, 30, 0);

DateOnly fromDt = DateOnly.FromDateTime(DateTime.Now);
TimeOnly fromDt2 = TimeOnly.FromDateTime(DateTime.Now);

TimeSpan — 시간 간격과 산술 연산

TimeSpan 은 두 DateTime 을 빼거나 TimeSpan.FromXxx() 팩토리 메서드로 만들 수 있는 시간 간격 타입입니다. DateTime에 더하거나 빼서 날짜 연산을 수행합니다.

csharp
TimeSpan oneHour  = TimeSpan.FromHours(1);
TimeSpan twoWeeks = TimeSpan.FromDays(14);

DateTime deadline = DateTime.Now + twoWeeks;
TimeSpan elapsed  = DateTime.Now - new DateTime(2026, 1, 1);

Console.WriteLine(elapsed.TotalDays);    // 경과 일수 (소수점 포함)
Console.WriteLine(elapsed.Days);         // 경과 일수 (정수)

포맷 — ToString과 표준 서식 지정자

ToString() 에 서식 문자열을 전달해 원하는 형태로 출력합니다. 사용자 정의 서식(yyyy-MM-dd)과 표준 서식 지정자("D", "F" 등) 두 가지 방식이 있습니다.

csharp
DateTime dt = new DateTime(2026, 3, 25, 9, 30, 0);

dt.ToString("yyyy-MM-dd")           // "2026-03-25"
dt.ToString("HH:mm:ss")            // "09:30:00"
dt.ToString("yyyy-MM-dd HH:mm:ss") // "2026-03-25 09:30:00"
dt.ToString("D")                   // "2026년 3월 25일 수요일" (문화권에 따라 다름)
dt.ToString("F")                   // "2026년 3월 25일 수요일 오전 9:30:00"
dt.ToString("O")                   // ISO 8601 라운드트립 서식

파싱 — Parse, TryParse, ParseExact

문자열을 DateTime으로 변환할 때 DateTime.Parse 는 형식이 맞지 않으면 예외를 던집니다. 입력이 신뢰할 수 없는 경우 DateTime.TryParse 로 안전하게 처리합니다. 형식이 고정된 경우 ParseExactCultureInfo.InvariantCulture 를 조합해 문화권 독립적으로 파싱하는 것이 권장됩니다.

csharp
// 기본 파싱 — 실패 시 예외
DateTime dt = DateTime.Parse("2026-03-25");

// 안전한 파싱 — 실패 시 false 반환
if (DateTime.TryParse("2026-03-25", out DateTime result))
    Console.WriteLine(result);

// 엄격한 형식 지정 파싱 (API 응답, 파일명 등)
DateTime exact = DateTime.ParseExact(
    "25/03/2026",
    "dd/MM/yyyy",
    CultureInfo.InvariantCulture);

DateTimeOffset — 타임존 안전한 처리

DateTimeOffset 은 UTC 오프셋을 함께 저장해 어느 타임존에서 생성된 값인지 명시합니다. 서로 다른 타임존의 값을 비교하거나 DB에 저장할 때 DateTime보다 안전합니다.

csharp
DateTimeOffset now    = DateTimeOffset.Now;       // 로컬 + 오프셋
DateTimeOffset utcNow = DateTimeOffset.UtcNow;    // UTC + 00:00

// 오프셋 직접 지정
DateTimeOffset seoul = new DateTimeOffset(
    2026, 3, 25, 9, 0, 0,
    TimeSpan.FromHours(9));   // +09:00

Console.WriteLine(seoul.Offset);         // 09:00:00
Console.WriteLine(seoul.UtcDateTime);    // UTC 기준 DateTime

DateTime.Kind 함정

DateTime에는 Kind 속성이 있어 Unspecified, Local, Utc 세 가지 값을 가집니다. DateTime.NowLocal, DateTime.UtcNowUtc이지만, new DateTime(...)으로 직접 만들면 Unspecified가 됩니다. Kind가 다른 값끼리 비교하면 의도치 않은 결과가 나올 수 있습니다.

csharp
DateTime local = DateTime.Now;           // Kind = Local
DateTime utc   = DateTime.UtcNow;        // Kind = Utc
DateTime raw   = new DateTime(2026, 3, 25); // Kind = Unspecified

Console.WriteLine(local.Kind);   // Local
Console.WriteLine(raw.Kind);     // Unspecified ← 주의

빠른 정리

타입용도주요 생성 방법
DateTime날짜 + 시간 (타임존 없음)DateTime.Now, DateTime.UtcNow, new DateTime(y,m,d)
DateOnly날짜만 (C# 10+)new DateOnly(y,m,d), DateOnly.FromDateTime()
TimeOnly시간만 (C# 10+)new TimeOnly(h,m,s), TimeOnly.FromDateTime()
TimeSpan시간 간격TimeSpan.FromDays(), dt1 - dt2
DateTimeOffset날짜 + 시간 + UTC 오프셋DateTimeOffset.Now, DateTimeOffset.UtcNow
포맷 지정자출력 예시
"yyyy-MM-dd"2026-03-25
"HH:mm:ss"09:30:00
"D"2026년 3월 25일 수요일
"F"2026년 3월 25일 수요일 오전 9:30:00
"O"2026-03-25T09:30:00.0000000 (ISO 8601)

주의할 점

DateTime.Now는 로컬 시간을 반환하므로 서버 코드에서 혼용하면 위험합니다. 서버 간 시간 비교나 DB 저장에는 DateTime.UtcNow 를 사용하세요.

타임존 정보가 중요한 애플리케이션(스케줄러, 글로벌 서비스 등)에서는 DateTimeOffset 이 가장 안전합니다. KindUnspecifiedDateTime은 변환 시 잘못된 시간이 계산될 수 있으므로, new DateTime(...) 직접 생성 후 오프셋 처리가 필요하다면 DateTimeOffset으로 전환하는 것을 권장합니다.

참고 링크

2 sources