2014-11-01 2 views
1

저는 writing a managed wrapper around Massachusetts Bay Transportation Authority (MBTA) Realtime API으로 일하고 있습니다. 그들은 유닉스 타임 스탬프 (epoch) 인 서버 시간을 반환하는 API를 가지고있다. 내가 그것을 구현하고있는 아래 도서관은 내가 BCL 시간대에 대한 지원을 제한 의미 PCL Profile 78, 그래서 나는 DateTimeAmerica/New_York을 동부 시간으로 서버에서 반환 시간을 변환하려고 Nodatime에보크 타임 스탬프를 동부 표준시로 변환하고 노다 티 메을 사용하여 반전하는 우아한 방법

을 사용하는 의지 개체 및 반대로 방법. My current code is very dirty

public static class TimeUtils 
{ 
    static readonly DateTimeZone mbtaTimeZone = DateTimeZoneProviders.Tzdb["America/New_York"]; 
    static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 

    public static DateTime GetMbtaDateTime (long unixTimestamp) 
    { 
     var mbtaEpochTime = epoch.AddSeconds (unixTimestamp); 
     var instant = Instant.FromUtc (mbtaEpochTime.Year, mbtaEpochTime.Month, 
      mbtaEpochTime.Day, mbtaEpochTime.Hour, mbtaEpochTime.Minute, mbtaEpochTime.Second); 
     var nodaTime = instant.InZone (mbtaTimeZone); 
     return nodaTime.ToDateTimeUnspecified(); 
    } 

    public static long MbtaDateTimeToUnixTimestamp (DateTime time) 
    { 
     TimeSpan secondsSinceEpochMbtaTz = time - epoch; 
     var instant = Instant.FromUtc (time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second); 
     var mbtaTzSpan = mbtaTimeZone.GetUtcOffset (instant).ToTimeSpan(); 
     var epochDiff = secondsSinceEpochMbtaTz - mbtaTzSpan; 
     return (long)epochDiff.TotalSeconds; 
    } 
} 

간단히 작성하는 다른 방법이 있습니까? Nodatime이 신기원 시간을 America/New_York DateTime으로 변환하고 America/New_York 신시대 시간을 지원해야한다고 희망합니다. 당신이 정말로가 이있는 경우에만 DateTime에 의존 - 내 방법 MbtaDateTimeToUnixTimestamp는 의견에 언급 한 바와 같이, 당신의 코드를 통해 노다 시간 유형을 사용하는 것이 가장 좋은 것입니다, 잔인한 해킹을 먼저

+1

정말'DateTime'을 사용해야합니까? Noda Time은 코드 전체에서 사용할 때 가장 잘 작동합니다. –

답변

6

입니다. 이를 통해 전체적으로 훨씬 명확한 코드로 이어질 것입니다. Instant에 유닉스 타임 스탬프를 변환

정말 간단합니다 :

Instant instant = Instant.FromSecondsSinceUnixEpoch(seconds); 

그런 다음 현재 코드 당으로 ZonedDateTime로 변환 ... 그리고 당신이 정말로 DateTime를 사용해야 할 경우 ToDateTimeUnspecified를 사용하는 것은 괜찮 수 있습니다.

반대의 경우 현재 코드가 깨졌습니다. DateTime은 UTC 값으로 간주됩니다. 나중에 사용하는 시간대와는 확연히 다릅니다. 입력을 LocalDateTime으로 변환하고 표준 시간대를 적용하고 싶습니다. 예 :

public static long MbtaDateTimeToUnixTimestamp(DateTime time) 
{ 
    var local = LocalDateTime.FromDateTime(time); 
    var zoned = local.InZoneStrictly(mbtaTimeZone); 
    var instant = zoned.ToInstant(); 
    return instant.Ticks/NodaConstants.TicksPerSecond; 
} 

전화는 InZoneStrictly입니다. 또는 중 하나가 두 번 존재했던 로컬 시간에 전달하면 DST 전환으로 인해 두 경우 모두 예외가 발생합니다. 이것은 아마도 이 아니며이 될 수 있습니다 - 당신은 정말로 당신이 그 사건에서 일어나고 싶은 일에 대해 생각하거나 그것들이 실현 가능한 것을 피하려고 노력할 필요가 있습니다. 자세한 내용 및 옵션은 time zones section of the documentation을 참조하십시오.