Xamarin.Android JSON.Net firmware failed on 4.2.2 only for the device TimeZoneNotFound exception

I use JSON.Net to serialize the DTO and I get the following exception on the physical device. This works on all the other devices we tested on, but does not work on the Samsung Galaxy Tab 3lite SM-T110 version 4.2.2.

I had this question , but when I upgraded to Xamarin 3.0, it became as follows:

 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). 

EDIT This is the DTO I'm trying to serialize. You can see when the called constructor is called, it sets it to DateTime.Now . Should this just suggest a local time zone?

  public class RecordTargetFrequency : BaseCommand, ICommand { public Guid TargetId { get; private set; } public Guid? LocationId { get; private set; } public Guid TherapistId { get; private set; } public bool? Increase { get; private set; } public DateTime TimeStamp { get; private set; } public RecordTargetFrequency(Guid targetId, Guid? locationId, Guid therapistId, bool? increase) { TimeStamp = DateTime.Now; TargetId = targetId; LocationId = locationId; TherapistId = therapistId; Increase = increase; } public void Validate() { ValidateGuid(TargetId); ValidateGuid(TherapistId); } } 

Then I serialize it using this line:

 JsonConvert.SerializeObject(executedCommand); 
+6
source share
3 answers

Yes, TimeZoneInfo.Local somewhat broken on Mono. I saw three different failure modes here:

  • Return timezone that works correctly but has the identifier "Local"
  • Return null reference
  • Throwing an exception

I don't have a good solution for this, but if you are trying to write a timestamp, it would be much better to use DateTime.UtcNow anyway. Then you do not need to worry about time zones. In most cases, you should only store and process date and time values ​​in terms of time, not worrying about the time zone or even which calendar is involved.

If you can get the timezone identifier from Java.Util.TimeZone.Default , because it looks the way you can, you would like America/New_York here - then another alternative is to use Noda Time , which includes the IANA database. This way you can create a ZonedDateTime that represents exactly what you need. We also support Json.NET serialization, so this part should not be a problem.

Again, I would advise you to just use UTC if you really don't need local time.

A couple of additional parameters - you can use DateTimeOffset instead of DateTime ; if you are just trying to serialize the value as "date and time with a UTC offset," then DateTimeOffset.Now can do exactly what you want.

(If this does not help, provide more context regarding what you need and what you expect from JSON.)

+8
source

Check the time settings for the device. This usually happens when the device time is set incorrectly. Even the time is correct, check if the time zone is correct (for example, for me this is GMT -3 = GMT-3 hours)

A good test is to install it yourself. Sometimes the operator does not give you the correct time zone.

This option is in the settings "System"> "Date and time."

+1
source

Ultimately, the problem boils down to the internal use of TimeZoneInfo.Local on non-Windows devices, but you can avoid this.

If you follow the source code DateTimeUtils.WriteDateTimeString , you will find that you need to do two things:

  • Switch to DateFormatHandling.IsoDateFormat . This should be the default anyway and is the recommended best practice.

  • Switch to DateTime.UtcNow . As a rule, it makes no sense to send local time to the server in any case. If for some reason you do, try serializing DateTimeOffset instead and use DateTimeOffset.Now .

+1
source

Source: https://habr.com/ru/post/970277/


All Articles