如何处理在.NET / java中以不同方式实现的“本地UTC转换时间”

How to handle that “Local Time to UTC Conversion” differently implemented in .NET / java

NET Web服务我有一个.NET Web服务返回的JSON格式的日期时间。JSON表示的日期是由一指定例如:微软(1302847200000 + /日期/ 0200)这是根据MSDN独立serialization JSON的millisecond自1970年1月第一偏移UTC(在+ / -登录时间和登录后,在本地区的偏移时间GMT。那么这serialization的DateTime值必须转换从Web服务的本地时间和UTC。

Android客户端(Java)Android应用程序的Web服务,它接收的结果,使用一gson解析JSON。因为JSON的。serialization DateTime不是一个标准(根据微软没有搜索标准的DateTime)解析搜索gson是不能够被格式化后的日期。这是我写的一个serialization约会typeadapter和反序列化在客户端侧。

似乎工作的很精细。日期时间和UTC和交换服务。这将是好,如果它的DateTime。NET和Java的日历会以完全相同的规则,当谈到时间转换到本地时间。

例:瑞士安切洛蒂DST(夏令时间)自1979年。知道Java的DST没有存在过。因为有它的存在。assumes。那么当一个约会是在1979年的夏天从UTC转换到Java和。NET和回本地时间(Presentation),那么这个约会很多小时在相同的时间。

问题如何面对这一问题?有没有在做任何的错误我在描述的数据交换。我思考许多不同的解决方案。唯一的方式我可以想象在这工作是替换。serialization/反序列化JSON的DateTime。这当然不是一个欠发达……

谢谢你的时间。


不要使用标准.NETJSON序列化程序,如果您在Java和.NET之间工作,将导致您比您需要的头痛太多。正如你所发现的,微软使用的是大多数人不使用的格式。

最好的序列化程序是NewtonSoft的json.net(nuget page),它已成为.NET开发人员的事实标准。它们有很好的日期时间序列化/反序列化选项,使用起来很简单。有关更多信息,请查看他们在日期时间上的博客文章。我倾向于使用ISO 8601,这是json.net v4.5中的默认格式。

我曾经在一个企业应用程序上工作,该应用程序通过JSON与许多不同的产品进行通信,这些产品是用一系列语言创建的,而JSON.NET使产品间通信变得微不足道。

瑞士日期时间处理的更新

因为您指定的是通用的中欧标准时间,.net不知道瑞士的日期时间规则是什么。为了与瑞士打交道,你需要给.NET提供瑞士规则。看看维基百科,它开始于1981年,因此创建一个自定义的TimeZoneInfo应该是如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// UTC Time
var date1 = new DateTime(1969, 4, 20, 2, 20,00, DateTimeKind.Utc);
Console.WriteLine("Date 1:" + date1.ToString() +" -" + date1.IsDaylightSavingTime());

// CEST
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var date2 = TimeZoneInfo.ConvertTimeFromUtc(date1, timezone);
Console.WriteLine("Date 2:" + date2.ToString() +" -" + date2.IsDaylightSavingTime() +"" + timezone.IsAmbiguousTime(date2));

// Switzerland
var cesAdjRule = timezone.GetAdjustmentRules().Single();
var switzerlandStartTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
        cesAdjRule.DaylightTransitionStart.TimeOfDay,
        cesAdjRule.DaylightTransitionStart.Month, cesAdjRule.DaylightTransitionStart.Week,
        cesAdjRule.DaylightTransitionStart.DayOfWeek
);
var switzerlandAdjustmentRule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
    new DateTime(1981, 1, 1),
    DateTime.MaxValue.Date,
    cesAdjRule.DaylightDelta,
    switzerlandStartTransition,
    cesAdjRule.DaylightTransitionEnd
);
TimeZoneInfo.AdjustmentRule[] adjustments = {switzerlandAdjustmentRule};

var switzerlandTimeZone = TimeZoneInfo.CreateCustomTimeZone("Switzerland",
                                                            timezone.BaseUtcOffset,
                                                           "Switzerland",
                                                           "Switzerland",
                                                           "Switzerland",
                                                            adjustments, false);

var date3 = TimeZoneInfo.ConvertTimeFromUtc(date, timezone, switzerlandTimeZone);
Console.WriteLine("Date 3:" + date3.ToString() +" -" + date3.IsDaylightSavingTime() +"" + timezone.IsAmbiguousTime(date3));

输出结果如下(至少在我的机器上):

1
2
3
Date 1: 4/20/1969 2:20:00 AM - False
Date 2: 4/20/1969 4:20:00 AM - True - False
Date 3: 4/20/1969 3:20:00 AM - True - False

如你所见,DateTime上的isDayLightSavingsTime是正确的,但TimeZoneInfo正确地转换了我们的时间。尝试其他几种组合也很不错。你也可以在它认为你拥有的塞斯特和瑞士之间转换。