0

I have a very strange behavior on an application. The server is in New York(-5 GMT timezone) and the client - me, in Romania(+2 GMT timezone) so there is a 7 hour discrepancy. The problem I'm facing is when I try to save a date, let's say 12:00(day doesn't matter), the client is sending a request with the date 12:00, the 12:00 reaches the database but when it returns the severs returns the hour 19:00. I tried to debug on local to see who messes up the date but since I have the same date on server and on client there is no discrepancy.

This is the parameter sent to server &startDate=07/25/2012%2012:00:00

And this is the result: 1343232000000 - the seconds from the epoch(if you use a converter - http://www.epochconverter.com/ - you will see that the date is in fact Wed Jul 25 2012 19:00:00

here are some code snippets :

public static void GetProfessionalsHours(List<long> ids, out List<SalonProfessional> professionals)
    {
        professionals = new List<SalonProfessional>();
        using (SqlConnection conn = new SqlConnection(DbConfig.ConnectionString))
        {
            using (
                SqlCommand command = new SqlCommand("GetProfessionalsHours", conn) { CommandType = CommandType.StoredProcedure })
            {
                conn.Open();
                command.Parameters.AddWithValue("professionalIDs", ids.CommaSeparated());
                using (IDataReader reader = command.ExecuteReader())
                {
                    //get normal schedule
                    while (reader.Read())
                    {
                        professionals.Add(SalonProfessional.GetSalonProfessional(reader));
                    }
                    reader.NextResult();
                    while (reader.Read())
                    {
                        professionals.Find(p => p.ID == reader.GetInt64(1)).Hours.Add(ProfessionalHours.GetProfessionalHour(reader));
                    }
                    //get overriden hours
                    reader.NextResult();
                    while (reader.Read())
                    {
                        professionals.Find(p => p.ID == reader.GetInt64(1)).OverriddenHours.Add(ProfessionalOverriddenHour.GetProfessionalOverriddenHour(reader));
                    }
                }
            }
        }
    }

public static ProfessionalOverriddenHour GetProfessionalOverriddenHour(IDataReader reader)
    {
        return new ProfessionalOverriddenHour()
                   {
                       ID = reader.GetInt64(0),
                       ProfessionalId = reader.GetInt64(1),
                       StartDate = reader.GetDateTime(2),
                       EndDate = reader.GetDateTime(3),
                   };
    }


public JsonResult CalendarData(List<long> professionalIDs, CalendarData calendarData)
    {
        AjaxResponse response = new AjaxResponse();
        response.Success = true;
        CalendarDataResponseObject responseData = new CalendarDataResponseObject();
        response.Content = responseData;

        try
        {
          List<SalonProfessional> professionals = null;
          CalendarOperations.GetProfessionalsHours(professionalIDs, out professionals);
          responseData.Professionals = professionals;

        }
        catch (Exception ex)
        {
            response.Success = true;
            response.ErrorMessage = "Could not retrieve calendar data";
            ExceptionsOperations.LogException(ex, "Could not retrieve calendar data");
        }

        return Json(response, JsonRequestBehavior.AllowGet);
    }

The problem is on StartDate and EndDate from the ProfessionalOverriddenHour object.

Daniel Tranca
  • 1,374
  • 3
  • 13
  • 23
  • The server is going to assume local time unless you tell is otherwise. There are date strings with time offset or time zone. – paparazzo Jul 24 '12 at 15:28
  • If you work according to UTC time then it may solve the problem – Adil Jul 24 '12 at 15:29

4 Answers4

1

Try storing and retrieving date string after converting with reference to UTC first.

Here is a excerpt from Scott Hanselman blog post

Phrased differently, don't use DateTime.Now for ANY date calculations or to store anything. Use DateTime.UTCNow and be aware that some methods will freak out if you send them future dates, as they should. Avoid doing ANYTHING in local time until that last second when you show the DateTime to the user.

Also check out Daylight saving time and time zone best practices

Community
  • 1
  • 1
Adil
  • 3,248
  • 1
  • 22
  • 27
1

You could send the offset (z) or agree on UTC

    Console.WriteLine(DateTime.Now.ToString("hh mm ss z"));
    Console.WriteLine(DateTime.Now.ToUniversalTime().ToString());
paparazzo
  • 44,497
  • 23
  • 105
  • 176
0

Like already suggested, always use UTC when storing dates (in databases, files, etc.), and let the client itself decide on what timezone should be used when displaying that date (and only then!)

You can of course get it working by just including the timezone data in the date string, but it makes everything more complex (imho), stick to the simple case where dates are always UTC, unless you're displaying it to the users.

Steen Tøttrup
  • 3,755
  • 2
  • 22
  • 36
0

Thanks a lot for help guys!

The problem was that both the server and the client were converting the date to their local time. So the solution was to get the hours difference on server and add them to the date and on javascript to work with utc time. Basically when you don't need time zones, work with UTC everywhere.

Daniel Tranca
  • 1,374
  • 3
  • 13
  • 23