C# Xamarin.Android JSON.Net序列化在4.2.2仅设备TimeZoneNotFound异常上失败

C# Xamarin.Android JSON.Net序列化在4.2.2仅设备TimeZoneNotFound异常上失败,c#,datetime,xamarin,xamarin.android,json.net,C#,Datetime,Xamarin,Xamarin.android,Json.net,我使用JSON.Net序列化DTO,在物理设备上出现以下异常。这适用于我们测试过的所有其他设备,但在运行版本4.2.2的三星Galaxy Tab 3lite SM-T110上出现故障 我曾经有过这样的经历,但当我升级到Xamarin 3.0时,它变成了这样: 06-03 21:17:41.687 E/mono-rt (22071): [ERROR] FATAL UNHANDLED EXCEPTION: System.TimeZoneNotFoundException: Exception of

我使用JSON.Net序列化DTO,在物理设备上出现以下异常。这适用于我们测试过的所有其他设备,但在运行版本4.2.2的三星Galaxy Tab 3lite SM-T110上出现故障

我曾经有过这样的经历,但当我升级到Xamarin 3.0时,它变成了这样:

06-03 21:17:41.687 E/mono-rt (22071): [ERROR] FATAL UNHANDLED EXCEPTION: System.TimeZoneNotFoundException: Exception of type 'System.TimeZoneNotFoundException' was thrown.
06-03 21:17:41.687 E/mono-rt (22071):   at System.TimeZoneInfo.get_Local () [0x00000] in <filename unknown>:0 
06-03 21:17:41.687 E/mono-rt (22071):   at Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset (DateTime d) [0x00000] in <filename unknown>:0 
06-03 21:17:41.687 E/mono-rt (22071):   at Newtonsoft.Json.Utilities.DateTimeUtils.WriteDateTimeString (System.Char[] chars, Int32 start, DateTime value, Nullable`1 offset, DateTimeKind kind, DateFormatHandling format) [0x00000] in <filename unknown>:0 
06-03 21:17:41.687 E/mono-rt (22071):   at Newtonsoft.Json.JsonTextWriter.WriteValue (DateTime value) [0x00000] in <filename unknown>:0 
06-03 21:17:41.687 E/mono-rt (22071):   at Newtonsoft.Json.JsonWriter.WriteValue (Newtonsoft.Json.JsonWriter writer, PrimitiveTypeCode typeCode, System.Object value) [0x00000] in <filename unknown>:0 
06-03 21:17:41.687 E/mono-rt (22071):   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializePrimitive (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonPrimitiveContract contract, Newtonsoft.Json.Serialization.
06-03 21:17:41.695 I/mono-stdout(22071): Executing Command: UpdateRegistration
The program 'Mono' has exited with code 0 (0x0).
然后,我将使用以下行对其进行序列化:

JsonConvert.SerializeObject(executedCommand);

检查设备的时间设置。这通常发生在设备时间设置错误的情况下。即使时间是正确的,也要检查时区是否正确(例如,对我来说是格林威治时间-3=格林威治时间-3小时)

一个好的测试就是自己设置。有时航空公司没有给你正确的时区


此设置位于System>Date&Time设置中。

是,
TimeZoneInfo.Local
在Mono上有点损坏。我在这里看到了三种不同的故障模式:

  • 返回一个动作正确但ID为“Local”的时区
  • 返回空引用
  • 抛出异常
我没有一个很好的解决方案,但是如果你想记录一个时间戳,最好还是使用
DateTime.UtcNow
。那么你根本不需要担心时区。在大多数情况下,您应该仅以瞬间的形式存储和处理日期/时间值,而不考虑时区,甚至不考虑涉及哪个日历

如果您可以从
Java.Util.TimeZone.Default
中获取时区ID,您可能希望
America/New_York
,那么另一种选择是使用我的项目,其中包括IANA数据库。因此,您可以创建一个
ZoneDateTime
,它准确地表示您需要的内容。我们也支持Json.NET序列化,所以这一部分不应该是个问题

不过,我还是鼓励您只使用UTC,除非您确实需要当地时间

多个选项-您可能需要考虑使用<代码> DATEMEMPLOOS而不是<代码> DATEIMET</代码>;如果您只是尝试将该值序列化为“具有UTC偏移量的日期和时间”,则

DateTimeOffset。现在
可能正是您想要的


(如果这些都没有帮助,请提供更多关于您需要什么以及您希望JSON看起来像什么的上下文。)

最终,问题归结为在非Windows设备上内部使用
TimeZoneInfo.Local
,但您可以避免这种情况

如果您仔细阅读的源代码,您会发现需要做两件事:

  • 切换到
    DateFormatHandling.IsoDateFormat
    。这应该是默认的,并且是推荐的最佳实践

  • 切换到
    DateTime.UtcNow
    。无论如何,将本地时间发送到服务器通常是没有意义的。如果出于某种原因,请尝试序列化
    DateTimeOffset
    ,然后使用
    DateTimeOffset.Now


  • 您是否可以调试代码,或者在其中放入日志条目,并找出代码认为无效的时区可能传递的是什么?Java.Util.TimeZone.Default是否为您提供了设备上的任何值?@RobertHarvey我添加了一些附加值code@SKall我正在从Java.Util.timezone.Default返回时区。东部标准时间美国/纽约Xamarin.Android有很多时区问题。这听起来与有关,我建议您使用Xamarin支持来记录。使用DateTime.UtcNow而不是DateTime。现在为我确定了这个。
    JsonConvert.SerializeObject(executedCommand);