[C# 문법] C# .NET의 DateTime 모범 사례

참조

 

소개

  • C# 개발자가 작업하고 있는 거의 모든 소프트웨어 시스템에서 일부 작업에 대한 TimeStamp를 나타내기 위해 DateTime 을 사용합니다.
  • 그러나, 어떤 경우에는 DateTime 을 사용하면서 치명적일 수 있는 몇 가지 실수를 합니다.
  • 따라서 C# .NET에서 DateTime을 처리할 때 따라야 할 모범 사례를 공유합니다.

 

DateTime vs DateTimeOffset

 

DateTime

  • DateTime 은 특정 날짜와 시간을 정의합니다. 또한, 인스턴스에 담긴 시간의 기준을 나타내는 3상태 플래그가 있습니다.
    • Local - 로컬 타임
    • UTC - UTC
    • Unspecfied - 둘 다 지정하지 않았는지
  • DateTime 을 사용할 때 현재 시스템 날짜가 저장되고 변수 내부에 캡슐화되지만 저장거나 시간대에 연결하지 않습니다.
  • 따라서 서로 다른 시간대를 가진 둘 이상의 시스템이 사용되는 경우 결국 문제가 발생합니다.

 

DateTimeOffset

  • 반대로 DateTimeOffset 은 다음과 같은 UTC 시간으로부터의 오프셋을 하나의 TimeSpan에 저장합니다.
  • 이런 식으로 저장된 값은 값 자체를 망치지 않고 다른 표준 시간대로 변환될 수 있는 형식으로 저장될 때 통합될 수 있습니다.UTC 시간이란? UTC 시간은 Coordinated Universal Time(UTC)로 협정 세계시 또는 협조 시계시 라고 불립니다.
  • 이러한 차이는 상등 비교에 영향 을 미칩니다.
    • DateTime은 비교 시 3상태 플래그를 무시하고, 두 값의 연, 월, 일, 시, 분 등이 같으면 둘이 같다고 간주합니다.
    • DateTimeOffset은 두 값이 시간상의 같은 지점 을 가리킬 때에만 같다고 간주합니다.
    • 예를 들어, DateTime 은 다음 두 값이 다르다고 간주하지만 DateTimeOffset 은 같다고 간주합니다.
      • July 01 2022 09:00:00 +00:00 (GMT)
      • July 01 2022 03:00:00 -06:00 (중앙아메리카 지역 시간대)

 

결론

  • 대부분의 경우에는 DateTimeOffset 을 사용한 상등 논리가 바람직 합니다.
  • 예를 들어, 두 국제 행사 중 어느 것이 더 최근인지 계산하는 경우 DateTimeOffset을 사용하면 별다른 처리 없이도 올바른 답을 얻을 수 있습니다.
  • 그러나, 실행 시점에서 Local 컴퓨터에 상대적인 시간 값을 지정할 때에는 DateTime 이 더 낫습니다.
  • 예를 들어, 모든 해외 지사가 각자 다음 일요일 새벽 3시(활동이 가장 적은 시간) 에 자료를 백업해야 하는 경우에는 각 지사의 시간대를 기준으로 작동하는 DateTime이 바람직 합니다.

 

DateTimeOffset 올바른 초기화

  • 다음 예제 코드가 있습니다.
  • 여기서 현재 하고 있는 것은 두 메서드를 호출하고 Now에 해당하는 동일한 날짜 TimeStamp를 전달하는 것입니다.
using System;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;

public class Program
{
    public static void Main()
    {
        BadTiming();

        Console.WriteLine("\n\n");

        GoodTiming();
    }

    public static void DoSomething1(DateTimeOffset dt)
    {
        // do something
        Console.WriteLine(dt.ToString("o"));
    }

    public static void DoSomething2(DateTimeOffset dt)
    {
        // do something else
        Console.WriteLine(dt.ToString("o"));
    }

    public static void BadTiming()
    {
        Console.WriteLine("Testing Bad Timing");

        Console.Write("First Stamp: ");
        DoSomething1(DateTimeOffset.Now);

        Console.Write("Second Stamp: ");
        DoSomething2(DateTimeOffset.Now);
    }

    public static void GoodTiming()
    {
        Console.WriteLine("Testing Good Timing");

        var now = DateTimeOffset.Now;

        Console.Write("First Stamp: ");
        DoSomething1(now);

        Console.Write("Second Stamp: ");
        DoSomething2(now);
    }
}

 

잘못된 사용

  • 여기서 DoSomething1 메서드를 호출할 때 DateTimeOffset.Now 를 전달하고, DoSomething2 메서드도 동일한 작업을 수행합니다.
  • 하지만 다음과 같이 전달하게 되면, 서로의 TimeStamp가 다르다는 문제가 발생합니다.
public static void BadTiming()
{
    Console.WriteLine("Testing Bad Timing");

    Console.Write("First Stamp: ");
    DoSomething1(DateTimeOffset.Now);

    Console.Write("Second Stamp: ");
    DoSomething2(DateTimeOffset.Now);
}
  • 때문에 다음과 같이 코드를 작성해야 합니다.
public static void GoodTiming()
{
    Console.WriteLine("Testing Good Timing");

    var now = DateTimeOffset.Now;

    Console.Write("First Stamp: ");
    DoSomething1(now);

    Console.Write("Second Stamp: ");
    DoSomething2(now);
}

 

실행 결과

  • 실행 결과, BadTiming 에서는 두 메서드 간에 TimeStamp가 서로 다릅니다.
  • 반면에 GoodTiming 메서드를 실행할 때 TimeStamp는 동일한 것을 확인하실 수 있습니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY