anthonyreilly / NetCoreForce

Salesforce REST API toolkit for .NET Standard and .NET Core
MIT License
110 stars 63 forks source link

Date objects change value on update #34

Open iamruss opened 3 years ago

iamruss commented 3 years ago

I have a custom object and couple of Date fields one them. Everytime I update object, those get updated as well. I update my custom object by first reading it with GetObjectById<>, then set values only for the fields I need to update and not touching the date (exactly SF Date filed, not DateTime) fielfds.

The date filed has time set to zeros, but the the serializer adds my localtime offset, as you can see below:

{
  "startDate__c": "2021-03-06T00:00:00+04:00",
  "expirationDate__c": "2021-05-15T00:00:00+04:00",
...[snipped]...
}

Is there a way to configure the client to utilize DateTimeZoneHandling option [DateTimeZoneHandling.Utc]? Salesforece stores datetimes in UTC, therefore, when my "updated" object is stored, SF converts 2021-03-06T00:00:00+04:00 to 2021-03-05T00:00:00+00:00

iamruss commented 3 years ago

Actually, nevermind. Serializer is using DateTimeZoneHandling.RoundtripKind Looks like the client's GetObjectById returns object adjusted to local time. any idea how to better handle this?

iamruss commented 3 years ago

ok, solved it by adding custom date converter to all the fields with Updateable(true) attribute with SF Type set to date.

 public class SfDateConverter : JsonConverter
 {
        public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
        {
            writer.WriteValue(((DateTime)value).ToString("yyyy-MM-ddT00:00:00+00:00"));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
        {
            if(reader.Value==null)return null;
            return DateTime.ParseExact(reader.Value.ToString(), "yyyy-MM-dd", CultureInfo.InvariantCulture);
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(DateTime);
        }
    }

I wonder if the model generator could be extended to apply this JsonConverter on all date fields?

anthonyreilly commented 3 years ago

Definitely sounds like it would be useful to handle the SF Date types more cleanly, and to avoid any accidental date shifts due to TZ.

iamruss commented 3 years ago

I could make required changes to the model generator next weekend and submit a PR.

anthonyreilly commented 3 years ago

Ill go ahead and take it for now, im going to look at a couple ways to integrate it into the client, I had been considering adding a couple new attributes to tag the models with SF types anyways.