2012-06-21 38 views
5

Tôi có một ngày serialized như là một chuỗi "2012-06-20T13: 19: 59.1091122Z"DateTimeConverter chuyển đổi từ chuỗi UTC

Sử dụng DateTimeConverter, điều này được chuyển đổi sang một đối tượng DateTime {22: 49: 59,1091122} với thuộc tính Kind được đặt thành "Địa phương".

ví dụ: Kiểm tra sau không thành công:

private static readonly DateTime UtcDate = new DateTime(634757951991091122, DateTimeKind.Utc); 
    private const string UtcSerialisedDate = "2012-06-20T13:19:59.1091122Z"; 

    [Test] 
    public void DateTimeConverter_Convert_From_Utc_String() 
    { 
     // Arrange 
     var converter = TypeDescriptor.GetConverter(typeof(DateTime)); 

     // Act 
     var result = converter.ConvertFrom(UtcSerialisedDate); 

     // Assert 
     Assert.AreEqual(UtcDate, result); 
     Assert.AreEqual(DateTimeKind.Utc, ((DateTime)result).Kind); 
    } 

Tôi hơi ngạc nhiên bởi điều này ... Tôi đã mong đợi rằng đối tượng DateTime được trình chuyển đổi trả về sẽ là UTC.

Các tài liệu nói rằng DateTimeConverter sử dụng DateTime.Parse, nhưng tôi đoán nó không được sử dụng tùy chọn DateTimeStyles.RoundtripKind.

Có cách nào xung quanh vấn đề này không?

Trả lời

6

Lỗi thực sự ở đây là DateTime.Parse() không có bất kỳ DateTimeStyles nào được chuyển qua vẫn sẽ thấy "Z" và nhận ra rằng nó sẽ được phân tích cú pháp là UTC. Nhưng may mắn nhận được MS để thừa nhận hoặc sửa chữa điều đó.

Vấn đề cụ thể được minh họa bởi mẫu mã của bạn là DateTimeConverter phải ghi đè các phương thức từ TypeConverter và do đó không có khả năng chuyển các tham số phụ như DateTimeStyles. Đó là quá xấu nó không thực hiện một số loại tài sản tĩnh hoặc threadstatic cho việc này. Nó thực sự tận dụng lợi thế của Culture.CurrentCulture của thread, nhưng DateTimeStyles là một điều riêng biệt từ văn hóa, vì vậy than ôi - đó là một kết thúc chết khác.

Tôi cho rằng bạn bị khóa bằng cách sử dụng trình chuyển đổi, thay vì chỉ gọi phân tích cú pháp trực tiếp? Đây có phải là một yêu cầu khó khăn? Nếu không, bạn có thể thực hiện các thao tác sau:

public static object ConvertFrom<T>(string value) 
{ 
    if (typeof(T) == typeof(DateTime)) 
    return DateTime.Parse(value, null, DateTimeStyles.RoundtripKind); 

    var converter = TypeDescriptor.GetConverter(typeof(T)); 
    return converter.ConvertFrom(value); 
} 

Cách khác sẽ sử dụng số DateTimeOffsetConverter thay vào đó - nó hiểu múi giờ Z chính xác. Sau đó, bạn có thể sử dụng thuộc tính .UtcDateTime của kết quả để quay lại DateTime với loại UTC.