OK, tôi thiếu gì ở đây? MSDN nói như sau liên quan đến DateTimeSerializationMode với:Nối tiếp chuỗi XML của DateTime và xsd: date?
Trong các phiên bản 2.0 và sau này của .Net Framework , với tài sản này thiết lập để đối tượng được kiểm tra RoundtripDateTime để xác định xem họ đang ở địa phương, hoặc tính theo giờ UTC một thời gian không xác định khu vực và được tuần tự hóa theo cách như vậy rằng thông tin này được giữ nguyên. Đây là hành vi mặc định và được đề nghị cho tất cả các ứng dụng mới không giao tiếp với các phiên bản cũ hơn của các khung công tác .
Tuy nhiên:
namespace ConsoleApplication1 {
public class DateSerTest {
[XmlElement(DataType = "date")]
public DateTime Date { get; set; }
}
class Program {
static void Main(string[] args) {
DateSerTest d = new DateSerTest {
Date = DateTime.SpecifyKind(new DateTime(2009,8,18), DateTimeKind.Utc),
};
XmlSerializer ser = new XmlSerializer(typeof(DateSerTest));
using (FileStream fs = new FileStream("out.xml", FileMode.Create)) {
ser.Serialize(fs, d);
}
// out.xml will contain:
// <Date>2009-08-18</Date>
using (FileStream fs = new FileStream("out.xml", FileMode.Open)) {
DateSerTest d1 = (DateSerTest) ser.Deserialize(fs);
Console.WriteLine(d1.Date); // yields: 8/18/2009 12:00:00 AM
Console.WriteLine(d1.Date.Kind); // yields: Unspecified
}
// in.xml:
// <DateSerTest>
// <Date>2009-08-18Z</Date>
// </DateSerTest>
using (FileStream fs = new FileStream("in.xml", FileMode.Open)) {
DateSerTest d1 = (DateSerTest) ser.Deserialize(fs);
Console.WriteLine(d1.Date); // yields: 8/17/2009 8:00:00 PM
Console.WriteLine(d1.Date.Kind); // yields: Local
using (FileStream fs1 = new FileStream("out2.xml", FileMode.Create)) {
ser.Serialize(fs1, d1);
// out2.xml will contain:
// <Date>2009-08-17</Date>
}
}
Console.ReadKey();
}
}
}
Vì vậy, cho các yếu tố XSD định nghĩa là "ngày" chứ không phải "datetime", ngày được không đăng như UTC. Đây là một vấn đề, bởi vì nếu tôi deserialize XML này ngày kết quả sẽ là Kind Unspecified, và bất kỳ chuyển đổi UTC (mà trong thực tế sẽ là một no-op vì UTC-ness của ngày nên được bảo quản trong suốt chuyến đi), sẽ thay đổi ít nhất là thời gian trong ngày, với 50% cơ hội thực hiện ngày hôm qua, tùy thuộc vào việc bạn đang ở phía đông hay phía tây của Greenwich.
nên không ngày được viết như sau:
<Date>2009-08-18Z</Date>
? Thật vậy, nếu tôi deserialize một tài liệu có chứa ở trên, tôi nhận được một DateTime đã được chuyển đổi sang thời gian địa phương (Tôi đang ở New York vì vậy đó là ngày 17 tháng 8 20:00), và nếu tôi ngay lập tức serialize đối tượng đó trở về XML, tôi nhận được:
<Date>2009-08-17</Date>
Vì vậy, UTC đã được chuyển đổi sang địa phương trên đường vào, và một phần thời gian đó địa phương đã giảm trên đường ra, mà sẽ làm cho nó Unspecified trên đường trở lại một lần nữa . Chúng tôi đã mất tất cả kiến thức về đặc điểm kỹ thuật ngày UTC ban đầu của ngày 18 tháng 8.
Đây là những gì W3C nói về xsd: date:
[Định nghĩa:] Cú pháp · không gian giá trị · của ngày bao gồm khoảng thời gian đầu mở của đúng một ngày dài trên mốc thời gian của dateTime, bắt đầu từ thời điểm bắt đầu mỗi ngày (trong mỗi múi giờ), tức là '00: 00: 00 ', tối đa nhưng không bao gồm '24: 00: 00' (là giống hệt với '00: 00 : 00 'của ngày tiếp theo ngày). Đối với các giá trị không được định thời gian, các khoảng thời gian mở hàng đầu là tách rời dòng thời gian không được định trước, mỗi lần ngày. Đối với các giá trị thời gian, các khoảng thời gian bắt đầu vào mỗi phút và do đó trùng lặp.
Các vấn đề cơ bản là nếu tôi làm như sau:
- Thi công (hoặc nhận) một giá trị tính theo giờ UTC DateTime.
- Nối tiếp với XML bằng lược đồ xác định trường đó là xsd: date
- Deserialize XML đó trở lại DateTime.
- Chuyển đổi DateTime thành UTC (sẽ không có hiệu lực vì "roundtrip" nên đã được giữ nguyên này).
Hoặc như sau:
- Deserialize một tài liệu XML chứa một UTC xsd: (. Ví dụ 2009-08-18Z) ngày đối tượng.
- Sắp xếp lại nó trở lại tài liệu XML mới mà không cần chạm vào nó.
Một trong các thủ tục này nên làm cho tôi cùng ngày tôi đưa vào.
Cách giải quyết
Cách duy nhất tôi có thể thấy cho đến nay để có được những khứ hồi hành vi của tôi mong đợi là để triển khai thuộc tính Date như sau, với giả định rằng tất cả các phần tử xsd: date đại diện cho UTC:
[XmlElement(DataType = "date")]
public DateTime Date {
get { return _dt; }
set { _dt = value.Kind == DateTimeKind.Unspecified ?
DateTime.SpecifyKind(value, DateTimeKind.Utc) :
value.ToUniversalTime(); }
}
Điều nhỏ: Trình nối tiếp XML không sử dụng '[Serializable]'. –
Ok, với sửa đổi của bạn, tôi không còn thấy câu hỏi. Câu hỏi là gì? – Cheeso
Tôi vẫn đang cố gắng thu hút đầu óc, nhưng tôi đoán câu hỏi của tôi vào thời điểm này là: Tôi có quyền kết luận rằng chuỗi tuần tự hóa XML giữa DateTime và xsd: date bị hỏng không? – lesscode