jquery datepicker getTime not UTC

17,290

Solution 1

It looks like the datepicker doesn’t return UTC dates, but local ones (which is actually the default in Javascript).

To convert your constructed dates to local time:

$("select.startdates").find("option").each( function() {
  var d = Date.UTC.apply(Date, this.value.split(",").map(Number));
  d = d + new Date(d).getTimezoneOffset() * 60000; // convert UTC to local
  startDates.push(d);
});

Normally, I’d use the new Date(year, month, day) constructor instead of the Date.UTC function, but you can’t use apply with the Date constructor.

If you’d rather leave your startDates array in UTC, then you need to convert the datepicker’s dates to UTC:

function showEventDates(date) {
  date = date - new Date(date).getTimezoneOffset() * 60000; // convert local to UTC
  // for ...
}

NB: choose one or the other of these methods, not both, or you’ll end up with the same problem... :-)

Solution 2

I hear there are some timezone updates to the jQuery datetimepicker so you may want to check the site first, however here is what I did to get the selected date & time in UTC format.

First create the datetimepicker and use cities instead of +0500 GMT because if you use GMT offsets you have to take into account daylight savings - and that is a nightmare.

 // create ye datetimepicker with timezone options 
 $('#datetimepicker').datetimepicker({
    showTimezone: true,
    onSelect: onSelect,
    timezoneList: [
      { value: 'America/New_York', label: 'New York'},
      { value: 'America/Chicago', label: 'Chicago' } ,
      { value: 'America/Denver', label: 'Denver' },
      { value: 'America/Los_Angeles', label: 'Los Angeles' }
    ]);

Next, grab the timezoneJS.Date library from mde on Github (NOTE: you will also need to download the appropriate timezone files for your region, just follow the README instructions)

Now when the user selects a date the onSelect method gets called.

function onSelect(dateText, dateInst) {
  // get the date without the timezone data
  var d = $('#datetimepicker').datepicker('getDate');

  // init timezoneJS
  timezoneJs.timezone.zoneFileBasePath = '/tz';
  timezoneJs.timezone.init();

  // get the selected timezone
  var tz = $('#datetimepicker').data('datepicker').settings.timepicker.timezone

  // construct the utcDate with the help of the timezoneJS.Date lib
  var utcDate = new timezoneJS.Date(
    d.getFullYear(),
    d.getMonth(),
    d.getDate(),
    d.getHours(),
    d.getMinutes(),
    tz)
  var utcLinuxTimestamp = utcDate.getTime() / 1000    
}

Not exactly painless, but it takes care of the daylight savings stuff for you.

The reverse of this to populate a datetimepicker with a date and a timezone from a UTC timestamp looks like this:

// init timezone JS
timezoneJs.timezone.zoneFileBasePath = '/tz';
timezoneJs.timezone.init();

// get timezone date JS object
var tz = 'America/New York';
var d = new timezoneJS.Date( timestamp * 1000, tz);

$('#datetimepicker').datetimepicker({
  showTimezone: true,
  timezoneList: [ 
      { value: 'America/New_York', label: 'New York'},
      { value: 'America/Chicago', label: 'Chicago' } ,
      { value: 'America/Denver', label: 'Denver' },
      { value: 'America/Los_Angeles', label: 'Los Angeles' }
    ],
  timezone: tz,
  defaultDate: d._dateProxy,
  onSelect: onSelect
}).datepicker('setDate',d._dateProxy);

I'm not certain if you need the setDate part on the last line, but couldn't hurt.

Share:
17,290

Related videos on Youtube

Tom
Author by

Tom

Web designer and wannabe developer (I'm learning... constantly)

Updated on September 14, 2022

Comments

  • Tom
    Tom over 1 year

    I have the following code which works fine until the datepicker reaches BST.

    var i;
    function showEventDates(date) {
      for (i = 0; i < startDates.length; i++) {
        if (date.getTime() == startDates[i]) {
          return [true, 'eventDay'];
        }
      }    
      return [false, ''];
    }
    var startDates = new Array();
    
    $("select.startdates").find("option").each( function() {
      startDates.push(Date.UTC.apply(Date, this.value.split(",").map(Number)));
    });
    
    $('#mydate').datepicker({
        beforeShowDay: showEventDates
    });
    

    During BST the line if (date.getTime() == startDates[i]) { returns false because there's an hour difference.

    Any ideas how I can get these to match? I think it's the datepicker time that's not UTC.

    EDIT:

    An example of an option from select.startdates is

    <option value="2013, 2, 1">01/03/2013</option>