Philipp Nies
Philipp Nies

Reputation: 969

Set datetime shows wrong date

I have two radio buttons to select a time range.

These two options are available:

0:00 - 0:00 (24h)

6:00 - 6:00 (24h)

And this is my jQ function:

$('.btn-time').on('change', function() {
    var value = $(this).attr('data-value');
    var a = new Date($('#ipDateTimeFrom').val());
    var b = new Date($('#ipDateTimeTo').val());
    switch(value) {
        case '0':
            a.setUTCHours(0);
            a.setUTCMinutes(0);
            a.setUTCSeconds(0);
            b.setUTCHours(0);
            b.setUTCMinutes(0);
            b.setUTCSeconds(0);
            break;
        case '6':
            a.setUTCHours(6);
            a.setUTCMinutes(0);
            a.setUTCSeconds(0);
            b.setUTCHours(6);
            b.setUTCMinutes(0);
            b.setUTCSeconds(0);
            break;
    }

    $('#ipDateTimeFrom').val(a.toISOString().replace('T', ' ').replace( /\..+/g, ''));
    $('#ipDateTimeTo').val(b.toISOString().replace('T', ' ').replace( /\..+/g, ''));
});

If I switch between 0:00 and 6:00 the date change from 2016-06-07 00:00:00 to 2016-06-06 06:00:00 and I dont know why. The Date day ist untouched.

Here is a working jsbin to point out the problem

Upvotes: 2

Views: 208

Answers (2)

trincot
trincot

Reputation: 350252

This happens because you mix local time with UTC time, and you are probably living in a UTC+something timezone.

More precisely, the string value you read from the input element and convert to date is interpreted as a local date/time. But in UTC format this is a few hours earlier, and so when you start truncating the date to 0:00 all is still OK, but then the input also gets 0:00, which in UTC is a few hours earlier, i.e. in the previous day. So the next time you perform a truncation to 6:00 it will be 6:00 the previous day.

So you should stick in all operations with either UTC or local dates. Here is how you make the input strings to be interpreted as UTC, so that all operations are in UTC:

var a = new Date($('#ipDateTimeFrom').val().replace(' ', 'T') + 'Z');
var b = new Date($('#ipDateTimeTo').val().replace(' ', 'T') + 'Z');
// etc.

Of course this assumes the date/time entered follows a certain format. But you'll get the idea. The Z at the end makes it UTC.

Upvotes: 2

derp
derp

Reputation: 2308

To save yourself a life of pain, use moment.js. It makes the parsing and formatting so much easier

$('.btn-time').on('change', function() {
        var value = $(this).attr('data-value');
        var a = new Date($('#ipDateTimeFrom').val());
        var b = new Date($('#ipDateTimeTo').val());
        var newA, newB;
        switch(value) {
            case '0':
                newA = moment(a).startOf('day');
                newB = moment(b).startOf('day');
                break;
            case '6':
                newA = moment(a).startOf('day').hours(6);
                newB = moment(b).startOf('day').hours(6);
                break;
        }

        $('#ipDateTimeFrom').val(newA.format('YYYY-MM-DD HH:mm:ss'));
        $('#ipDateTimeTo').val(newB.format('YYYY-MM-DD HH:mm:ss'));
    });

http://jsbin.com/gecahaquqo/1/edit?html,js,console,output

Upvotes: 2

Related Questions