Let's say we have this datetime:
var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
Exporting it as a string (console.log(d)) gives inconsistent results among browsers:
Sat Jul 21 2018 14:00:00 GMT+0200 (Paris, Madrid (heure d’été)) with Chrome
Sat Jul 21 14:00:00 UTC+0200 2018 with Internet Explorer, etc.
so we can't send datetime to a server with an unconsistent format.
The natural idea then would be to ask for an ISO8601 datetime, and use d.toISOString(); but it gives the UTC datetime: 2018-07-21T12:00:00.000Z whereas I would like the local-timezone time instead:
2018-07-21T14:00:00+0200
or
2018-07-21T14:00:00
How to get this (without relying on a third party dependency like momentjs)?
I tried this, which seems to work, but isn't there a more natural way to do it?
var pad = function(i) { return (i < 10) ? '0' + i : i; };
var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
Y = d.getFullYear();
m = d.getMonth() + 1;
D = d.getDate();
H = d.getHours();
M = d.getMinutes();
S = d.getSeconds();
s = Y + '-' + pad(m) + '-' + pad(D) + 'T' + pad(H) + ':' + pad(M) + ':' + pad(S);
console.log(s);
There is limited built-in support for formatting date strings with timezones in ECMA-262, there is either implementation dependent toString and toLocaleString methods or toISOString, which is always UTC. It would be good if toISOString allowed a parameter to specify UTC or local offset (where the default is UTC).
Writing your own function to generate an ISO 8601 compliant timestamp with local offset isn't difficult:
function toISOLocal(d) {
var z = n => ('0' + n).slice(-2);
var zz = n => ('00' + n).slice(-3);
var off = d.getTimezoneOffset();
var sign = off > 0? '-' : '+';
off = Math.abs(off);
return d.getFullYear() + '-'
+ z(d.getMonth()+1) + '-' +
z(d.getDate()) + 'T' +
z(d.getHours()) + ':' +
z(d.getMinutes()) + ':' +
z(d.getSeconds()) + '.' +
zz(d.getMilliseconds()) +
sign + z(off/60|0) + ':' + z(off%60);
}
console.log(toISOLocal(new Date()));
The trick is to adjust the time by the timezone, and then use toISOString(). You can do this by creating a new date with the original time and subtracting by the timezone offssetfrom the original time:
var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
var newd = new Date(d.getTime() - d.getTimezoneOffset()*60000);
console.log(newd.toISOString()); // 2018-07-21T22:00:00.000Z
Alternatively, you can simply adjust the original date variable:
var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
d = new Date(d.getTime() - d.getTimezoneOffset()*60000);
console.log(d.toISOString()); // 2018-07-21T22:00:00.000Z
For your convenience, the result from .getTime() is the number of milliseconds since 1 January 1970. However, getTimezoneOffset() gives a time zone difference from UTC in minutes; that’s why you need to multiply by 60000 to get this in milliseconds.
Of course, the new time is still relative to UTC, so you’ll have to ignore the Z at the end:
d = d.slice(0,-1); // 2018-07-21T22:00:00.000
My version:
// https://stackoverflow.com/questions/10830357/javascript-toisostring-ignores-timezone-offset/37661393#37661393
// https://stackoverflow.com/questions/49330139/date-toisostring-but-local-time-instead-of-utc/49332027#49332027
function toISOLocal(d) {
const z = n => ('0' + n).slice(-2);
let off = d.getTimezoneOffset();
const sign = off < 0 ? '+' : '-';
off = Math.abs(off);
return new Date(d.getTime() - (d.getTimezoneOffset() * 60000)).toISOString().slice(0, -1) + sign + z(off / 60 | 0) + ':' + z(off % 60);
}
console.log(toISOLocal(new Date()));
i have found a solution which has worked for me.
see this post: Modifying an ISO Date in Javascript
for myself i tested this with slight modification to remove the "T", and it is working. here is the code i am using:
// Create date at UMT-0
var date = new Date();
// Modify the UMT + 2 hours
date.setHours(date.getHours() + 2);
// Reformat the timestamp without the "T", as YYYY-MM-DD hh:mm:ss
var timestamp = date.toISOString().replace("T", " ").split(".")[0];
and an alternative method is stipulate the format you need, like this:
// Create the timestamp format
var timeStamp = Utilities.formatDate(new Date(), "GMT+2", "yyyy-MM-dd' 'HH:mm:ss");
note: these are suitable in locations that do not have daylight saving changes to the time during the year
it has been pointed out that the above formulas are for a specific timezone.
in order to have the local time in ISO format, first specify suitable Locale ("sv-SE" is the closest and easiest to modify), then make modification (change the space to a T) to be same as ISO format. like this:
var date = new Date(); // Create date
var timestamp = date.toLocaleString("sv-SE").replace(" ", "T").split(".")[0]; // Reformat the Locale timestamp ISO YYYY-MM-DDThh:mm:ss
References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString)
https://www.w3schools.com/Jsref/jsref_tolocalestring.asp
https://www.w3schools.com/Jsref/tryit.asp?filename=tryjsref_tolocalestring_date_all
Related
I need a little help to create a variable on google tag manager that takes me the timestamp of when an event is triggered.
Now I have implemented this custom javascript but it takes me as the timezone that of the country of the user who will trigger the event.
On the other hand, I would like timezone always +02.00, can someone teach me which part of the code I need to modify to have my timezone always set?
Thank you
function()
{
var now = new Date();
var tzo = -now.getTimezoneOffset();
var dif = tzo >= 0 ? '+' : '-';
var pad = function(num) {
var norm = Math.abs(Math.floor(num));
return (norm < 10 ? '0' : '') + norm;
};
return now.getHours()
+ ':' + pad(now.getMinutes())
+ ':' + pad(now.getSeconds())
+ '.' + pad(now.getMilliseconds())
+ dif + pad(tzo / 60)
+ ':' + pad(tzo % 60);
}
This should be ample:
function qwe() {
var d = new Date();
nd = new Date((d.getTime() + (d.getTimezoneOffset() * 60000)) + (3600000 * 2));
var tzo = 120;
var dif = tzo >= 0 ? '+' : '-';
var pad = function (num) {
var norm = Math.abs(Math.floor(num));
return (norm < 10 ? '0' : '') + norm;
};
return nd.getHours()
+ ':' + pad(nd.getMinutes())
+ ':' + pad(nd.getSeconds())
+ '.' + pad(nd.getMilliseconds())
+ dif + pad(tzo / 60)
+ ':' + pad(tzo % 60);
}
Try to see this answer to "How to ignore user's time zone and force Date() use specific time zone": How to ignore user's time zone and force Date() use specific time zone
It says:
A Date object's underlying value is actually in UTC. To prove this, notice that if you type new Date(0) you'll see something like: Wed Dec 31 1969 16:00:00 GMT-0800 (PST). 0 is treated as 0 in GMT, but .toString() method shows the local time.
Big note, UTC stands for Universal time code. The current time right now in 2 different places is the same UTC, but the output can be formatted differently.
What we need here is some formatting
var _date = new Date(1270544790922);
// outputs > "Tue Apr 06 2010 02:06:30 GMT-0700 (PDT)", for me
_date.toLocaleString('fi-FI', { timeZone: 'Europe/Helsinki' });
// outputs > "6.4.2010 klo 12.06.30"
_date.toLocaleString('en-US', { timeZone: 'Europe/Helsinki' });
// outputs > "4/6/2010, 12:06:30 PM"
This works but.... you can't really use any of the other date methods for your purposes since they describe the user's timezone. What you want is a date object that's related to the Helsinki timezone. Your options at this point are to use some 3rd party library (I recommend this), or hack-up the date object so you can use most of it's methods.
Option 1 - a 3rd party like moment-timezone
moment(1270544790922).tz('Europe/Helsinki').format('YYYY-MM-DD HH:mm:ss')
// outputs > 2010-04-06 12:06:30
moment(1270544790922).tz('Europe/Helsinki').hour()
// outputs > 12
This looks a lot more elegant than what we're about to do next.
Option 2 - Hack up the date object
var currentHelsinkiHoursOffset = 2; // sometimes it is 3
var date = new Date(1270544790922);
var helsenkiOffset = currentHelsinkiHoursOffset*60*60000;
var userOffset = _date.getTimezoneOffset()*60000; // [min*60000 = ms]
var helsenkiTime = new Date(date.getTime()+ helsenkiOffset + userOffset);
// Outputs > Tue Apr 06 2010 12:06:30 GMT-0700 (PDT)
It still thinks it's GMT-0700 (PDT), but if you don't stare too hard you may be able to mistake that for a date object that's useful for your purposes.
I conveniently skipped a part. You need to be able to define currentHelsinkiOffset. If you can use date.getTimezoneOffset() on the server side, or just use some if statements to describe when the time zone changes will occur, that should solve your problem.
Conclusion - I think especially for this purpose you should use a date library like moment-timezone.
I am going crazy with this Date to String conversion into a TypeScript project:
I have this function performing my conversion:
fromDateToString(date: Date) : String {
let dateAsString = date.toISOString().substr(0, 19)
console.log(dateAsString);
return dateAsString;
}
As you can see it take a Date object containing the following value:
Wed Feb 08 2017 07:00:00 GMT-0800 (Ora standard del Pacifico USA)
and, in theory it have to convert this date in the following string format:
2017-02-08T07:00:00"
But I am finding a strange behavior on the time !!! The generated string is not the previous one but it is:
2017-02-08T15:00:00"
The generated time section is not 07:00:00 but it is 15:00:00
Why? What is wrong? What am I missing? How can I fix this issue?
The value isn't wrong; you're disregarding the timezone. toISOString returns a string written in UTC with Z at the end saying it's in UTC. You're stripping off the part of the string saying what timezone it's in.
If you like, you can get that string in local time instead by subtracting the timezone offset:
function fromDateToString(date/*: Date*/)/* : String*/ {
date = new Date(+date);
date.setTime(date.getTime() - (date.getTimezoneOffset() * 60000));
let dateAsString = date.toISOString().substr(0, 19);
return dateAsString;
}
console.log(fromDateToString(new Date()));
Just beware that your code using that string handles it as a local time, not UTC.
2017-02-08T15:00:00 -> this is UTC date (ISO) [UTC has 0:00 offset]
2017-02-08T07:00:00 -> this is GMT-0800
so if we convert 2017-02-08T07:00:00 to UTC we need to add 8:00 hours so 7 + 8 = 15 so its giving 2017-02-08T15:00:00
You directly cannot ignore timezone offset without adding/subtracting.
That happens because the EcmaScript algorithm for generating an ISO string always generates it with the UTC+0 timezone. You don't need (and shouldn't) modify the Date object. Here's an algorithm to get a ISO string with the local timezone:
let toLocalISOString;
{
const pad = function pad(str) {
return String(str).padStart(2, "0");
}
toLocalISOString = function toLocalISOString(date) {
const tzOffset = date.getTimezoneOffset(),
tzPlus = tzOffset >= 0;
return date.getFullYear() +
'-' + pad(date.getMonth() + 1) +
'-' + pad(date.getDate()) +
'T' + pad(date.getHours()) +
':' + pad(date.getMinutes()) +
':' + pad(date.getSeconds()) +
'.' + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5) +
(tzPlus ? "+" + pad(tzOffset / 60) : "-" + pad((tzOffset / 60).toString().slice(1))) +
":" + pad((tzOffset % 60).toFixed(0));
};
}
I am trying to set an end date for a JSON object. The end date equals 30 days after the start date. Sometimes this returns the correct date, sometimes it doesn't.
Here is the GetDateSchedulerFormatted function
GetDateSchedulerFormatted(date) {
function pad(s) { return (s < 10) ? '0' + s : s; }
var d = new Date(date);
// yyy-MM-dd
return [pad(d.getDate()), pad(d.getMonth() + 1), d.getFullYear()].join('/') + " " + pad(d.getHours()) + ":" + pad(d.getMinutes());
}
In this example the code returns the correct date
//activity.startDate = 2017-07-02T00:00:00-08:00
var startDate = this.GetDateSchedulerFormatted(activity.startDate); //start date 07/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Tue Aug 01 2017 00:00:00 GMT-0700 (Pacific Daylight Time) also 1 day off
var endDate = this.GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns correct date 01/08/2017 00:00 d/m/yyyy
In this next example it returns the date 1 year off
//activity.startDate = 2016-12-12T00:00:00-08:00
var startDate = this.GetDateSchedulerFormatted(activity.startDate); //returns 12/12/2016 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Jan 11 2017 00:00:00 GMT-0800 1 month ahead
var endDate = this.GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 11/01/2017 00:0 d/m/yyy
In this example the same exact date is returned
//activity.startDate = 2017-02-01T00:00:00-08:00
var startDate = this.GetDateSchedulerFormatted(activity.startDate); //returns 01/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Feb 01 2017 00:00:00 GMT-0800
var endDate = this.GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 01/02/2017 00:00 the same date, it's not 30 days ahead
Then in this final example I get NaN/NaN/NaN NaN:NaN
//activity.startDate = 2017-02-25T00:00:00-08:00
var startDate = this.GetDateSchedulerFormatted(activity.startDate); //returns 25/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns invalid date
var endDate = this.GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns NaN/NaN/NaN NaN:NaN
I have also tried new Date(Date.parse(startDate));
You really don't need a library. To add one month to a date is fairly straight forward, starting with:
date.setMonth(date.getMonth() + 1);
This maintains the time associated with the date, even over daylight saving boundaries, but can push the date beyond the end of the following month, e.g. adding 1 month to Jan 31 gives 31 Feb which goes to 2 or 3 March (depending on if it's a leap year or not).
So there needs to be a check that if the date isn't the same, it's rolled over a month so set it to the last day of the previous month. Written as a function to add an arbitrary number of months:
function addMonths(date, months) {
var d = date.getDate();
date.setMonth(date.getMonth() + +months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
// Add 12 months to 29 Feb, 2016
var d = new Date(2016,1,29)
console.log(addMonths(d, 12).toString()); // 28 Feb 2017
Adding is even easier, see Add +1 to current date which is easily adapted to add any number of days (which means this question is really a duplicate).
So, back to your code.
Here is the GetDateSchedulerFormatted function
function GetDateSchedulerFormatted(date) {
function pad(s) {
return (s < 10) ? '0' + s : s;
}
var d = new Date(date);
// yyy-MM-dd
return [pad(d.getDate()),
pad(d.getMonth() + 1),
d.getFullYear()
].join('/') + " " +
pad(d.getHours()) + ":" +
pad(d.getMinutes());
}
// In this example the code returns the correct date
var activity = {};
activity.startDate = '2017-07-02T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //start date 07/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Tue Aug 01 2017 00:00:00 GMT-0700 (Pacific Daylight Time) also 1 day off
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns
correct date 01/08/2017
Your issue is that you start with a valid ISO 8601 formatted string, '2017-07-02T00:00:00-08:00' but then reformat it into your own format in your own timezone (something like '02/07/2017 00:00' if your timezone is -0800), then parse that with the Date constructor, which is a very bad idea. It's likely treated as 7 February so I don't know how you can say it returns the correct date when you started with 2 July. And adding 1 month should be 2 August, not 1 August (though you did add 30 days rather than 1 month). Lastly, if you cross a daylight saving boundary, you may lose or pick up an hour so the date may be 23:00 the day before or go from 00:00 to 01:00.
Note that you have:
07/02/2017 00:00 d/m/yyy
^^^^^^^
which is not 2 July, it's 7 February.
The rest of your issues are similar.
Anyhow, if you're happy with using a library, fine. Just thought I'd point out where you'd gone wrong.
Here's your code adapted so it runs here, showing the errors:
function GetDateSchedulerFormatted(date) {
function pad(s) {
return (s < 10) ? '0' + s : s;
}
var d = new Date(date);
// yyy-MM-dd
return [pad(d.getDate()),
pad(d.getMonth() + 1),
d.getFullYear()
].join('/') + " " +
pad(d.getHours()) + ":" +
pad(d.getMinutes());
}
// In this example the code returns the correct date
var activity = {};
activity.startDate = '2017-07-02T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //start date 07/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Tue Aug 01 2017 00:00:00 GMT-0700 (Pacific Daylight Time) also 1 day off
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns correct date 01/08/2017 00: 00 d / m / yyyy
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// In this next example it returns the date 1 year off
activity.startDate = '2016-12-12T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 12/12/2016 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Jan 11 2017 00:00:00 GMT-0800 1 month ahead
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 11/01/2017 00:0 d/m/yyy
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// In this example the same exact date is returned
activity.startDate = '2017-02-01T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 01/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns Wed Feb 01 2017 00:00:00 GMT-0800
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns 01/02/2017 00:00 the same date, it 's not 30 days ahead
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
// Then in this final example I get NaN / NaN / NaN NaN: NaN
activity.startDate = '2017-02-25T00:00:00-08:00';
var startDate = GetDateSchedulerFormatted(activity.startDate); //returns 25/02/2017 00:00 d/m/yyy
var newDate = new Date(startDate); // returns invalid date
var endDate = GetDateSchedulerFormatted(new Date(newDate.setTime(newDate.getTime() + 30 * 86400000))); //returns NaN/NaN/NaN NaN:NaN
console.log('activity.startDate: ' + activity.startDate +
'\nstartDate : ' + startDate +
'\nnewDate : ' + GetDateSchedulerFormatted(newDate) +
'\nendDate : ' + endDate);
Thanks To Jordan S and zzzzBov for the help. I decided to go with moment.js
a code snippet of how I returned the correct dates
var startDate = moment(activity.startDate);
var endDate = moment(activity.startDate);
endDate = endDate.clone().add(1, 'months').calendar();
endDate = moment(endDate);
startDate = startDate._d;
endDate = endDate._d;
The moment() function returned the moment date object.
You have to .clone() the object to add to it correctly, also .calendar() returned a different format DD/MM/YYYY.
And finally the variable _d refered to the date object generated from the library.
I want to convert my local time (shown below) to UTC. Local time can belong to any timezone which a user belongs to. I just want to convert it to UTC format.
Local Time : '2015-12-04 19:05:48'
How do I achieve this requirement in JavaScript or AngularJS?
Update
My Original date/time string as like this "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)" and I have converted them to "2016-03-28 23:59:59 CDT" as requested date format. But again, I need to convert this interim output in to UTC in the same interim output format "YYYY-MM-DD HH:MM:SS". How do I achieve this
You can try this.
fiddle: https://jsfiddle.net/shuNaka/v891skuh/
const datetime = "2020-02-12 10:30:00";
const timezone = "Asia/Tokyo";
document.getElementById("localtime").innerHTML = datetime;
document.getElementById("timezone").innerHTML = timezone;
document.getElementById("utctime").innerHTML = getUtcFromLocaltime(datetime, timezone);
function getUtcFromLocaltime (localtimeString, timezone) {
// Change it to moment object
const localTime = moment(localtimeString, 'YYYY-MM-DD HH:mm:ss', true);
// Get the timezone
const timeDiff = moment().tz(timezone).format('ZZ')
// Get the time difference
let numTimeDiff = Number(timeDiff.substr(1)) / 100;
numTimeDiff = hourAdjust(numTimeDiff);
// Get UTC from the timezone(+0900)
if (timeDiff.charAt(0) === '+') {
return localTime.subtract({hours: numTimeDiff}).format('YYYY-MM-DD HH:mm:ss');
} else if (timeDiff.charAt(0) === '-') {
return localTime.add({hours: numTimeDiff}).format('YYYY-MM-DD HH:mm:ss');
}
}
function hourAdjust (hour) {
let mhour = Math.floor(hour);
let min = (Math.floor(hour * 100) % 100) / 6;
return Number(mhour+"."+min);
}
You can create a new local date based on the UTC values of the original (local) date.
var localDate = parseDate('2015-12-04 19:05:48 CDT'); // With or without CDT (still works)
document.body.innerHTML = [
'- Local Time: ' + formatDate(localDate),
'- UTC Time: ' + formatDate(localDateToUTC(localDate))
].join('\n');
function parseDate(dateString) {
var tokens = dateString.split(/[-: ]/g).slice(0, 6).map(function(token) { return parseInt(token, 10); });
tokens[1] -= 1; // Subtract 1 from month.
return newInstance(Date, tokens);
}
function formatDate(date) {
function pad(val, pattern) { return (pattern + val).substr(-pattern.length); }
return date.getFullYear() + '-' + pad(date.getMonth() + 1, '00') + '-' + pad(date.getDate(), '00') + ' ' +
pad(date.getHours(), '00') + ':' + pad(date.getMinutes(), '00') + ':' + pad(date.getSeconds(), '00');
}
function localDateToUTC(localDate) {
return new Date(localDate.getUTCFullYear(), localDate.getUTCMonth(), localDate.getUTCDate(),
localDate.getUTCHours(), localDate.getUTCMinutes(), localDate.getUTCSeconds());
}
function newInstance(clazz, arguments, scope) {
return new (Function.prototype.bind.apply(clazz, [scope].concat(arguments)));
}
body {
font-family: monospace;
white-space: pre;
}
The first step is to parse your original string. Do not remove the timezone offset since timezone names are not standardised, nor are their abbreviations. To parse "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)" you can use a function like the following.
You can then format a string based on the date, but you must keep the timezone as a string like "2016-03-29 05:59:59" will be treated as local by any implementation that is vaguely consistent with ISO 8601.
In most cases, "2016-03-29 05:59:59Z" will be treated as UTC as the joining "T" can be omitted by agreement (per ISO 8601).
// Parse date string in format:
// "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)"
function parseDate(s) {
var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,
jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
var b = s.split(/[\s:]/);
// Calc offset in minutes
// JS offsets are opposite sense to everyone else
var offset = (b[8] < 0? 1 : -1) * (b[8].slice(1,3)*60 + +b[8].slice(-2));
// Create UTC date
return new Date(Date.UTC(b[3], months[b[1].toLowerCase().substr(0,3)],
b[2], b[4], +b[5] + offset, b[6]));
}
// Format date as yyyy-mm-dd hh:mm:ssZ
// The timezone really should be included as this string will
// be treated as local if ISO 8601 rules are used (and the commonly are)
function formatDate(d) {
function z(n){return (n<10?'0':'')+n}
return d.getUTCFullYear() + '-' +
z(d.getUTCMonth() + 1) + '-' +
z(d.getUTCDate()) + ' ' +
z(d.getUTCHours()) + ':' +
z(d.getUTCMinutes()) + ':' +
z(d.getUTCSeconds()) + 'Z';
}
var s = 'Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)';
var d = parseDate(s);
document.write('<br>Original: ' + s + '<br>' +
'Local : ' + d + '<br>' +
'UTC : ' + formatDate(d) + '<br>' +
'ISO 8601: ' + d.toISOString());
body {
font-family: courier, monospace;
font-size: 75%;
white-space: pre;
}
I am trying to add days to a given date using Javascript. I have the following code:
function onChange(e) {
var datepicker = $("#DatePicker").val();
alert(datepicker);
var joindate = new Date(datepicker);
alert(joindate);
var numberOfDaysToAdd = 1;
joindate.setDate(joindate + numberOfDaysToAdd);
var dd = joindate.getDate();
var mm = joindate.getMonth() + 1;
var y = joindate.getFullYear();
var joinFormattedDate = dd + '/' + mm + '/' + y;
$('.new').val(joinFormattedDate);
}
On first alert I get the date 24/06/2011 but on second alert I get Thu Dec 06 2012 00:00:00 GMT+0500 (Pakistan Standard Time) which is wrong I want it to remain 24/06/2011 so that I can add days to it. In my code I want my final output to be 25/06/2011.
Fiddle is # http://jsfiddle.net/tassadaque/rEe4v/
Date('string') will attempt to parse the string as m/d/yyyy. The string 24/06/2011 thus becomes Dec 6, 2012. Reason: 24 is treated as a month... 1 => January 2011, 13 => January 2012 hence 24 => December 2012. I hope you understand what I mean. So:
var dmy = "24/06/2011".split("/"); // "24/06/2011" should be pulled from $("#DatePicker").val() instead
var joindate = new Date(
parseInt(dmy[2], 10),
parseInt(dmy[1], 10) - 1,
parseInt(dmy[0], 10)
);
alert(joindate); // Fri Jun 24 2011 00:00:00 GMT+0500 (West Asia Standard Time)
joindate.setDate(joindate.getDate() + 1); // substitute 1 with actual number of days to add
alert(joindate); // Sat Jun 25 2011 00:00:00 GMT+0500 (West Asia Standard Time)
alert(
("0" + joindate.getDate()).slice(-2) + "/" +
("0" + (joindate.getMonth() + 1)).slice(-2) + "/" +
joindate.getFullYear()
);
Demo here
I would like to encourage you to use DateJS library. It is really awesome!
function onChange(e) {
var date = Date.parse($("#DatePicker").val()); //You might want to tweak this to as per your needs.
var new_date = date.add(n).days();
$('.new').val(new_date.toString('M/d/yyyy'); //You might want to tweak this as per your needs as well.
}
Assuming numberOfDaysToAdd is a number:
joindate.setDate(joindate.getDate() + numberOfDaysToAdd);
The first alert is the value of the field. the second is the generated date from a non-US formatted date.
Here is a working example (seems that this kind of markup is necessary to get noticed)
If you want to keep your code, then you need to change
var joindate = new Date(datepicker);
to
var parms = datepicker.split("/");
then use
var joindate = new Date(parms[1]+"/"+parms[0]+"/"+parms[2]);
OR the identically working
var joindate = new Date(parms[2],parms[1]-1,parms[0]);
As pointed out in a few other answers too, use the .getDate()
joindate.setDate(joindate.getDate() + numberOfDaysToAdd);
Lastly you want to add a 0 if the month is < 10
if (mm<10) mm="0"+mm;
If you are using the datepicker from jQuery UI, then you can do
$('.new').val($("#DatePicker").datepicker( "setDate" , +1 ).val());
instead of your function
http://jqueryui.com/demos/datepicker/#method-setDate
Sets the current date for the
datepicker. The new date may be a Date
object or a string in the current date
format (e.g. '01/26/2009'), a number
of days from today (e.g. +7) or a
string of values and periods ('y' for
years, 'm' for months, 'w' for weeks,
'd' for days, e.g. '+1m +7d'), or null
to clear the selected date.
Try
function onChange(e) {
var datepicker = $("#DatePicker").val();
alert(datepicker);
var parts = datepicker.split(/[^\d]/);
var joindate = new Date();
joindate.setFullYear(parts[2], parts[1]-1, parts[0]);
alert(joindate);
var numberOfDaysToAdd = 1;
joindate.setDate(joindate + numberOfDaysToAdd);
var dd = joindate.getDate();
var mm = joindate.getMonth() + 1;
var y = joindate.getFullYear();
var joinFormattedDate = dd + '/' + mm + '/' + y;
$('.new').val(joinFormattedDate);
}
I suppose the problem is JavaScript expects format MM/DD/YYYY not DD/MM/YYYY when passed into Date constructor.
To answer your real problem, I think your issue is that you're trying to parse the text-value of the DatePicker, when that's not in the right format for your locale.
Instead of .val(), use:
var joindate = $('#DatePicker').datepicker("getDate");
to get the underyling Date() object representing the selected date directly from jQuery.
This guarantees that the date object is correct regardless of the date format specified in the DatePicker or the current locale.
Then use:
joindate.setDate(joindate.getDate() + numberOfDaysToAdd);
to move it on.
Is it a typo round joindate.setDate(joindate + numberOfDaysToAdd)?
I tried this code, it seems ok to me
var joindate = new Date(2010, 5, 24);
alert(joindate);
var numberOfDaysToAdd = 1;
joindate.setDate(joindate.getDate() + numberOfDaysToAdd);
var dd = joindate.getDate();
var mm = joindate.getMonth() + 1;
var y = joindate.getFullYear();
var joinFormattedDate = dd + '/' + mm + '/' + y;
alert(joinFormattedDate);
Date.prototype.addDays = function(days) {
this.setDate(this.getDate() + days);
return this;
};
and in your javascript code you could call
var currentDate = new Date();
// to add 8 days to current date
currentDate.addDays(8);
function onChange(e) {
var datepicker = $("#DatePicker").val().split("/");
var joindate = new Date();
var numberOfDaysToAdd = 1;
joindate.setFullYear(parseInt(datepicker[2]), parseInt(datepicker[1])-1, parseInt(datepicker[0])+numberOfDaysToAdd);
$('.new').val(joindate);
}
http://jsfiddle.net/roberkules/k4GM5/
try this.
Date.prototype.addDay = function(numberOfDaysToAdd){
this.setTime(this.getTime() + (numberOfDaysToAdd * 86400000));
};
function onChange(e) {
var date = new Date(Date.parse($("#DatePicker").val()));
date.addDay(1);
var dd = date.getDate();
var mm = date.getMonth() + 1;
var y = date.getFullYear();
var joinFormattedDate = dd + '/' + mm + '/' + y;
$('.new').val(joinFormattedDate);
}