Display Templates and wrong date formatting

Display Templates and wrong date formatting

Whenever you are building an intranet solution there is usually a part where you are providing some sort of news solution. Most news solutions will provide some sort of roll-up with the latest news, and they out of the box search capabilities will help you achieving that goal. And whether you are rolling-up news or some other type of pages the odds are you are required to display the article date. Now you can create a new Managed Property in case the out of the box properties prove not to be sufficient but whatever property you are using you might encounter some formatting issues. Back in SharePoint 2007 there was a similar issue as pointed out in a blog about the curious incident of the date column in the night-time. The resolution however will not apply to a SharePoint 2013 environment (running on Windows Server 2012 R2), while the cause looks slightly familiar. 

If you are running a box that has Daylight Saving time enabled you can save a date like 03/10/2012 on your page. When you then view the page it all looks correct, while it will be shown as Tuesday, March 09, 2014 in a search result. Now diving into it you will find that the value that is stored in the database actually will be 03/11/2012 23:00. While if you request the information in a SharePoint Control like the Microsoft.SharePoint.WebControls.DateTimeField it will be displayed correctly to the users regardless of their locale. The trick is that the control will resolve the given value based on the format. You can see that if you would do search request with a REST call and check the result:

REST Search Result

Within the default display templates that are provided you can see how the results are formatted. If you use these out of the box display templates all of the values will be formatted using the following snippet from the display templates:

var line2 = $getItemValue(ctx, "Line 2");
line2.overrideValueRenderer($contentLineText);

The overrideValueRender will call some logic and will ends with formatting the date. The javascript file that contains this logic can be found  in the 15 hyve on the following location: \15\TEMPLATE\LAYOUTS\Search.ClientControls.debug.js. The call to retrieve the the formatted date is actually the one that will be done using the following line:

return SP.Utilities.HttpUtility.htmlEncode(Srch.U.toFormattedDate(valueObject.value, $v_0));

Now as you can see the value that is passed to format the date is the valueObject.value, and that value is of type DateTime.

When you create a custom display template can create your own objects, and you can debug it a little more, so lets assume you have a custom display template for debugging purposes and there is an object called ArticleDate that you can use. You can checkout all the available properties on the articleDate object. One of these properties is the inputValue instead of the value. This property is the actual inputted value as a string and will return a slightly different value: 

var articleDate = $getItemValue(ctx, "Article Date");
console && console.log('inputValue: ' + articleDate.inputValue);
//result of inputValue: 2014-03-11T23:00:00Z
console && console.log('value: ' + articleDate.value);
//result of value: Tue Mar 11 2014 23:00:00 GMT+0100

If you would parse the inputValue to a datetime object and then format it the way you want you will end up with a corrected date string in your display templates, and thus not being confronted with a date that is wrong due to Daylight Savings Time:

var parsedDate = new Date(articleDate.inputValue);
parsedDate.format('dddd, MMMM dd, yyyy')
//result: Tuesday, March 11, 2014

Now you can also create your own overrideValueRender method instead of calling the default one and provide the logic there, as long as you are using the inputValue property instead of the value property for determining the input. In our case we just created a custom display template to control the rendering of the date. 

There are 10 comments for this article
  1. Cas van Iersel at 09:00

    Hey Appie I came across this just yesterday. Weird! I was expecting a correct value to be in the Index like 2014-03-12T00:00:00Z instead of 2014-03-11T23:00:00Z .. It's kind of awkward that this needs fixing in the Display Template since I'm using a default Display Template for a Content by Search WebPart. Thanks for this solution anyway 🙂

  2. Elio Struyf at 15:09

    Appie,

    It has nothing to do with the display template. It has to do with the value type of your managed property and how it gets crawled (plus as in the previous versions, date time values are stored in UTC format).

    By default if search crawls new date time properties they are stored as Text Data values, instead of DateTime.
    In a text property, the date value will be stored as just text as you showed it above: "2014-03-11T23:00:00Z". This text value isn't UTC aware, so you need to parse it to a date object like you showed in the end.

    If the value gets stored as a DateTime data type, it will also return a datetime object and you don't need to do any conversion. Here is an example:

    Regards,
    Elio

  3. Albert-Jan Schot at 15:43

    Elio thanks for pointing that out, you are right the crawled properties are of type text instead of a DateTime, still a bit confusing that for a default property with a default display template it will fail.

    • Elio Struyf at 20:06

      I have the same questions about it. If they stored it by default as a date time data type, it would also make it easier for sorting. Now you need to manually create the property before it can be used for sorting.

    • Elio Struyf at 13:37

      Appie,

      One other detail, this only works with the auto-created properties. So with managed properties that have OWSDATE at the end of the name.
      Otherwise the inputValue just be a text value. This is because in the search.clientscontrols.js file, there is a method ValueTypeHandler which extracts the auto-generated name property ("OWSDATE", "OWSTEXT", …) from the name. With that extracted value it knows to which type the value can be parsed.
      If you have a custom created managed property, of the type text, for a date time field. The "inputValue" will be the same as "value", just a string.

      Regards,
      Elio

      • Albert-Jan Schot at 16:46

        Good one, hadn't spotted it yet but it's good to know that even your own properties should have the OWSDATE suffix.

  4. Stefan Hennicken at 15:20

    Thank you sooooooo much for sharing. Such a great post. I was searching for hours why my datefields were displaying date-1.

Leave a Reply