Date Picker value not encoding timezone

6 posts, 0 answers
  1. Harlan
    Harlan avatar
    19 posts
    Member since:
    Dec 2014

    Posted 08 Mar Link to this post

    We have a problem with the kendo ui date picker. We have a server which returns dates in ISO8601 format, encoded with timezone information. (it's rare that there are any UTC dates in our database) We've gotten the date picker to display those ISO8601 dates in a sane, human-readable format, but what we haven't managed is how to encode timezone information with the date value sent back to the server upon saving.

    Here is a jsfiddle which hopefully makes it a little easier to follow along with what the problem is: https://jsfiddle.net/stdph60n/

    To see the problem we're having, (1) Fill in the datepicker (e.g. 03/07/2016)

    (2) Open your developer tools on the jsfiddle tab and click on the "Network" tab (or you can skip steps 2, 3, and 4 and just look at the value of dateString below the datepicker)

    (3) Hit the "Click me!" button

    (4) Look at the dateString value under "Request Payload"  It says "3/7/2016". When this gets sent to the server, the server reads it as "2016-03-07T00:00:00+00:00". For my particular time zone, the server should be reading the value as "2016-03-07T00:00:00-05:00"

    Is there a way to send the time zone information encoded within the date information so the server can know which time zone the date is in?

  2. Harlan
    Harlan avatar
    19 posts
    Member since:
    Dec 2014

    Posted 09 Mar in reply to Harlan Link to this post

    I found a solution using an angular directive to work around this problem. The values that are submitted to the server now are proper ISO8601 dates WITH timezone information encoded in the date string.  Here's my directive, for those who are interested.

    1.<!-- For best results, assign the kendo-datepicker attribute to an object on the scope. ng-model is required, obviously. -->
    2.<input kendo-datepicker="datePickerObj" date-picker-value-changer ng-model="dateValue" />

    01.angular.module('PZEApp').directive('datePickerValueChanger', [function () {
    02.    function prelink() {
    03. 
    04.    }
    05. 
    06.    // Not everybody uses the default kendo-date-picker directive. I've personally been using kendo-datepicker, which shows up in the attrs object as 'kendoDatepicker'
    07.    function getCaseInsensitiveKey(obj, key) {
    08.        for (var i in obj) {
    09.            if (i.toLowerCase() == key.toLowerCase()) {
    10.                return obj[i];
    11.            }
    12.        }
    13.    }
    14. 
    15.    /**
    16.    * @param {Date} date
    17.    *
    18.    * Built this function because the default Javascript Date.toISOString() does not encode timezone information with its dates.
    19.    */
    20.    function toISOStringWithTimeZone(date) {
    21.        var offset = date.getTimezoneOffset();
    22.        offset = -offset;
    23. 
    24.        var offsetString = String.format("{0}{1}:{2}",
    25.            (offset >= 0) ? '+' : '-',
    26.            zeroPadLeft(parseInt(Math.abs(offset) / 60), 2),
    27.            zeroPadLeft(Math.abs(offset) % 60, 2)
    28.        );
    29. 
    30.        return String.format("{0}-{1}-{2}T{3}:{4}:{5}.{6}{7}",
    31.            zeroPadLeft(date.getFullYear(), 4),
    32.            zeroPadLeft(date.getMonth() + 1, 2),
    33.            zeroPadLeft(date.getDate(), 2),
    34.            zeroPadLeft(date.getHours(), 2),
    35.            zeroPadLeft(date.getMinutes(), 2),
    36.            zeroPadLeft(date.getSeconds(), 2),
    37.            zeroPadLeft(date.getMilliseconds(), 3),
    38.            offsetString
    39.        );
    40.    }
    41. 
    42.    function link(scope, element, attrs, ngModel) {
    43.        ngModel = ngModel[0];
    44. 
    45.        ngModel.$parsers.push(function (value) {
    46.            var date = new Date(value);
    47.            return toISOStringWithTimeZone(date);
    48.        });
    49. 
    50.        ngModel.$formatters.push(function (value) {
    51.            var date = new Date(value);
    52.            var datePicker = scope.$eval(getCaseInsensitiveKey(attrs, 'kendoDatePicker'));
    53. 
    54.            if (attrs.dateFormatter) {
    55.                value = scope.$eval(attrs.dateFormatter, { date: date });
    56.            } else if (datePicker && datePicker.options.format) {
    57.                value = kendo.toString(date, datePicker.options.format);
    58.            } else {
    59.                value = kendo.toString(date, "M/d/yyyy");
    60.            }
    61. 
    62.            return value;
    63.        });
    64.    }
    65. 
    66.    return {
    67.        restrict: 'A',
    68.        require: ['ngModel'],
    69. 
    70.        compile: function (element, attrs, transclude) {
    71.            return {
    72.                pre: prelink,
    73.                post: link
    74.            };
    75.        }
    76.    };
    77.}]);

  3. Kendo UI is VS 2017 Ready
  4. Kiril Nikolov
    Admin
    Kiril Nikolov avatar
    2565 posts

    Posted 10 Mar Link to this post

    Hello Harlan,

    The widget works with JavaScript dates, so the behavior that you observer is expected, however the workaround looks good and I would like to thank you for sharing it.

    Regards,
    Kiril Nikolov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  5. Elliot
    Elliot avatar
    59 posts
    Member since:
    May 2012

    Posted 17 Mar in reply to Harlan Link to this post

    Thanks for posting this Harlan but something is missing.  The zeroPadLeft function is raising an error.
  6. Harlan
    Harlan avatar
    19 posts
    Member since:
    Dec 2014

    Posted 17 Mar in reply to Elliot Link to this post

    Yes, sorry about that.  Here's the zeroPadLeft function:

    1.function zeroPadLeft(n, p, c) {
    2.    var pad_char = typeof c !== 'undefined' ? c : '0';
    3.    var pad = new Array(1 + p).join(pad_char);
    4.    return (pad + n).slice(-pad.length);
    5.}

     

    Hopefully there's no other code in here that was defined elsewhere in the project.

  7. Kiril Nikolov
    Admin
    Kiril Nikolov avatar
    2565 posts

    Posted 18 Mar Link to this post

    Hello Harlan,

    Thanks for the update!

    Regards,
    Kiril Nikolov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready