Programing

C #의 특정 시간대에서 DateTime 만들기

crosscheck 2020. 6. 23. 07:44
반응형

C #의 특정 시간대에서 DateTime 만들기


시간대가 잘못 설정되어 수정 된 경우 사례를 테스트하기 위해 단위 테스트를 작성하려고합니다.

테스트에서 로컬 시간대가 아닌 시간대에 DateTime 객체를 만들어 테스트를 실행하는 사람들이 위치에 관계없이 성공적으로 수행 할 수 있어야합니다.

DateTime 생성자에서 볼 수 있듯이 TimeZone을 현지 시간대, UTC 시간대 또는 지정하지 않도록 설정할 수 있습니다.

PST와 같은 특정 시간대로 DateTime을 어떻게 만듭니 까?


Jon의 답변TimeZone대해 이야기 하지만 대신 TimeZoneInfo사용하는 것이 좋습니다 .

개인적으로 나는 가능한 한 UTC로 물건을 유지하는 것을 좋아합니다 (적어도 과거 에는 미래위해 UTC를 저장하면 잠재적 인 문제가 있습니다 ). 다음과 같은 구조를 제안합니다.

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
    {
        var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
        utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone); 
        this.timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return timeZone; } }

    public DateTime LocalTime
    { 
        get 
        { 
            return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); 
        }
    }        
}

더 명확하게하기 위해 "TimeZone"이름을 "TimeZoneInfo"로 변경할 수 있습니다. 더 짧은 이름을 선호합니다.


DateTimeOffset 구조는 정확히이 유형의 용도로 작성되었습니다.

참조 : http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx

특정 시간대를 사용하여 DateTimeOffset 객체를 만드는 예는 다음과 같습니다.

DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));


여기에있는 다른 답변은 유용하지만 태평양에 구체적으로 액세스하는 방법은 다루지 않습니다.

public static DateTime GmtToPacific(DateTime dateTime)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime,
        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
}

"태평양 표준시"는 일반적으로 "태평양 일광 절약 시간"과 다른 것을 의미하지만 이상하게도 태평양 표준시를 의미합니다. 실제로 FindSystemTimeZoneById가져 오기에 사용 하는 경우 사용 가능한 속성 중 하나는 해당 시간대가 현재 일광 절약 시간인지 여부를 알려주는 바보입니다.

사용자가 요청한 위치 등에 따라 다른 TimeZone에서 필요한 DateTime을 처리하기 위해 함께 던진 라이브러리에서 더 일반적인 예를 볼 수 있습니다.

https://github.com/b9chris/TimeZoneInfoLib.Net

시간 목록이 Windows 레지스트리에서 제공되므로 Windows 외부에서는 작동하지 않습니다 (예 : Linux의 경우 Mono). HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

그 아래에는 키 (레지스트리 편집기의 폴더 아이콘)가 있습니다. 그 키의 이름은 당신이 전달하는 것 FindSystemTimeZoneById입니다. Linux에서는 적절하게 살펴 보지 않은 별도의 Linux 표준 시간대 정의 세트를 사용해야합니다.


Jon Skeet 이 확장 방법으로 웹에 약간 응답 하도록 변경했습니다 . 그것은 매력처럼 하늘빛에도 작용합니다.

public static class DateTimeWithZone
{

private static readonly TimeZoneInfo timeZone;

static DateTimeWithZone()
{
//I added web.config <add key="CurrentTimeZoneId" value="Central Europe Standard Time" />
//You can add value directly into function.
    timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["CurrentTimeZoneId"]);
}


public static DateTime LocalTime(this DateTime t)
{
     return TimeZoneInfo.ConvertTime(t, timeZone);   
}
}

이를 위해 커스텀 객체를 만들어야합니다. 사용자 정의 개체에는 두 가지 값이 포함됩니다.

해당 CLR 제공 데이터 형식이 있는지 확실하지 않지만 적어도 TimeZone 구성 요소는 이미 사용 가능합니다.


I like Jon Skeet's answer, but would like to add one thing. I'm not sure if Jon was expecting the ctor to always be passed in the Local timezone. But I want to use it for cases where it's something other then local.

I'm reading values from a database, and I know what timezone that database is in. So in the ctor, I'll pass in the timezone of the database. But then I would like the value in local time. Jon's LocalTime does not return the original date converted into a local timezone date. It returns the date converted into the original timezone (whatever you had passed into the ctor).

I think these property names clear it up...

public DateTime TimeInOriginalZone { get { return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); } }
public DateTime TimeInLocalZone    { get { return TimeZoneInfo.ConvertTime(utcDateTime, TimeZoneInfo.Local); } }
public DateTime TimeInSpecificZone(TimeZoneInfo tz)
{
    return TimeZoneInfo.ConvertTime(utcDateTime, tz);
}

Using TimeZones class makes it easy to create timezone specific date.

TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(TimeZones.Paris.Id));

참고URL : https://stackoverflow.com/questions/246498/creating-a-datetime-in-a-specific-time-zone-in-c-sharp

반응형