DateTime과 TimeSpan은 앱이나 게임을 만들 때 자주 사용되곤 합니다. 두 가지 모두 틱을 기본 단위로 가지기 때문에 현재 틱을 시간이나 분, 초로 바꾸거나, 현재시간으로 바꿔야하는 경우가 많습니다. 이 두 가지의 사용이 능숙하지 않을 경우 이러한 간단한 작업도 시간이 오래 걸립니다. 그렇기에 이번시간에는 DateTime과 TimeSpan 개념과 특징을 알아보고 자주 쓰이는 기능을 유틸 클래스로 만들어서 제공해 드리려고 합니다.
목차
[DateTime의 개념과 사용법]
날짜와 시간 정보를 다루는 데 사용되는 구조체입니다. 이 구조체는 많은 유용한 멤버 함수들을 제공하여 날짜와 시간에 대한 기능을 제공합니다.
[사용 예시]
날짜와 시간 생성하기
// 현재 날짜와 시간 가져오기
DateTime now = DateTime.Now;
// 특정 날짜와 시간 생성하기
DateTime customDateTime = new DateTime(2024, 5, 15, 10, 30, 0); // 2024년 5월 15일 오전 10시 30분
날짜와 시간 정보 추출하기
// 년, 월, 일, 시, 분, 초 등 각각의 구성 요소 추출하기
int year = now.Year;
int month = now.Month;
int day = now.Day;
int hour = now.Hour;
int minute = now.Minute;
int second = now.Second;
날짜와 시간 연산하기
// 특정 시간을 더하거나 빼기
DateTime futureDateTime = now.AddHours(5); // 현재 시간으로부터 5시간 후
DateTime pastDateTime = now.AddMonths(-1); // 현재로부터 한 달 전
// 두 날짜 사이의 차이 계산하기
TimeSpan difference = futureDateTime - now;
날짜와 시간 형식 지정하기
// 날짜와 시간을 문자열로 변환하여 특정 형식에 맞게 출력하기
string formattedDateTime = now.ToString("yyyy-MM-dd HH:mm:ss");
날짜와 시간 비교하기
// 두 날짜를 비교하여 이전인지, 이후인지, 같은지 확인하기
bool isFuture = futureDateTime > now;
bool isPast = pastDateTime < now;
bool isEqual = now == now;
유효성 검사하기
// 유효한 날짜와 시간인지 확인하기
bool isValidDate = DateTime.TryParse("2024-05-15", out DateTime parsedDate); // true or false 반환
[DateTime의 특징과 예시코드]
- 불변성 (Immutable):
- 수정할 수 없는 불변 객체입니다. 한 번 생성된 후에는 내부 상태를 변경할 수 없습니다.
- 가변성 (Mutable):
- 메서드를 사용하여 날짜 및 시간을 변경할 수 있는 가변성을 제공합니다.
- 시간대 정보 포함 (Timezone Awareness):
- 시간대 정보를 포함하고 있습니다. 그러나 이 정보는 제한적이며, 시간대 변경 및 간격 변환을 다루기에 적합하지 않을 수 있습니다.
- 제한된 범위 (Limited Range):
- 특정 범위의 날짜와 시간만 처리할 수 있습니다. 최소 값은 0001년 1월 1일이고, 최대 값은 9999년 12월 31일입니다.
불변성 (Immutable):
DateTime originalDateTime = DateTime.Now;
DateTime modifiedDateTime = originalDateTime.AddHours(5); // 기존 객체를 변경하는 대신 새로운 객체를 반환
Console.WriteLine(originalDateTime); // 원본은 변경되지 않음
Console.WriteLine(modifiedDateTime); // 새로운 값 출력
가변성 (Mutable):
DateTime mutableDateTime = DateTime.Now;
mutableDateTime = mutableDateTime.AddDays(1); // 기존 객체를 변경하여 새로운 날짜로 설정
Console.WriteLine(mutableDateTime); // 변경된 날짜 출력
시간대 정보 포함 (Timezone Awareness):
DateTime utcTime = DateTime.UtcNow; // UTC 시간 가져오기
DateTime localTime = DateTime.Now; // 현지 시간 가져오기
Console.WriteLine(utcTime); // UTC 시간 출력
Console.WriteLine(localTime); // 현지 시간 출력
제한된 범위 (Limited Range):
DateTime minDateTime = DateTime.MinValue; // 최소 날짜 및 시간
DateTime maxDateTime = DateTime.MaxValue; // 최대 날짜 및 시간
Console.WriteLine(minDateTime); // 0001-01-01 출력
Console.WriteLine(maxDateTime); // 9999-12-31 출력
[TimeSpan의 개념과 사용법]
시간 간격을 나타내는 구조체로, 두 날짜 또는 시간 사이의 시간 차이를 표현하는 데 사용됩니다. 이것은 일, 시간, 분, 초 및 밀리초 단위의 시간 간격을 저장할 수 있습니다.
[사용법]
생성하기:
// 일, 시간, 분, 초로 TimeSpan 생성
TimeSpan timeSpan1 = new TimeSpan(1, 2, 30, 15);
// 일(day)을 제외한 시간, 분, 초로 TimeSpan 생성
TimeSpan timeSpan2 = TimeSpan.FromHours(36.5);
더하기 및 빼기:
TimeSpan timeSpan3 = timeSpan1.Add(TimeSpan.FromMinutes(45)); // TimeSpan 더하기
TimeSpan timeSpan4 = timeSpan2.Subtract(TimeSpan.FromHours(12)); // TimeSpan 빼기
곱하기 및 나누기:
TimeSpan timeSpan5 = timeSpan1.Multiply(2.5); // TimeSpan 곱하기
TimeSpan timeSpan6 = timeSpan2.Divide(2); // TimeSpan 나누기
비교하기:
bool isEqual = (timeSpan1 == timeSpan2); // TimeSpan이 같은지 확인
bool isGreaterThan = (timeSpan1 > timeSpan2); // TimeSpan1이 TimeSpan2보다 큰지 확인
bool isLessThan = (timeSpan1 < timeSpan2); // TimeSpan1이 TimeSpan2보다 작은지 확인
속성 및 메서드 사용하기:
// TimeSpan의 일(day), 시간(hour), 분(minute), 초(second), 밀리초(millisecond) 속성
int days = timeSpan1.Days;
int hours = timeSpan1.Hours;
int minutes = timeSpan1.Minutes;
int seconds = timeSpan1.Seconds;
int milliseconds = timeSpan1.Milliseconds;
// TimeSpan의 총 시간을 밀리초로 반환하는 TotalXXX 속성
double totalHours = timeSpan1.TotalHours;
double totalMinutes = timeSpan1.TotalMinutes;
double totalSeconds = timeSpan1.TotalSeconds;
double totalMilliseconds = timeSpan1.TotalMilliseconds;
// TimeSpan을 문자열로 변환하여 출력
string timeSpanString = timeSpan1.ToString();
사용하여 날짜 및 시간 조작하기:
DateTime currentDateTime = DateTime.Now;
DateTime newDateTime = currentDateTime.Add(timeSpan1); // 현재 날짜와 TimeSpan을 더하여 새로운 날짜 생성
DateTime earlierDateTime = currentDateTime.Subtract(timeSpan2); // 현재 날짜에서 TimeSpan을 빼서 이전 날짜 생성
[TimeSpan 특징]
- 불변성 (Immutable):
- 한 번 생성되면 수정할 수 없는 불변 객체입니다. 새로운 값을 생성하려면 기존 값에 연산을 적용하여 새로운
TimeSpan
을 생성해야 합니다.
- 한 번 생성되면 수정할 수 없는 불변 객체입니다. 새로운 값을 생성하려면 기존 값에 연산을 적용하여 새로운
- 가변성 (Mutable)이 없음:
- 수정할 수 없기 때문에 값을 직접 변경할 수 없습니다. 대신에 새로운
TimeSpan
인스턴스를 생성하여 연산 결과를 저장해야 합니다.
- 수정할 수 없기 때문에 값을 직접 변경할 수 없습니다. 대신에 새로운
- 시간 간격 표현:
- 일(day), 시(hour), 분(minute), 초(second), 밀리초(millisecond)의 단위로 시간 간격을 표현할 수 있습니다.
- 양수 또는 음수 값:
- 양수 또는 음수 값으로 생성할 수 있으며, 각각 미래 시간 또는 과거 시간을 나타냅니다.
불변성 (Immutable):
TimeSpan timeSpan1 = TimeSpan.FromHours(2);
TimeSpan timeSpan2 = timeSpan1.Add(TimeSpan.FromMinutes(30)); // 새로운 TimeSpan 생성
Console.WriteLine(timeSpan1.TotalMinutes); // 기존 TimeSpan 값 변화 없음
Console.WriteLine(timeSpan2.TotalMinutes); // 새로운 값 출력
가변성 (Mutable)이 없음:
TimeSpan timeSpan3 = TimeSpan.FromDays(1);
// timeSpan3.Hours = 3; // 컴파일 에러: TimeSpan은 수정할 수 없음
TimeSpan newTimeSpan = timeSpan3.Add(TimeSpan.FromHours(3)); // 새로운 TimeSpan 생성
Console.WriteLine(newTimeSpan.TotalHours); // 새로운 값 출력
시간 간격 표현:
TimeSpan timeSpan4 = new TimeSpan(1, 2, 30, 15); // 1일 2시간 30분 15초
Console.WriteLine(timeSpan4.TotalDays); // 총 일 수 출력
Console.WriteLine(timeSpan4.TotalHours); // 총 시간 수 출력
양수 또는 음수 값:
DateTime now = DateTime.Now;
DateTime futureDateTime = now.AddHours(2);
DateTime pastDateTime = now.AddHours(-2);
TimeSpan timeSpanToFuture = futureDateTime - now;
TimeSpan timeSpanToPast = now - pastDateTime;
Console.WriteLine(timeSpanToFuture.TotalHours); // 양수 값: 미래 시간과의 시간 간격
Console.WriteLine(timeSpanToPast.TotalHours); // 음수 값: 과거 시간과의 시간 간격
[DateTime과 TimeSpan의 유틸 클래스 제공]
public static class TimeUtility
{
// UTC 시간을 반환하는 메서드
public static DateTime GetUtcNow()
{
return DateTime.UtcNow;
}
// 로컬 시간을 반환하는 메서드
public static DateTime GetLocalTime()
{
return DateTime.Now;
}
// 두 날짜 사이의 경과 시간을 계산하여 TimeSpan으로 반환하는 메서드
public static TimeSpan GetElapsedTime(DateTime start, DateTime end)
{
return end - start;
}
// TimeSpan을 문자열로 변환하는 메서드
public static string TimeSpanToString(TimeSpan timeSpan)
{
return timeSpan.ToString(@"hh\:mm\:ss");
}
// 현재 시간을 특정 시간대로 변환하는 메서드
public static DateTime ConvertToTimeZone(DateTime dateTime, string timeZoneId)
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
return TimeZoneInfo.ConvertTime(dateTime, timeZone);
}
// 특정 시간대의 현재 시간을 반환하는 메서드
public static DateTime GetTimeInTimeZone(string timeZoneId)
{
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, timeZone);
}
// 날짜 형식의 문자열을 DateTime으로 변환하는 메서드
public static DateTime ParseDateTime(string dateString, string format)
{
return DateTime.ParseExact(dateString, format, null);
}
// DateTime을 날짜 형식의 문자열로 변환하는 메서드
public static string FormatDateTime(DateTime dateTime, string format)
{
return dateTime.ToString(format);
}
// 틱을 시간, 분, 초로 변환하는 메서드
public static (int Hours, int Minutes, int Seconds) TicksToTime(long ticks)
{
TimeSpan timeSpan = TimeSpan.FromTicks(ticks);
return (timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);
}
// 틱을 현재 시간의 문자열로 반환하는 메서드
public static string TicksToTimeString(long ticks)
{
DateTime dateTime = new DateTime(ticks);
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
}
[사용 예시]
// 사용 예시
class Program
{
static void Main(string[] args)
{
// 현재 시간과 지정된 시간대의 현재 시간 가져오기
DateTime localTime = TimeUtility.GetLocalTime();
DateTime utcTime = TimeUtility.GetUtcNow();
DateTime newYorkTime = TimeUtility.GetTimeInTimeZone("Eastern Standard Time");
// 현재 시간 출력
Console.WriteLine("로컬 시간: " + localTime);
Console.WriteLine("UTC 시간: " + utcTime);
Console.WriteLine("뉴욕 시간: " + newYorkTime);
// 날짜 형식의 문자열을 DateTime으로 변환
string dateString = "2024-05-15 12:30:00";
DateTime parsedDateTime = TimeUtility.ParseDateTime(dateString, "yyyy-MM-dd HH:mm:ss");
Console.WriteLine("파싱된 날짜: " + parsedDateTime);
// DateTime을 날짜 형식의 문자열로 변환
string formattedDateTime = TimeUtility.FormatDateTime(localTime, "yyyy-MM-dd HH:mm:ss");
Console.WriteLine("형식화된 날짜: " + formattedDateTime);
// 틱을 시간, 분, 초로 변환
long ticks = TimeSpan.FromHours(3).Ticks;
var timeTuple = TimeUtility.TicksToTime(ticks);
Console.WriteLine($"틱을 시간으로 변환: {timeTuple.Hours}시간 {timeTuple.Minutes}분 {timeTuple.Seconds}초");
// 틱을 현재 시간의 문자열로 변환
long currentTicks = DateTime.UtcNow.Ticks;
string currentTimeString = TimeUtility.TicksToTimeString(currentTicks);
Console.WriteLine($"틱을 현재 시간의 문자열로 변환: {currentTimeString}");
}
}
제가 작성한 유틸함수의 사용 예시들입니다.
[마무리 글]
DateTime과 TimeSpan은 처음 사용하실 때 개념을 숙지하고 사용법을 이해하는데 시간이 꽤 걸리며, 익숙해지기 전까지 어렵게 느껴지는 부분이 많습니다. 제가 작성해드린 예시코드를 눈으로 익히시고, 유틸클래스와 그 사용법을 숙지하셔서 개발에 시간관련 기능을 구현할 때 드는 시간을 최소화 하시기 바랍니다.