Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug with setValue: hours is 1hr less than selected #462

Closed
Hirurg103 opened this issue Oct 28, 2018 · 9 comments · Fixed by #500
Closed

Bug with setValue: hours is 1hr less than selected #462

Hirurg103 opened this issue Oct 28, 2018 · 9 comments · Fixed by #500
Labels
Status: done Type: bug Valid bug introduced in new features, confirmed by a contributor.

Comments

@Hirurg103
Copy link
Contributor

I use setValue to set date values in the app form. But the issue is that the displayed value is 1hr less than selected by the user.

datepicker-error-example.html

This bug is reproducible when I select Greenwich Mean Time time zone on my computer
screen shot 2018-10-28 at 12 44 24 pm

I am adding a source code how to reproduce this bug:

<!doctype html>
<html>
  <head>
    <script src="https://rawgit.com/jquery/jquery/1.12.4/dist/jquery.min.js"></script>
    <script src="https://rawgit.com/moment/moment/develop/min/moment-with-locales.min.js"></script>
    <script src="https://rawgit.com/longbill/jquery-date-range-picker/master/dist/jquery.daterangepicker.min.js"></script>
    <link href="https://rawgit.com/longbill/jquery-date-range-picker/master/dist/daterangepicker.min.css" rel="stylesheet"/>
  </head>

  <body>
    <input type="text" id="from"/>
    <input type="text" id="to"/>
    <a id="datepicker">
      select dates
    </a>
    <script>
      $('#datepicker').dateRangePicker({
        separator: ' to ',
        time: { enabled: true },
        format: 'DD-MM-YYYY HH:mm',
        showShortcuts: true,
        setValue: function(s, s1, s2) {
          console.log(s)
          console.log(s1)
          console.log(s2)
          $(this).val(s)
          $("#from").val(s1)
          $("#to").val(s2)
        },
        shortcuts: {
          'prev-days': null,
          'next-days': null,
          prev: null,
          next: null
        },
        startOfWeek: 'monday'
      })
    </script>
  </body>
</html>

There is a gist with this source code

@monovertex
Copy link
Collaborator

Please see this JSFiddle that contains the gist you posted and let me know if you can reproduce the bug there. On my Windows machine it seems to be setting the values correctly.

image

image

If the JSFiddle is OK for you, then the issue is caused by some other code in your app. Are you setting the timezone for the moment object, by any chance?

@monovertex monovertex added the Status: needs submitter response There's additional information to properly assess this issue. label Oct 29, 2018
@Hirurg103
Copy link
Contributor Author

Hirurg103 commented Oct 29, 2018

Hi @monovertex, yes I am unable to reproduce this bug today. I tried to set my computer's time to yesterdays date (28 Oct 2018) and it is reproducible! See screenshot

screen shot 2018-10-28 at 9 15 33 am - highlighted

@Hirurg103
Copy link
Contributor Author

Hi @monovertex , what do you think about it?

@monovertex
Copy link
Collaborator

@Hirurg103 Sorry, I've been caught up with work and real life. I'm currently on a Linux machine, which gives me grief with date changes, I'll check it out on 28 October as soon as I get home on my Windows machine and come back with my feedback.

@monovertex monovertex added Status: needs triage Issue has not been properly analyzed yet. and removed Status: needs submitter response There's additional information to properly assess this issue. labels Nov 1, 2018
@Hirurg103
Copy link
Contributor Author

@monovertex no problem at all. Thank you for the response!

@monovertex
Copy link
Collaborator

monovertex commented Nov 2, 2018

@Hirurg103, some first thoughts:

  • You don't need to change computer timezone or date to 28 October, it's enough to just select 28 October in the datepicker.
  • I'm pretty sure it has to do with daylight savings, since 28 October is the day when the time switched to winter hour.
  • Even if I turned off daylight savings in my computer's time settings, the bug was still there.

I'll have to take a look through the code and see where is the hour difference coming from, but this is definitely a confirmed bug now. PRs are welcome 😁.

@monovertex monovertex added Type: bug Valid bug introduced in new features, confirmed by a contributor. Status: todo Accepted issue that needs someone to fix it. and removed Status: needs triage Issue has not been properly analyzed yet. labels Nov 2, 2018
@brainumbc
Copy link

brainumbc commented Dec 6, 2018

This is probably related to an issue I had. When function x() fires (the one that fires when you click a date), the math to determine date range is based on milliseconds. On November 4th this year the clocks rolled back 1 hour so technically November 4th is 25 hours long in countries that use daylight savings. So if you do an alert to spit out the times "a.start" and "a.end" you'll see a UTC offset such as
28 Oct 2018 00:00:00T-04:00
and
28 Nov 2018 00:00:00T-05:00

My requirement was to make the maxdays=31 but because this range above is 31 days and 1 hour, daterangepicker rounds up to 32. I imagine you'll have a similar issue when daylight savings starts and you'll be able to select 1 day more than your date range, or the range will report as 1 day less. Your problem is likely similar to mine. Here's what I added at the very top of function x() to fix this issue. You might want to use this as starting point. This assumes that all dates are midnight, though:

` var mystart = new Date(a.start);
var myend = new Date(a.end);

        if (mystart.getTimezoneOffset() < myend.getTimezoneOffset()) {
            mystart = mystart.setMinutes(myend.getTimezoneOffset() - mystart.getTimezoneOffset()); //if end date is after daylight savings ends (end date is 1 hour later, add 1 hour to start date)
        } else if (myend.getTimezoneOffset() < mystart.getTimezoneOffset()) {
            myend = myend.setMinutes(mystart.getTimezoneOffset() - myend.getTimezoneOffset()); // opposite if end date is 1 hour earlier offset than start date
        } else {
            mystart = mystart.setMinutes(0); 
            myend = myend.setMinutes(0);
        }
        
        a.start = new Date(mystart).getTime();
        a.end = new Date(myend).getTime();`

Essentially what you get is when datlight savings ends, the start date (before it ended) will have the same UTC offset as it did before, so the start date time thrown in the calculation will be 60 minutes shorter so the calculation will be exactly 31 days... or you could just subtract 60 minutes from the last day.. either way.

@brainumbc
Copy link

Actually strike that second condition where "myend" is set. This takes a range that would be 30 days and 23 hours and adds 60 minutes to make the range an even 31, which is unnecessary because date range calcs in JS are going to round up to 31 anyways. However, if you're looking for exact time between ranges and not just days, I'd keep it in.

@Hirurg103
Copy link
Contributor Author

Hello @monovertex @longbill . Could you please take a look at my PR that fixes this bug when you have time. Thank you!

monovertex pushed a commit that referenced this issue Oct 28, 2020
…T clocks change

[fix #462]

Before this commit the time calculated by the plugin was one hour more
than the time selected by the user when the clocks move forward an hour
and one hour less when the clocks move back for users in BST/DST regions.

This happened because to calculate the selected time, the selected hours
were added to the beginning of the selected day. For example, when user
selected 02:00 on the day when the clocks move forward then the calculated
time was 03:00 because the beginning of the day plus 2 hours is 03:00.
This is due to the fact that at 01:00 the clocks move forward an hour.

For more details see
https://en.wikipedia.org/wiki/British_Summer_Time
https://en.wikipedia.org/wiki/Daylight_saving_time

In this commit the code was changed to use the hour/minute MomentJS
functions to set time:

https://momentjs.com/docs/#/get-set/hour
https://momentjs.com/docs/#/get-set/minute
@monovertex monovertex added Status: done and removed Status: todo Accepted issue that needs someone to fix it. labels Oct 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: done Type: bug Valid bug introduced in new features, confirmed by a contributor.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants