Search code examples
c#angulardatetimeasp.net-apicontroller.net-standard-2.1

Updating DateTime property in C# and .NetStandard 2.1 Issues


{
   amount:10000
   date:"2023-07-14T13:46:25.626"
   endDate:Sun Jul 16 2023 00:00:00 GMT+0100 (West Africa Standard Time) {}
   id:"323a3676-765b-cbea-57ee-08db8470b7c2"
   isLastPayment:false
   profileId:"e9c79eaa-ca4e-c843-de40-08db7bd10853"
   startDate:Wed Jul 12 2023 00:00:00 GMT+0100 (West Africa Standard Time) {}
}






{
   id:'323a3676-765b-cbea-57ee-08db8470b7c2',
   date: '2023-07-14T13:46:25.626',
   amount: 10000,
   endDate: Sun Jul 16 2023 00:00:00 GMT+0100 (West Africa Standard Time) {},
   isLastPayment:false,
   profileId:"e9c79eaa-ca4e-c843-de40-08db7bd10853",
   startDate:Wed Jul 12 2023 00:00:00 GMT+0100 (West Africa Standard Time) {}
}

I am using angular on the frontend to send this json to my API for and Update request. I changed the dates properties to 12 and 16 of July 2023

Whent it gets to API Controller, the dates changes and the 11 and 15 of July 2023, it resets a day behind my intended dates

{
id:'323a3676-765b-cbea-57ee-08db8470b7c2',
date: '2023-07-14T13:46:25.626',
amount: 10000,
endDate: Sun Jul 15 2023 ......,
isLastPayment:false,
profileId:"e9c79eaa-ca4e-c843-de40-08db7bd10853",
startDate:Wed Jul 11 2023 ........
}

this is my typsecript model for the frontend

export class Payment {

  id: string;
  date: Date;
  amount: number;
  isLastPayment: boolean;
  profileId: string;

  //Date Range for Payment
  startDate?: Date;
  endDate?: Date

}

and this is my Object model for the backend

public class PaymentObject
{
    public Guid Id { get; set; }
    public DateTime Date { get; set; }
    public decimal Amount { get; set; }
    public bool IsLastPayment { get; set; }
    public Guid ProfileId { get; set; }

    //Date Range for Payment
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

The trick this is only affecting the date property. Please I'll appreciate all the help I can get.


Solution

  • Usually there are two types of dates in applications: timestamps (e.g. created date, or some short deadline like until next hour) and calendar/business dates (e.g. payment due date).

    Timestamp is date in UTC (zero offset, can be converted to local time in browser), calendar date is something like yyyy-mm-dd (it does not depend on client timezone, usually it is assumed to be in your business timezone).

    In your case you intend to use Date as calendar date but by default it will not work as expected due to client and server date handling.

    I'm not using ISO format below for brevity.

    When server serializes date it does not differentiate between timestamps and calendar dates, it will serialize them in the same way, and when client receives these dates (looks like your have new Date(jsonString) somewhere) it will automatically convert it to local browser time which is not correct for calendar dates because date is interpreted as timestamp and 2023-06-21 00:00:00 can result in 2023-06-22 or 2023-06-21 depending on browser timezone offset (offset can be +3 or -3 for example).

    When you send date back to server browser serializes dates without offset information, so you loose information about client timezone offset and as a result server does not know what date was displayed in browser. For example 2023-06-21 00:00:00 in timezone with +3 offset will be serialized as 2023-06-20 21:00:00 and server gets date that is one day behind.

    Long story short, you should use strings like yyyy-mm-dd to pass around calendar dates and avoid using js Date for them.