2012-05-10 5 views
2

내 머리가 아틀라스에 흩어져있는 작은 선으로 폭발 할 준비가 될 때까지 여러 게시물을 읽었습니다.한 시간대에서 다른 시간대로 변환하는 것이 왜 그렇게 어려운가요?

  1. 나는이 사업에 대해 표시 할 약속의 전체 일정이 : 여기

    내가하고 싶었던 것입니다.

  2. 프로덕션 서버가 캘리포니아에있는
  3. 내 dev에 기계가 PST에
  4. 비즈니스 뉴욕에 (EDT) (PST)
  5. 캘린더 데이터는 UTC의 DB에 저장되어

내가 원하는 것은 EDT (5 월 15 일 오전 9시 - 오후 5시)에 명시된 시간 범위를 가져 와서 모든 약속을 캘린더에 표시하는 것입니다.

내 캘린더 컨트롤에서 "5/15/12 오전 9 시부 터 5시 15 분부 터 5 시부 터 5 시까 지 약속을 원합니다"라고 말합니다. 괜찮 으면, 데이터베이스 프로 시저를 호출하고 날짜 값을 전달합니다. UTC, 즉 (5/15/12 13:00 UTC - 5/15/12 21:00 UTC). 내가 그들을 데려 올 때, 나는 그들을 당신에게 건네주기 전에 그들을 EDT로 되돌릴 것이다.

그러나 .NET은 나를 위를 이동시키는이 간단한 작업을 찾을 것이라는 것을 거의 알지 못했습니다.

TimeZoneInfo zoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") 

을하지만 일을 일로서 그까지이다 :

나는 사용하여 TimeZoneInfo 중 잘있어. 여기

내가 노력 무엇 다음 :

DateTime rangeStartUTC = TimeZoneInfo.ConvertTimeToUtc(rangeStart, zoneInfo); 

EXCEPTION: Kind is not properly specified. 

(WTF는 종류입니까?) 나는 내가로 변환 할 당신에게, 나는 그것이 EDT에 당신에게, 당신에게 내가 변환 할 시간을 말했다 UTC. 뭘 더 원하니? 나는 그것을 손으로 할 수 있었다. F ** ing 이미 해.

그래서 종류를 설정하려고했지만 두 가지 값만 있습니다. 로컬 또는 Utc. 그러나 나의 시간은 지방도 Utc도 아니다. 그럼 왜 나 한테 시간대 정보를 묻는거야? 그냥 시스템 시간을 물어서 현지 시간대를 알려주시겠습니까? 예상 할 수는 있지만 둘 다 효과가 없습니다. (예, Unspecified 문서에 따르면,하지만 다시는 문서에 따르면, 그것은 실제로 아무것도하지 않으며 그렇습니다 나는 그것도 시도했습니다).

다음, 나는 시도 :

TimeZoneInfo.ConvertTime(rangeStart, zoneInfo, TimeZoneInfo.Utc) 

SAME 절름발이 변명!

성 존 스키 위 (St John Skeet)의 구절을 더 읽을 시간.

아시겠지만 새 클래스 인 DateTimeOffset이 있습니다. 모든 문제를 해결할 것입니다. 하나님은 모든 좋은 자비 .NET 4.0의 현상금을위한 축복 ...

DateTimeOffset offStartTime = new DateTimeOffset(rangeStart, zone.GetUtcOffset(rangeStart)); 
rangeStartUTC = offStartTime.UtcDateTime; 

EXCEPTION: "Offset should be 0 for Utc dates" 

Gaaaaah! rangeStart가 Utc라고 결론을 내 렸습니다. 내가 너 한테 말 했니?

수많은 사람들이 인용하고 있습니다. TimeZoneInfo.ConvertTime (rangeStart, zone)을 솔루션으로 사용하면 어떻게 작동 할만큼 "친절"할 수 있습니까? 원본 시간대가 현지 시간대와 같은 경우가 아니라면 편리합니다.

.NET C# 개발자는 어떻게해야할까요?

+2

노다 시간을 사용하십시오. – SLaks

+0

MSDN의 [이 트리를 읽으십시오] (http://msdn.microsoft.com/en-us/library/bb384268)가 아직 있습니까? 그것은 시간대와'DateTime'와 함께 일하는 방법에 대해 깊이있게 간다. –

+0

@Slaks - 확실히 다음 프로젝트를 생각하고있다. 이 하나는 너무 많은 변경/테스트주기가 필요합니다. – Hooligan

답변

2

DateTime.SpecifyKind(rangeStart, DateTimeKind.Unspecified)DateTimeOffset 또는 TimeZoneInfo 전에 시도하십시오. 시간 자체의 변환을해서는 안되며 Kind 만 변경하면됩니다. 내가 알고있는 것처럼

DateTimeKind 중 하나 Unspecified 수 또는 TimeZoneInfo.Utc에 대한 TimeZoneInfo.LocalUtc에 대한 Local을 반환 개인 TimeZoneInfo.GetCorrespondingKind() 방법의 결과와 일치해야합니다.

업데이트 : 죄송합니다. 원본 답변이 잘못되었습니다. 이제는 모두 좋을 것입니다.

+0

Andrey - 솔루션을 제공하는 데 시간을내어 주셔서 감사합니다. 나는 3 개의 가능한 모든 값을 가지고, 모두가 예외로 끝나고, ConvertTime()을 호출했을 때, SpecifyKind()를 시도했다. TimeZoneOffset을 사용하면 도움이 될 것이라고 제안 하시겠습니까? 나는 아직 시도하지 않았다. 그것이 어떻게되는지 곧 알려줄 것입니다. – Hooligan

+0

'SpecifyKind'의 리턴 결과를 사용 했습니까? 그것은'DateTime' 자체를 변경하지 않기 때문에 대신 새로운 것을 생성합니다. –

+0

DateTime.Kind 값 이름은 약간의 오해의 소지가 있습니다. "로컬"은 현지 시간이 아니라 실제 현재 로컬 시간과 같은 로컬 시간을 의미합니다. "Unspecified"라는 이름은 저를 버렸습니다. 정말로 "Other"라고 불려야했습니다. 이들에 대한 올바른 의미를 이해하면 TimeZoneInfo 예외가 훨씬 더 적합합니다. – Rich

관련 문제