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

In IE11, picking a date sets the value to the day before #151

Open
jdhines opened this issue Jun 6, 2017 · 3 comments
Open

In IE11, picking a date sets the value to the day before #151

jdhines opened this issue Jun 6, 2017 · 3 comments

Comments

@jdhines
Copy link

jdhines commented Jun 6, 2017

Everything works fine in Chrome, but in IE, as soon as you click a day, or if entering the day manually, say "5/6/2017" and tabbing to the next field, the day becomes the previous day. I'm using the useUTC=true prop, which fixed this issue upon saving to the backend in Chrome, but in IE, this is happening as soon as a day is selected, so I don't know what's going on or how to correct it.

@duizendnegen
Copy link
Contributor

Welcoming a PR, the problem comes from UTC and non-UTC to use different methods. We need to normalise this.

See https://github.com/edgycircle/ember-pikaday/blob/master/addon/mixins/pikaday.js#L106

Could be combined with #106

@ghost
Copy link

ghost commented Jun 9, 2017

This is also not working for me in Safari.

@jdhines
Copy link
Author

jdhines commented Jun 9, 2017

I don't know how I'd change ember-pikaday to solve this, so I'm not the one to do a PR, but I did solve this in my project by adding a computed field in my model, using that field in my template, and saving that computed field to the actual field when saving the model. Seems like a lot of work to me, but it's not all this add-in's fault; I don't understand why dates are so difficult to do right in my application; may be in part because the database has just a date, and in JavaScript it's all date and time. If I could just use strings, it would be easier. Does this plugin support that?

app/models/my-model.js

//uses the dates mixin
export default DS.Model.extend({
  // ...
  date: attr('date'),
  dateTransform: function() {
    var d = this.get('date');
    if (d) {
      //if it is a valid date, then we want to convert to UTC or else we'll have "day before" issues
      //set the time to noon; this will account for all US time zones
      d = convert(d);
      d = moment(d).utc().hours(12).toISOString();
    }
    return d;
  }.property('date'),
});

app/controllers/my-component.js

save: function() {
      this.get('model').set('date',this.get('dateTransform'));
      get(this, 'model').save().then(function(){
        //stuff
      });
    }

mixins/dates.js

//mixins/dates.js
import Ember from 'ember';

function convert(d) {
  // Converts the date in d to a date-object. The input can be:
  //   a date object: returned without modification
  //  an array      : Interpreted as [year,month,day]. NOTE: month is 0-11.
  //   a number     : Interpreted as number of milliseconds
  //                  since 1 Jan 1970 (a timestamp)
  //   a string     : Any format supported by the javascript engine, like
  //                  "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
  //  an object     : Interpreted as an object with year, month and date
  //                  attributes.  **NOTE** month is 0-11.
  return (
    d.constructor === Date ? d :
    d.constructor === Array ? new Date(d[0],d[1],d[2]) :
    d.constructor === Number ? new Date(d) :
    d.constructor === String ? new Date(d) :
    typeof d === "object" ? new Date(d.year,d.month,d.date) :
    NaN
  );
}

function compare(a,b) {
  // Compare two dates (could be of any type supported by the convert
  // function above) and returns:
  //  -1 : if a < b
  //   0 : if a = b
  //   1 : if a > b
  // NaN : if a or b is an illegal date
  // NOTE: The code inside isFinite does an assignment (=).
  return (
    isFinite(a=convert(a).valueOf()) &&
    isFinite(b=convert(b).valueOf()) ?
    (a>b)-(a<b) :
    NaN
  );
}

function inRange(d,start,end) {
  // Checks if date in d is between dates in start and end.
  // Returns a boolean or NaN:
  //    true  : if d is between start and end (inclusive)
  //    false : if d is before start or after end
  //    NaN   : if one or more of the dates is illegal.
  // NOTE: The code inside isFinite does an assignment (=).
  return (
    isFinite(d=convert(d).valueOf()) &&
    isFinite(start=convert(start).valueOf()) &&
    isFinite(end=convert(end).valueOf()) ?
    start <= d && d <= end :
    NaN
    );
}

var Dates = Ember.Mixin.create({
  convert: convert,
  compare: compare,
  inRange: inRange
});

export {compare, convert, inRange};
export default Dates;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants