I've read all of the articles for UTC dates for the newer versions but they aren't working.
MVC v4.17.2.183
Here's what I got:
@(Html.Infragistics().Grid<TaskModel>() .PrimaryKey("TaskApprovalId") .ID("GlobalTasksGrid") .AutoGenerateColumns(false) .AutoGenerateLayouts(false) .EnableUTCDates(true) .Columns(column => { column.For(m => m.TaskApprovalId).DataType("number").HeaderText(" ").Hidden(true); column.For(m => m.Location).DataType("string").Width("215").HeaderText("Location"); column.For(m => m.Task).DataType("string").Width("195").HeaderText("Task").Template("[Task Name]"); column.For(m => m.Employee).DataType("string").Width("155").HeaderText("Employee").Template("[Employee Name]"); column.For(m => m.ApprovalDate).DataType("date").Format("dateTime").Width("180").HeaderText("Date") .Template("<div align='center'>${ApprovalDate}</div>").DateDisplayType(DateDisplayType.Local); }) .Features(feature => { feature.Updating() .EnableAddRow(false) .EnableDeleteRow(true) .EditMode(GridEditMode.None); }) .AutoCommit(true) .DataSourceUrl(Url.Action("GetGlobalTasks")) .DataBind() .Render() )
EnableUTCDates set to true. This notifies the datasource that the incoming date are in UTC format. So it should convert it into a Date object.
LocalSchemaTransform is set to true by default, which is what we want.
The ApprovalDate column is set to DateTime and the DateDisplayType is set to "local".
Unfortunately, the desired result is still the same. The UTC date stored in the database is still rendered as such to the client.
Here's the data coming from the server:
The only thing that stands out is the Metadata.timezoneOffset which I don't set myself.
Thoughts?
So I've read a few other articles:
https://es.infragistics.com/community/forums/f/ignite-ui-for-javascript/111827/convert-utc-time-to-browser-timezone-in-iggrid
This particular one pointed to DateTime.Kind being set to Unspecified with Entity Framework. So far that assumption is true. I checked the code and sure enough it was set to that. So I changed it programmatically before serialization to Utc. But now the dates render in the UI another 5 hours past than what it is supposed to be. Date was set at 2019-10-15T22:34:02.513Z but I actually did it at 17:34:02 local time.
Seems to be going 5 hours in the wrong direction. Now I'm completely stumped. In addition, I would expect that if I change the DateDisplayType from UTC to Local I would see the dates change but I don't.
Funny thing...setting up a formatter function and then manually setting the date works. This answer isn't correct because the documentation states it can do what I want out of the box. But here's what I applied:
function formatApprovalDate(val, record) { return $.ig.formatter(new Date(val), "date", "dateTime", null, false, null); }
@(Html.Infragistics().Grid<TaskModel>() .PrimaryKey("TaskApprovalId") .ID("GlobalTasksGrid") .AutoGenerateColumns(false) .AutoGenerateLayouts(false) .EnableUTCDates(true) .Columns(column => { column.For(m => m.TaskApprovalId).DataType("number").HeaderText(" "); column.For(m => m.Location).DataType("string").Width("215").HeaderText("Location"); column.For(m => m.Task).DataType("string").Width("195").HeaderText("Task"); column.For(m => m.Employee).DataType("string").Width("155").HeaderText("Employee"); column.For(m => m.ApprovalDate).DataType("string").Width("90").HeaderText("Date").FormatterFunction("formatApprovalDate") .Template("<div align='center'>${ApprovalDate}</div>"); }) .Features(feature => { feature.Updating() .EnableAddRow(false) .EnableDeleteRow(true) .EditMode(GridEditMode.None); feature.Hiding() .ColumnSettings(settings => { settings.ColumnSetting().ColumnKey("TaskApprovalId").Hidden(true).AllowHiding(false); settings.ColumnSetting().ColumnKey("Location").AllowHiding(false); settings.ColumnSetting().ColumnKey("Task").AllowHiding(false); settings.ColumnSetting().ColumnKey("Employee").AllowHiding(false); settings.ColumnSetting().ColumnKey("ApprovalDate").AllowHiding(false); }); }) .AutoCommit(true) .DataSourceUrl(Url.Action("GetGlobalTasks")) .DataBind() .Render() )
You are on the right track but its more like this:- The action happened at 17:34:02.- It was stored in the database as UTC as 22:34:02.- It shows in the UI as 22:34:02 instead of 17:34:02.
When should I convert it to "ToUniversalTime"? When we tag the task as complete we mark the date as DateTime.UtcNow.
So should I call "ToUniversalTime" before I push it to the database? Or when I pull the date out before pushing it to the UI?
Hello Karthik,
When you are saying that the action happened at 17:34:02, is this on a server that is in a UTC-5 time zone?
Best regards,
Stamen Stoychev
Yes, the server is on CST Central Time Zone.
In this case, the time stored in the data base is correct. If you obtain it with EF the DateTime objects should have DateTimeKind.Utc (if I remember correctly, EF sets the correct DateTimeKind if it is Utc). If this is not the case, you should set the Kind to Utc manually.
If you then set your date column to use DateDisplayType.Local, opening the application on clients that are in the same time zone should correctly display 17:34:02. Opening it on clients in other time zones will display the local representation of that point in time, which is expected with DateDisplayType.Local.
Please, ensure the DateTimes are of Kind.Utc and the column has DateDisplayType.Local and let me know what gets displayed for values in that column then.
It just doesn't work. The problem is the JSON that gets returned back. Why is the timezoneOffsets set to 0??? That is the base problem. Everything else I have set correctly. I even recreated the date ticks into a new date and set the Kind to Utc. Right now everything is being displayed exactly how the DB is rendering it, which is in UTC.
{ "Records": [{ "TaskApprovalId": 3320, "Location": "(Global)", "LocationId": 0, "Task": "Approval Hierarchy Set", "TaskId": 4, "Employee": "PERSON", "ApprovalDate": "2019-09-19T18:38:09.093Z" }, { "TaskApprovalId": 3321, "Location": "(Global)", "LocationId": 0, "Task": "Profit Sharing Data Uploaded", "TaskId": 1, "Employee": "PERSON", "ApprovalDate": "2019-09-20T00:34:52.553Z" }, { "TaskApprovalId": 3436, "Location": "(Global)", "LocationId": 0, "Task": "First Pass Data Uploaded", "TaskId": 2, "Employee": "PERSON", "ApprovalDate": "2019-10-23T15:41:16.16Z" }, { "TaskApprovalId": 3437, "Location": "(Global)", "LocationId": 0, "Task": "Deferral Data Uploaded", "TaskId": 3, "Employee": "PERSON", "ApprovalDate": "2019-10-23T15:41:34.657Z" }], "TotalRecordsCount": 0, "Metadata": { "timezoneOffset": -21600000.0, "timezoneOffsets": { "3320": { "ApprovalDate": 0 }, "3321": { "ApprovalDate": 0 }, "3436": { "ApprovalDate": 0 }, "3437": { "ApprovalDate": 0 } } } }
Hello,
The timezoneOffsets are used in the scenario where you want to show the local representation of a certain DateTime as it is on the server regardless of the timezone of your clients. Please, check the section concerning igGrid, igTreeGrid and igHierarchical grid in this document for more information.
To trigger this behavior you need your server DateTime objects to be of type Local so that their UTC offset can be extracted. To convert dates which are already in DateTimeKind.Utc to Local you can use their ToLocalTime() method. Additionally, you should not set any DateDisplayType for your columns. Finally your data source end point (the GetGlobalTasks controller in your case) should be decorated with a [GridDataSourceAction] attribute.
However, as I mentioned, this option only matters if you don't want to show the client representation of that date, but whatever the server time was when an action happened.
Now, to answer your question - as your DateTime objects are of Kind.Utc, they represent UTC time and therefore their UTC offset is 0. However, as long as your column's DateDisplayType is set to Local, the client's local representation of that UTC time should be displayed. If it is set to DateDisplayType.Local and the column still shows UTC time, that may be a bug in the product version you are using. However, I did try it out last week and couldn't reproduce it. I'll check it again and let you know if I find anything.
In the meantime, if you have a small sample that reproduces the behavior, even if it doesn't have any DB and only creates dummy DateTime objects, please share it so I can investigate it further.