2012-10-01 3 views
1

로컬 시간대에서 복잡한 객체의 모든 날짜 시간 필드는 내가 모두를 변환 할 등 출생의 고객 날짜에 대한 모든 세부로 구성되어 고객 개체, 가입 날짜,변환 UTC

이 날짜 필드는 유니버설 날짜 시간 및 데이터베이스에 저장합니다.

누구든지 고객 개체의 모든 날짜 필드를 어떻게 보편적 인 날짜 시간으로 변환 할 수 있습니까?

나는 Customer.ChangeToUTC()를 호출 할 때 고객에게있는 모든 날짜/시간 필드가 표준시로 변경되어야하는 솔루션을 원합니다.

+1

시도한 코드는 어떻게됩니까? 어떤 DAL을 사용하고 있습니까? EF 또는 ADO.NET? –

답변

0

날짜 시간에 익숙하다면 꽤 간단합니다.

customer.BirthDate = customer.BirthDate.ToUniversalTime(); 

모든 날짜 필드에 대해 위 작업을 수행하고 고객 ID 번호에 where 절을 사용하여 업데이트 쿼리를 실행하십시오.

+0

문제는 고객에게 제출 된 새 날짜를 추가 할 때 customer.newdatefiled = new custome.nedatefile.ToUniversalTime()으로 호출해야한다는 것입니다. 대신 customer.ConvertToUST()를 호출 할 때 Customer 객체의 모든 날짜 필드를 범용 datetime으로 변경해야하는 단일 함수를 만들고 싶습니다. –

+0

우선 중요한 정보를 주셔서 감사합니다. 문제는 고객에게 새 날짜를 추가하면 customer.newdatefiled = new custome.nedatefile.ToUniversalTime()으로 호출해야한다는 것입니다. 대신 customer.ConvertToUST()를 호출하면 Customer 객체의 모든 날짜 필드가 Universal datetime으로 변경되도록 단일 함수를 만들려고합니다. –

+0

@AbdulAdhar : 예, 모델에 필드를 추가하면 다음을 수행해야합니다. 앱을 통해 올바르게 처리하는지 확인해야합니다. 그것은 예상된다. 모든 날짜/시간 관련 값에 동일한 규칙을 적용 할 수 있어야합니다. 내 대답은 말하지만, 나는 어쨌든 보편적으로나 로컬 날짜/시간에 동일한 속성을 사용하지 말 것을 권장합니다. –

1

이 함께 할 수있는 간단한 일이 :

TimeZone ltz = TimeZone.CurrentTimeZone; 

DateTime t1 = DateTime.Now; 

DateTime t2 = ltz.ToUniversalTime(t1); 
+0

현지 시간에서 유니버설로의 변환은 일광 절약 시간제 변경으로 인해 모호 할 수 있음에 유의하십시오. 프레임 워크는 이것을 ""흥미로운 방식으로 처리합니다 (http://msmvps.com/blogs/jon_skeet/archive/2012/05/02/more-fun-with-datetime.aspx) –

+0

이제 괜찮습니까. ?? @ JonSkeet –

+0

아니요, 여전히 모호합니다. 시계가 돌아 오면 특정 현지 시간이 두 번 발생합니다. (나는 요즘에는'TimeZone'을 사용하지 말고'TimeZoneInfo'를 사용하십시오.). –

1

사람은 고객 객체에서 모든 날짜 필드를 가지고

그냥 할 보편적 날짜 시간에 사람들을 변환하는 방법 좀 도와 줄래 수동으로. 그러나 은 원래 Customer 유형의 속성을 다시 사용하여을 수행하지 않습니다. 나는 전에 전에 개체를 만들거나 (데이터를 처음 가져올 때) 데이터베이스 전송을 위해 경량 DTO의 일부로 수행합니다. 이 속성은, 보편적 인 지역이 될 것입니다 여부를 알 수없는 경우, 또는 지정되지 않은 것이 많이있을거야 - 당신이을 특정 속성을 해석하는 방법을 알고 충분히 때 날짜/시간 속성에 대한

추론은 어렵다 더 세게.

같은 것들 날짜은 보편적이지 않다고 생각하는 것조차별로 의미가 없습니다. 데이터베이스에 저장하기 위해 시작하려면 DateTimeKind.Utc을 사용하여 명시 적으로 만들고 싶을 수도 있지만 근본적으로 날짜는 날짜입니다. .NET 프레임 워크의 문제점 중 하나는 날짜에 대해 별도의 데이터 형식이 없다는 것입니다.

.NET 용 대체 날짜/시간 API 인 Noda Time이라는 프로젝트가 있습니다. 한 가지 옵션은 당연히 사용하는 것이지만 BCL 유형을 고수하고 싶다고 가정하면 올바른 방법으로 날짜와 시간을 생각할 때 도움이되도록 conceptstype choices 문서를 읽을 가치가 있다고 생각합니다. 모델의 각 속성에 대해 을 입력하고을 사용하는 것이 좋습니다. 그런 다음 문서화하십시오. 코드에서 다르게 처리하기를 원할 것입니다.

0

나는 동일한 문제에 직면 해있다. 그리고 제 경우에는 해결책이 필요했습니다. DateTime 필드가있는 너무 복잡한 모델이 너무 많기 때문입니다.

가 는
public static class ObjectExtensions 
{ 
    /// <summary> 
    /// Convert all DateTime fields in a complex object from UTC to a destination time zone. 
    /// </summary> 
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam> 
    /// <param name="obj">Object that will be deeply converted.</param> 
    /// <param name="destTimeZone"><c>TimeZoneInfo</c> object of a destination time zone.</param> 
    public static void DeepConvertFromUtc<TInput>(this TInput obj, TimeZoneInfo destTimeZone) 
     where TInput : class 
    { 
     obj.DeepConvert(TimeZoneInfo.Utc, destTimeZone); 
    } 

    /// <summary> 
    /// Convert all DateTime fields in a complex object from source time zone to UTC. 
    /// </summary> 
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam> 
    /// <param name="obj">Object that will be deeply converted.</param> 
    /// <param name="sourceTimeZone"><c>TimeZoneInfo</c> object of a source time zone.</param> 
    public static void DeepConvertToUtc<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone) 
     where TInput : class 
    { 
     obj.DeepConvert(sourceTimeZone, TimeZoneInfo.Utc); 
    } 

    /// <summary> 
    /// Convert all DateTime fields in a complex object from UTC to a destination time zone. 
    /// </summary> 
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam> 
    /// <param name="obj">Object that will be deeply converted.</param> 
    /// <param name="sourceTimeZone"><c>TimeZoneInfo</c> object of a source time zone.</param> 
    /// <param name="destTimeZone"><c>TimeZoneInfo</c> object of a destination time zone.</param> 
    public static void DeepConvertTime<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone) 
     where TInput : class 
    { 
     obj.DeepConvert(sourceTimeZone, destTimeZone); 
    } 

    private static void DeepConvert<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone) 
     where TInput : class 
    { 
     if (obj == null) 
     { 
      return; 
     } 

     var items = obj as ICollection; 
     if (items != null) 
     { 
      foreach (var item in items) 
      { 
       item.DeepConvert(sourceTimeZone, destTimeZone); 
      } 

      return; 
     } 

     var props = obj.GetType().GetProperties(); 
     foreach (var prop in props.Where(prop => !IsIgnore(prop))) 
     { 
      if (prop.PropertyType == typeof(DateTime) || prop.PropertyType == typeof(DateTime?)) 
      { 
       prop.ConvertDateTime(obj, sourceTimeZone, destTimeZone); 
       continue; 
      } 

      var value = prop.GetValue(obj); 
      var list = value as ICollection; 
      if (list != null) 
      { 
       foreach (var item in list) 
       { 
        item.DeepConvert(sourceTimeZone, destTimeZone); 
       } 

       continue; 
      } 

      // here I check that an object is located in one of my assemblies 
      if (prop.PropertyType.Assembly.FullName.StartsWith("Should be your namespace")) 
      { 
       value.DeepConvert(sourceTimeZone, destTimeZone); 
      } 
     } 
    } 

    private static void ConvertDateTime<TInput>(this PropertyInfo prop, TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone) 
     where TInput : class 
    { 
     var value = prop.GetValue(obj); 
     if (value != null) 
     { 
      var dateTime = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Unspecified); 
      value = TimeZoneInfo.ConvertTime(dateTime, sourceTimeZone, destTimeZone); 

      var setMethod = prop.SetMethod; 
      if (setMethod != null) 
      { 
       setMethod.Invoke(obj, new[] { value }); 
      } 
     } 
    } 

    private static bool IsIgnore(this PropertyInfo prop) 
    { 
     var attr = prop.GetCustomAttribute<IgnoreUtcConversionAttribute>(); 
     return attr != null; 
    } 
} 

public class IgnoreUtcConversionAttribute : Attribute 
{ 
} 

당신은 아주 간단하게 사용할 수 있습니다 :

var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Belarus Standard Time"); 
yourComplexObject.DeepConvertToUtc(timeZoneInfo); 

당신 경우 :

yourComplexObject.DeepConvertToUtc(TimeZoneInfo.Local); 

// a collection could be converted as well 
collection.DeepConvertToUtc(TimeZoneInfo.Local); 

은 또한 당신이 FindSystemTimeZoneById 방법에서 TimeZineInfo 개체를 얻을 수 있습니다 내 요구를 들어 나는 다음 확장을 썼다 모델에 양방향 효과가 있으면 [IgnoreUtcConversion] :

을 사용하여 한 가지 설명을 장식해야합니다.
public class Customer 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public DateTime Birth { get; set; } 

    public Address Address { get; set; } 
} 

public class Address 
{ 
    public string Street { get; set; } 

    public DateTime LastUpdated { get; set; } 

    [IgnoreUtcConversion] 
    public Customer Customer { get; set; } 
} 
관련 문제