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의 특징과 예시코드]

      1. 불변성 (Immutable):
        • 수정할 수 없는 불변 객체입니다. 한 번 생성된 후에는 내부 상태를 변경할 수 없습니다.
      2. 가변성 (Mutable):
        • 메서드를 사용하여 날짜 및 시간을 변경할 수 있는 가변성을 제공합니다.
      3. 시간대 정보 포함 (Timezone Awareness):
        • 시간대 정보를 포함하고 있습니다. 그러나 이 정보는 제한적이며, 시간대 변경 및 간격 변환을 다루기에 적합하지 않을 수 있습니다.
      4. 제한된 범위 (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 특징]

      1. 불변성 (Immutable):
        • 한 번 생성되면 수정할 수 없는 불변 객체입니다. 새로운 값을 생성하려면 기존 값에 연산을 적용하여 새로운 TimeSpan을 생성해야 합니다.
      2. 가변성 (Mutable)이 없음:
        • 수정할 수 없기 때문에 값을 직접 변경할 수 없습니다. 대신에 새로운 TimeSpan 인스턴스를 생성하여 연산 결과를 저장해야 합니다.
      3. 시간 간격 표현:
        • 일(day), 시(hour), 분(minute), 초(second), 밀리초(millisecond)의 단위로 시간 간격을 표현할 수 있습니다.
      4. 양수 또는 음수 값:
        • 양수 또는 음수 값으로 생성할 수 있으며, 각각 미래 시간 또는 과거 시간을 나타냅니다.

      불변성 (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은 처음 사용하실 때 개념을 숙지하고 사용법을 이해하는데 시간이 꽤 걸리며, 익숙해지기 전까지 어렵게 느껴지는 부분이 많습니다. 제가 작성해드린 예시코드를 눈으로 익히시고, 유틸클래스와 그 사용법을 숙지하셔서 개발에 시간관련 기능을 구현할 때 드는 시간을 최소화 하시기 바랍니다.

      답글 남기기

      이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다