My scheduler is having a problem when a user creates a recurring event that crosses a time change (day light savings). If i create a recurring event for Oct 29 at 12PM and have it recur for 10 days it is correctly displayed at 12PM until Nov 3rd (after the time change) it starts showing at 11AM.
The database record looks like
The timezone is set to:.Timezone( "America/New_York")
The other thing I notice is when i go in to edit an event in the Scheduler it shows in UTC time in the editor instead of in America/New_York. Most of my events are not edited through the Scheduler UI, so this has not become a problem.
10 Answers, 1 is accepted
Hello Logan,
Could you please post you Scheduler declaration? This will give us an idea of how it is configured and we will further investigate the reported behavior.
Regards,
Ivan Danchev
Progress Telerik
I have removed some of the logic.
@(Html.Kendo().Scheduler<
ISchedulerEvent
>()
.Name("scheduler")
.Date(startDate)
.Height(600)
.Views(views =>
{
views.DayView(w => w.Selected(false));
views.WeekView(w => w.Selected(true));
views.MonthView(w => w.Selected(false));
})
.Editable(e =>
{
e.Create(true);
e.Update(true);
e.Destroy(true);
})
.Timezone("America/New_York")
.AllDaySlot(false)
.CurrentTimeMarker(true)
.EventTemplateId("display-template")
.Events(events =>
{
events.Add("scheduler_add");
events.Resize("scheduler_resize");
events.ResizeEnd("scheduler_resizeEnd");
events.Move("scheduler_move");
events.MoveEnd("scheduler_moveEnd");
events.Remove("scheduler_remove");
events.Edit("scheduler_edit");
events.DataBound("scheduleBound");
events.Change("scheduler_removenever");
}
)
.Resources(resource =>
{
resource.Add(m => m.CalendarItemAttendees)
.Title("Technologist")
.DataTextField("Text")
.DataValueField("Value")
.DataColorField("Color")
.BindTo(Model.AllAttendees).Multiple(Model.RequiredSkills.Count > 1);
resource.Add(m => m.HardwareId)
.Title("Equipment")
.DataTextField("Text")
.DataValueField("Value")
.DataColorField("Color")
.BindTo(Model.AllAttendees).Multiple(Model.RequiredSkills.Count > 1);
resource.Add(m => m.MeetingTypeId)
.Title("Meeting Type")
.DataTextField("Text")
.DataValueField("Value")
.DataColorField("Color")
.BindTo(Model.AllMeetingTypes).Multiple(false);
})
.DataSource(d => d
.ServerOperation(true) //this forces a re-read on change
.Model(m =>
{
m.Id(f => f.Id);
m.Field(f => f.Title).DefaultValue(Model.CalendarTitle);
m.RecurrenceId(f => f.RecurrenceId);
})
.Events(e => e.Error("error_handler").RequestEnd("rebindSchedule")) //show user any errors
.Read(r => r.Action("Schedule_Read", "Calendar").Data("calendarRead"))
.Create("Schedule_Create", "Calendar")
.Destroy("Schedule_Destroy", "Calendar")
.Update("Schedule_Update", "Calendar")
)
)
Logan,
I tried reproducing the reported behavior, but to no avail. The November 3rd event is shown properly: see the attached screenshot.
A sample runnable project is attached to this reply. Could you run it and let me know whether there is any difference in how the recurring event is displayed at your end?
Regards,
Ivan Danchev
Progress Telerik
I stripped everything out i could and I am still having the problem when i match my original setup, which was to set the timezone in the database to Etc/UTC and the timezone in the view to America/New_York. My goal is to store it in the database as UTC, but for it to always be displayed in America/New_York time in the browser (even if their computer is set to something different).
When I change the .TimeZone setting in the view to "Etc/UTC" it appears to be stay the same across daylight savings, but the time is incorrect. It comes across as 12PM UTC but shows at 4PM. This confuses me because my local timezone is America/New_York so i would think if it was being converted from UTC to EST it would be 8/7AM depending on daylight savings.
You can see the output and data at https://imgur.com/a/g3Gc4MY
My test code is
View
@{
ViewBag.Title = "Index";
}
<
h2
>Index</
h2
>
@(
Html.Kendo().Scheduler<
Radiology.Web.Controllers.SchedulerEvent
>()
.Name("scheduler-test")
.Date(DateTime.Today)
.Height(300)
.Views(v =>
{
v.DayView();
v.WorkWeekView();
v.WeekView(wv => wv.Selected(true));
v.MonthView();
})
.Timezone("America/New_York")
.DataSource(d => d
.ServerOperation(true) //this forces a re-read on change
.Model(m =>
{
m.Id(f => f.Id);
m.Field(f => f.Title).DefaultValue("no title");
m.RecurrenceId(f => f.RecurrenceId);
})
.Events(e => e.Error("error_handler")) //show user any errors
.Read(r => r.Action("Schedule_Read", "TestCalendar"))
.Create("Schedule_Create", "TestCalendar")
.Destroy("Schedule_Destroy", "TestCalendar")
.Update("Schedule_Update", "TestCalendar")
)
)
Classes
public class SchedulerEvent : ISchedulerEvent
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string StartTimezone { get; set; }
public string EndTimezone { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public int? RecurrenceId { get; set; }
}
public class TestCalendarController : BaseController
{
// GET: TestCalendar
public ActionResult Index()
{
return View();
}
public virtual async Task<
JsonResult
> Schedule_Read([DataSourceRequest] DataSourceRequest request)
{
var result = new DataSourceResult();
var list = Db.CalendarItems
.Where(w => w.HardwareId == 21 && w.Id == 2337 && w.DeletedOn == null)
.Select(s => new SchedulerEvent()
{
Id = s.Id,
Title = s.Title,
Description = s.Description,
Start = s.Start,
StartTimezone = s.StartTimezone,
End = s.End,
EndTimezone = s.EndTimezone,
IsAllDay = false,
RecurrenceException = s.RecurrenceException,
RecurrenceRule = s.RecurrenceRule,
RecurrenceId = s.RecurrenceId
}).ToList();
result = list.ToDataSourceResult(request, ModelState);
var jsonResult = Json(result);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
}
}
Thanks!
Logan
Hello Logan,
The Start and End dates in the response in the screenshot miss the "Z" literal, which is part of the standard for UTC times. For example:
"Start":"2013-06-09T21:00:00Z"
Try out out the approach we demonstrate in the service used in out demos in your Schedule_Read action:
Start = DateTime.SpecifyKind(s.Start, DateTimeKind.Utc), End = DateTime.SpecifyKind(s.End, DateTimeKind.Utc),
See the Timezones article for more information on the Date format the Scheduler expects.
Regards,
Ivan Danchev
Progress Telerik
Thanks for responding.
I have added the following code directly after the database call in my sample above.
list.ForEach(e =>
{
e.Start = DateTime.SpecifyKind(e.Start, DateTimeKind.Utc);
e.End = DateTime.SpecifyKind(e.End, DateTimeKind.Utc);
});
This did add a "Z" to the end of the Start and End values when it is set to the browser, but i still have the same problem. You can see this in the screenshots linked below
Thanks for helping with this
Logan,
I tested some more and made a change to the way dates are returned in the Read action in the project I attached earlier. Previously the date were being returned in this format: "Start":"\/Date(1572364800000)\/".
I modified the Read action:
public JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
var events = from a in appointments
select new
{
TaskID = a.TaskID,
Description = a.Description,
Title = a.Title,
Start = a.Start.ToString("o"),
End = a.End.ToString("o"),
RecurrenceRule = a.RecurrenceRule
};
return Json(events.ToDataSourceResult(request));
}
so now the dates are returned in this format: "Start":"2019-10-29T12:00:00.0000000Z"
The event starting at 12PM UTC is shown starting at 8AM with the "America/New_York" timezone set.
I am attaching the example again. Could you check how it behaves at your end? Are you able to reproduce the issue?
Regards,
Ivan Danchev
Progress Telerik
Ivan,
tl;dr: Removing the TimeZone fields from the read along with the trailing Z appears to have fixed it. Is that right?
Your sample did work on my machine, but it would be real work for me to match it in my production code because my model comes from a service and implements ISchedulerEvent which defines Start and End as DateTime. I also saw that my code was not returning a json datetime.
I noticed you were not setting the Start/EndTimeZone property on the read. I has always set that value to Etc/UTC to specify the timezone. When I removed this value from the read it appears to work in my sample.
Removing that value only appears to work when the Start/End times have the trailing Z to indicate time (otherwise they display on the calendar in UTC).
I am going to move on to test this in the full system, but I wanted to make sure that this is a reasonable outcome and that it is OK to leave the StartTimeZone and EndTimeZone null in the scheduler read?
Thanks again!
Logan,
I am glad it worked out. Actually, I was not able to reproduce the problematic behavior even with Start/EndTimeZone set to "Etc/UTC". But these two fields are not obligatory. Passing dates with the Z literal specify them as UTC dates and then the Scheduler's Тimezone option is applied.
Regards,
Ivan Danchev
Progress Telerik