Alan Garduño III
Alan Garduño III

Reputation: 43

SQL Server / EF Core not respect date from the client

I'm a bit newbie with the MS tech stack, I developed a REST API using c# and EF core

I have this body request

{
  "name": "Test Fecha",
  "awardDate": "2020-05-19T00:00:00.000Z",
  "governancePermit": "TEST",
  "totalTickets": 5000,
  "legals": "TEST",
  "logo": "TEST",
  "ticket": "TEST",
  "ticketLifeTime": "200000",
  "ticketPrice": 2000,
  "saleStartDate": "2020-05-19T00:00:00.000Z",
  "saleEndDate": "2020-05-19T00:00:00.000Z"
}

Thats the body of a post request to create a new resourse. That body is procesed by the next code:

Controller:

[HttpPost("/api/contest")]
public async Task<IActionResult> Create([FromBody] ContestCreateRequest request)
{

    var activeContest = await _contestService.GetByStatus("Active");
    if (activeContest == null)
    {
        var contest = new Contest
        {
            Name = request.Name,
            AwardDate = DateTime.Parse(request.AwardDate),
            TotalTickets = request.TotalTickets,
            GovernancePermit = request.GovernancePermit,
            Logo = request.Logo,
            Ticket = request.Ticket,
            Legals = request.Legals,
            Status = "Active",
            TicketLifeTime = request.TicketLifeTime,
            TicketPrice = request.TicketPrice,
            SaleStartDate = DateTime.Parse(request.SaleStartDate),
            SaleEndDate = DateTime.Parse(request.SaleEndDate),
            CreatedAt = DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")),
            UpdatedAt = DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")),
        };

        var result = await _contestService.Create(contest);
        if (result)
        {
            var response = new GeneralResponse
            {
                Message = "Contest Create",
                Data = null,
                Status = 201,
                Success = true
            };

            return Ok(response);
        }
        else
        {
            var response = new GeneralResponse
            {
                Message = "Contest not create",
                Data = null,
                Status = 400,
                Success = false
            };

            return BadRequest(response);

        }
    }
    else
    {
        var response = new GeneralResponse
        {
            Message = "Only one contest can be active",
            Data = null,
            Status = 400,
            Success = false
        };

        return BadRequest(response);
    }

}

As you can see I am only parsing the dates from string to a DateTime Object

Then the the object(entity) is inserted in the data base with the following code:

public async Task<bool> Create(Contest contest)
{
    await _dataContext.Contest.AddAsync(contest);
    var create = await _dataContext.SaveChangesAsync();
    return create > 0;
}

Model:

[Table("Contest")]
public class Contest
{
    [Key]
    public int ContestId { get; set; }
    [Column("id_udlap")]
    public int IdUdlap { get; set; }
    [Column("name")]
    public string Name { get; set; }
    [Column("start_date")]
    public DateTime StartDate { get; set; }
    [Column("end_date")]
    public DateTime EndDate { get; set; }
    [Column("award_date")]
    public DateTime AwardDate { get; set; }
    [Column("avaible_tickets")]
    public int AvaibleTickets { get; set; }
    [Column("total_tickets")]
    public int TotalTickets { get; set; }
    [Column("status")]
    public string Status { get; set; }
    [Column("dynimic_fields")]
    public string DynamycFields { get; set; }
    [Column("custom_message")]
    public string CustomMessage { get; set; }
    [Column("grateful_message")]
    public string GratefulMessage { get; set; }
    [Column("ticket_life_time")]
    public string TicketLifeTime { get; set; }
    [Column("ticket_price")]
    public double TicketPrice { get; set; }
    [Column("governance_permit")]
    public string GovernancePermit { get; set; }
    [Column("legals")]
    public string Legals { get; set; }
    [Column("logo")]
    public string Logo { get; set; }
    [Column("ticket")]
    public string Ticket { get; set; }
    [Column("sale_start_date")]
    public DateTime SaleStartDate { get; set; }
    [Column("sale_end_date")]
    public DateTime SaleEndDate { get; set; }
    [Column("created_at")]
    public DateTime CreatedAt { get; set; }
    [Column("updated_at")]
    public DateTime UpdatedAt { get; set; }

    public List<Ticket> Tickets { get; set; }



    public Contest() {}
}

But when I retrieve the object with this code:

public async Task<Contest> GetByStatus(string status)
{
    var result = await _dataContext.Contest.SingleOrDefaultAsync(c => c.Status == status);
    return result;
}

In this case status is "Active", that returns this.

{
  "status": 200,
  "message": "Active Contest",
  "data": {
    "contestId": 1,
    "name": "Test Fecha",
    "startDate": "0001-01-01T00:00:00",
    "endDate": "0001-01-01T00:00:00",
    "awardDate": "2020-05-18T19:00:00",
    "avaibleTickets": 0,
    "totalTickets": 5000,
    "status": "Active",
    "dynamycFields": null,
    "customMessage": null,
    "gratefulMessage": null,
    "ticketLifeTime": "200000",
    "ticketPrice": 2000,
    "governancePermit": "TEST",
    "legals": "TEST",
    "logo": "TEST",
    "ticket": "TEST",
    "saleStartDate": "2020-05-18T19:00:00",
    "saleEndDate": "2020-05-18T19:00:00",
    "createdAt": "2020-05-19T19:04:10.517",
    "updatedAt": "2020-05-19T19:04:10.518",
    "tickets": null
  },
  "success": true,
  "pages": 0,
  "totalData": 0
}

This three fields (saleEndDate,saleEndDate,awardDate) are not the value that I charge in the request body.

The fast solution is add the hours that are out of phase, but Why this is happen? Is there other way to fix it or avoid it.

I suspect that is a SQL server configuration issue because I did it with two different instances and I obtain two different results, but I am not sure

Thanks a lot.

Upvotes: 1

Views: 313

Answers (1)

Alan Gardu&#241;o III
Alan Gardu&#241;o III

Reputation: 43

With the comments of Caius Jard (thanks a lot) and this question in SO Convert DateTimeOffset to DateTime and add offset to this DateTime And this: Convert datetime without timezone

I was able to achieve the desired behavior

Hera the code that works for me:

 var activeContest = await _contestService.GetByStatus("Active");
            if (activeContest == null)
            {   
                var AwardDateFormated = DateTimeOffset.Parse(request.AwardDate);
                var StartDateFormated = DateTimeOffset.Parse(request.SaleStartDate);
                var EndDateFormated = DateTimeOffset.Parse(request.SaleEndDate);
                var contest = new Contest
                {
                    Name = request.Name,
                    AwardDate = AwardDateFormated.UtcDateTime,
                    TotalTickets = request.TotalTickets,
                    GovernancePermit = request.GovernancePermit,
                    Logo = request.Logo,
                    Ticket = request.Ticket,
                    Legals = request.Legals,
                    Status = "Active",
                    TicketLifeTime = request.TicketLifeTime,
                    TicketPrice = request.TicketPrice,
                    SaleStartDate = StartDateFormated.UtcDateTime,
                    SaleEndDate = EndDateFormated.UtcDateTime,
                    CreatedAt = DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")),
                    UpdatedAt = DateTime.Parse(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")),
                };
                var result = await _contestService.Create(contest);

Now I retrieve exactly the data that I want, I don't really know if this is the best solution but for now works. Hope helps someone else.

Upvotes: 2

Related Questions