ZhangyuWang
ZhangyuWang

Reputation: 9

javascript date plus some days issue

I am developing a report system. In my report system I am going to automatically plus days to date that picked date. I used following Javascript code snippet.

function add_date(curdate, days) {
  
  //curdate format : "yyyy-mm-dd"
  var newdate = new Date(curdate);

  newdate.setDate(newdate.getDate() + days);

  var dd = newdate.getDate();
  var mm = newdate.getMonth() + 1;
  var y = newdate.getFullYear();

  if(dd < 10)
    dd = '0' + dd;
  if(mm < 10)
    mm = '0' + mm;

  var someFormattedDate = y + '-' + mm + '-' + dd;
  return someFormattedDate;
  
}

This function is working as well on almost platforms and browsers. But on the particular platform or browser like iPhone Safari and Windows 8.1, I got different result. If I plus 3 days, I can get the result that plus 2 days. I tested on my computer, iPhone and browserstack.com. I want kindly your assistance. Thanks.

Upvotes: 0

Views: 122

Answers (3)

RobG
RobG

Reputation: 147353

As pointed out in other answers, ECMAScript 2015 requires y-m-d format to be parsed as UTC, however there was a time when ECMCAScript 2015 was interpreted as treating it as local (per ISO 8601 and long format date and time strings without a timezone), however that interpretation was reversed (note that ISO 8601 format date and time without a timezone is treated as local).

Also, not all browsers in use correctly parse ISO formats, and some don't parse them at all.

If you are west of Greenwich, then new Date('2016-02-20') will create a date for local 19 February, not 20, which might be confusing.

You don't say whether you want it to be local or not, but since this is for reporting perhaps it should be. You can use a library to do the parsing, but it only takes a couple of lines of code:

/*  Parse and validate a date in format yyyy-mm-dd
**  Note that a date without a timezone is treated as LOCAL, per ISO 8601
**  @param {string} s - date in format y-m-d
**  @returns {Date} time vlaue is NaN if date is invalid
*/
function parseISODateLocal(s){
  var b = s.split(/\D/);
  var d = new Date(b[0], --b[1], b[2]);
  return d && d.getMonth() == b[1]? d : new Date(NaN);
}

To format a date as y-mm-dd, you can use:

/* Return an ISO 8601 string without timezone
** @param {Date} d - date to create string for
** @returns {string} string formatted as ISO 8601 without timezone
*/
function toISODateLocal(d) {
  function z(n){return (n<10?'0':'') + n}
  return d.getFullYear() + '-' + z(d.getMonth()+1) + '-' + z(d.getDate());
}

Upvotes: 0

terrymorse
terrymorse

Reputation: 7086

The date problem is probably because of time zone interpretations.

The date string 'yyyy-mm-dd' is supposed to mean midnight UTC, but some browsers may not respect this convention.

To work around this issue, you can do a quick fix by appending a fixed time to your date string.

Adding this:

  curdate += 'T12:00:00Z';

will definitely set the time to noon UTC.

jsfiddle here

Upvotes: 0

WhiteHat
WhiteHat

Reputation: 61212

I'd say your best bet would be to look into Moment.js

But you might try something like this...

// add 5 days
console.log(add_date('2016-02-18T15:53:02Z', 5));

function add_date(curdate, days) {
    var newdate = new Date(curdate);

    // add number of days
    return new Date(newdate.getTime() + ((24 * 60 * 60 * 1000) * days));
}

Upvotes: 1

Related Questions