Javascript date backward - javascript

I'm trying to compute the date of the day before using:
var da = new Date('2016-11-25');
nda = new Date(da-86400000);
It seems to work well when printed out using:
document.write(nda);
The output is:
Thu Nov 24 2016 00:00:00 GMT+0000 (WET)
which is correct, but when I do:
document.write(nda.getFullYear()+"-"+nda.getMonth()+"-"+nda.getDay());
I get a wrong output:
2016-10-4
Any suggestion?

You need to do nda.getMonth() + 1.
Months start from 0 so in order to get the right number of the month you must add 1.
Also you need to use getDate() instead of getDay(). getDay will give you the day of the week, while getDate will give you the day of the month.
The end result would be:
nda.getFullYear() + "-" + (nda.getMonth() + 1) + "-" + nda.getDate()

var da = new Date('2016-11-25');
nda = new Date(da-86400000);
document.write((nda.getFullYear())+
"-"+(nda.getMonth()+1)+
"-"+(nda.getDate()));

Date.getMonth() returns the index of the month, which is 0-indexed (So 0 is January, and 11 is December). To correct for this, you add 1.
Date.getDay() returns the day of the week, which is also 0-indexed starting from Sunday (So 4 is Thursday).
Here, you would use Date.getDate() to get the day in the current month (Which is not 0-indexed).
var da = new Date('2016-11-25'),
nda = new Date(da-86400000);
document.write(nda.getFullYear() + "-" +
(nda.getMonth() + 1) + "-" +
nda.getDate());

There is a fundamental rule wiht parsing dates: do not use the Date constructor or Date.parse (they are equivalent for parsing) to parse date strings. Use a library with a parser or parse it yourself with a simple function.
When using:
var da = new Date('2016-11-25');
the date will be treated as UTC, so if you are in a timezone that is west of Greenwich the local date will be the day before. Note the differences in the following:
console.log('Built-in parse: ' + new Date('2016-11-25').toLocaleString());
console.log('No parse : ' + new Date(2016, 10, 25).toLocaleString());
When you do:
nda.getFullYear()+"-"+nda.getMonth()+"-"+nda.getDay();
as others have said, you should use nda.getMonth() + 1, and you want getDate rather than getDay. However, since you are parsing the date as UTC then getting local values, the previous issue with UTC may mean that the date is one day previous.
To construct a date in the local time zone and avoid parsing errors, set the values directly.
To get the day before any date, simply subtract one day. Don't subtract 24 hours or you'll then get errors over daylight saving boundaries (since those days aren't exactly 24 hours long). e.g.:
/* Format a date as yyyy-mm-dd
** #param {Date} date
** #returns {string}
*/
function formatDate(date) {
return date.getFullYear() + '-' +
('0' + (date.getMonth() + 1)).slice(-2) + '-' +
('0' + date.getDate()).slice(-2);
}
var nda = new Date(2016, 10, 25);
console.log('Created date: ' + formatDate(nda));
nda.setDate(nda.getDate() - 1);
console.log('Previous day: ' + formatDate(nda));

Related

Convert date with full month name and time to ISO date

I have a date and time stamp in the format 02 December 2016 18:00pm.
This is generated by jQuery selector:
"datestamp": $('span.article_info__published').text(),
How can I convert it to the format 2007-07-24T12:50:00+01:00?
If possible, I'd like to do it on the same line. Otherwise it needs to accommodate this sort of construction...
result = {
"other": $('div.article__header h1').text(),
"datestamp": $('span.article_info__published').text(),
"more": $('meta[name="twitter:image"]').attr("content"),
"assorted": $('figcaption.caption').text(),
};
(I can't remember the name of the destination format... I think ISO 8601?)
Update: the following returns "invalid date"...
var myDate = new Date("02 December 2016 18:00pm");
document.write(myDate);
You need to firstly parse the string to get its components. You can then either generate a Date and use its methods to generate a suitable string, or you can manually reformat the string. Both approaches are very similar.
It's not clear to me why you want the timezone offset. You can get that independently, but if you just transfer all dates as UTC and ISO 8601 then you can just adopt the host timezone offset. If UTC is OK, then you just need to parse to a Date and use toISOString.
It's unusual to specify the time as "18:00pm", the pm part is redundant. Typically it would be specified as "1800hrs", "18:00" or "6:00 pm".
// Reformat string, using Date object for
// host timezone offset only
function reformatDate(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
// Host timezone offset for given date and time
var tzOffset = new Date(b[2], monNum - 1, b[0], b[3], b[4]).getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return b[2] + '-' +
z(monNum) + '-' +
b[0] + 'T' +
b[3] + ':' +
b[4] + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
// Reformat string using Date object for
// parts and host timezone offset
function reformatDate2(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
var d = new Date(b[2], monNum - 1, b[0], b[3], b[4]);
// Host timezone offset for given date and time
var tzOffset = d.getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return d.getFullYear() + '-' +
z(d.getMonth() + 1) + '-' +
z(d.getDate()) + 'T' +
z(d.getHours()) + ':' +
z(d.getMinutes()) + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
var s = '02 December 2016 18:00pm';
console.log(reformatDate(s));
console.log(reformatDate2(s));
As you can see, you're really only using a Date to get the timezone offset, the rest of the values can be used as-is except for the month, which must be converted to a number in both cases.
There are also a number of libraries that can help with parsing and formatting strings, such as moment.js (large, widely used, fully functional) and fecha.js (small and functional parser/formatter). In both cases you can parse the string and format it however you wish, e.g. using fecha.js:
var s = '02 December 2016 18:00pm';
// Create a Date
var d = fecha.parse(s, 'DD MMMM YYYY HH:mm');
// Format string
console.log(fecha.format(d, 'YYYY-MM-DDTHH:mmZZ'));
The parse and format can be one statement, but it's clearer as 2. With moment.js (which has better support for chaining methods):
moment(s, 'DD MMMM YYYY HH:mm').format('YYYY-MM-DDTHH:mmZZ');
For the string to be interpretable as a date for conversion, I needed to remove the time "pm" from the back of the string first.
var date = "02 December 2016 18:00pm"
date = date.slice(0, -2);
var myDate = new Date(date);
document.write(myDate);

Set value of input type date bug

I have 2 fields input and output dates. On certain conditions I set the endDate to be 1 year ahead of start date.
<input type='date' id='endDate'>
$("#startDate").change(function(){
var endDate = new Date($("#startDate").val());
endDate.setMonth(endDate.getMonth() + 1);
endDate.setFullYear(endDate.getFullYear() + 1);
var myDay = ("0" + endDate.getDate()).slice(-2);
var myMonth = ("0" + endDate.getMonth()).slice(-2);
$("#endDate").val(endDate.getFullYear() + '-' + myMonth + '-' + myDay);
}
The issue when I set the start date to 2-29-2016
I got the following error:
The specified value "2017-02-29" does not conform to the required
format, "yyyy-MM-dd".
I expected the Date() function to take care of it. Apparently, they don't. Is this a bug?
Is their anyway faster than adding a bunch of if statements?
The specified value "2017-02-29" does not conform to the required
format, "yyyy-MM-dd".
2017-02-29 is not a valid date. 29th feb of next year (2017) is not possible.
Only leap years have february Month of 29.
Try 2016-02-29 instead.
Is their anyway faster than adding a bunch of if statements?
No need to add bunch of if statements, you can use this answer
function leapYear(year)
{
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
For answering your question, if you set the date explicitly like "2017-02-29" then it will throw an error.
Just make changes in the date object itself and apply that date object to the input by
$("#endDate").val( endDate.toJSON().slice(0,10) );
Now it should take care of rolling over to next month.
Edit (based on TJ's comment)
Leap years occur every year that is evenly divisible by 4 except ones evenly divisible by 100 (which are not leap years), except ones evenly divisible by 400 (which are leap years).
The real problem here is that you've used the value of getMonth without adding 1 to it. The value from getMonth starts at 0 (January), but month values in your yyyy-MM-dd format start with 1.
So:
var myMonth = ("0" + (endDate.getMonth() + 1)).slice(-2);
// Note -------------^------------------^^^^^
That's how you ended up with an invalid string, 2017-02-29, despite having used the Date object, which will indeed ensure it only gives you valid dates. The Date object contained the date March 29th, not February 29th.
However:
On certain conditions I set the endDate to be 1 year ahead of start date.
Your code doesn't do that. It adds a year and a month, not just a year:
endDate.setMonth(endDate.getMonth() + 1); // <== Changing month
endDate.setFullYear(endDate.getFullYear() + 1);
If you only want to add a year, remove the first of those two lines. That, combined, with the correction to how you're using getMonth when forming the string, will reliably add a year to the date (with possible month rollover).
So:
$("#startDate").change(function(){
var endDate = new Date($("#startDate").val());
endDate.setFullYear(endDate.getFullYear() + 1);
var myDay = ("0" + endDate.getDate()).slice(-2);
var myMonth = ("0" + (endDate.getMonth() + 1)).slice(-2);
$("#endDate").val(endDate.getFullYear() + '-' + myMonth + '-' + myDay);
});

Javascript Date inconsistency

On my node server, I receive time value from the client in epoch format (milliseconds since Jan 1 1970). I feed it into the Date() object and print it like so:
var d = new Date(epochTime);
var year = d.getFullYear();
var mo = d.getMonth();
var day = d.getDay();
console.log("ISO:" + d.toISOString() + " year:" + year + " mo:" + mo + " day:" + day);
Now, I get weird inconsistency from the date object.
E.g. for the value of "1437386620207.58" - this is what above console.log prints:
ISO:2015-07-20T10:03:40.207Z year:2015 mo:6 day:1
Huh? Why are those dates so different?
Two problems in your code:
Months are zero-based in Javascript, i.e. 0 is January and 11 is December.
getDay() returns the day of the week. That should be getDate() instead to return the day of the month.

How to add weeks to date using javascript?

Javascript definitely isn't my strongest point. I've been attempting this for a couple of hours now and seem to be getting stuck with date formatting somewhere.
I have a form where a user selected a date (dd/mm/yyyy) and then this date will be taken and 2 weeks will be added to it and then date will be copied to another form field.
My latest attempt below isn't even adding a date yet just copying the selected date in one form field to another, if I select '03/02/2012', it outputs 'Fri Mar 02 2012 00:00:00 GMT+0000 (GMT Standard Time)', so its outputting in American format as well as the full date. How to I get it to out put in the same format and add 2 weeks?
function LicenceToOccupy(acceptCompletionDate)
{
var date1 = new Date(acceptCompletionDate);
document.frmAccept.acceptLicence.value = date1;
}
You can do this :
const numWeeks = 2;
const now = new Date();
now.setDate(now.getDate() + numWeeks * 7);
or as a function
const addWeeksToDate = (dateObj,numberOfWeeks) => {
dateObj.setDate(dateObj.getDate()+ numberOfWeeks * 7);
return dateObj;
}
const numberOfWeeks = 2
console.log(addWeeksToDate(new Date(), 2).toISOString());
You can see the fiddle here.
According to the documentation in MDN
The setDate() method sets the day of the Date object relative to the beginning of the currently set month.
This might not answer the question per se, but one can find a solution with these formulas.
6.048e+8 = 1 week in milliseconds
Date.now() = Now in milliseconds
Date.now() + 6.048e+8 = 1 week from today
Date.now() + (6.048e+8 * 2) = 2 weeks from today
new Date( Date.now() + (6.048e+8 * 2) ) = Date Object for 2 weeks from today
You're assigning date1 to be a Date object which represents the string you pass it. What you're seeing in the acceptLicense value is the toString() representation of the date object (try alert(date1.toString()) to see this).
To output as you want, you'll have to use string concatenation and the various Date methods.
var formattedDate = date1.getDate() + '/' + (date1.getMonth() + 1) + '/' + date1.getFullYear();
In terms of adding 2 weeks, you should add 14 days to the current date;
date1.setDate(date.getDate() + 14);
... this will automatically handle the month increase etc.
In the end, you'll end up with;
var date1 = new Date(acceptCompletionDate);
date1.setDate(date1.getDate() + 14);
document.frmAccept.acceptLicence.value = date1.getDate() + '/' + (date1.getMonth() + 1) + '/' + date1.getFullYear();
N.B Months in JavaScript are 0-indexed (Jan = 0, Dec = 11), hence the +1 on the month.
Edit: To address your comment, you should construct date as follows instead, as the Date argument is supposed to be "A string representing an RFC2822 or ISO 8601 date." (see here).
var segments = acceptCompletionDate.split("/");
var date1 = new Date(segments[2], segments[1], segments[0]);
This should do what you're looking for.
function LicenceToOccupy(acceptCompletionDate)
{
var date1 = new Date(acceptCompletionDate);
date1.setDate(date1.getDate() + 14);
document.frmAccept.acceptLicence.value = date1.getDate() + '/' + (date1.getMonth() + 1) + '/' + date1.getFullYear();
}
To parse the specific dd/mm/yyyy format and increment days with 14 , you can do something like split the parts, and create the date object with y/m/d given specfically. (incrementing the days right away) Providing the separator is always -, the following should work:
function LicenceToOccupy(acceptCompletionDate)
{
var parts = acceptCompletionDate.split("/");
var date1 = new Date(parts[2], (parts[1] - 1), parseInt(parts[0]) + 14); //month 0 based, day: parse to int and increment 14 (2 weeks)
document.frmAccept.acceptLicence.value = date1.toLocaleDateString(); //if the d/m/y format is the local string, otherwise some cusom formatting needs to be done
}
date1.toLocaleDateString()
Thiswill return you date1 as a String in the client convention
To create a new date date2 with 2 weeks more (2weeks = 27246060 seconds):
var date2 = new Date(date1 + 60*60*24*7*2);

Javascript getDate problem

I have a very weird problem with javascript's getDate function. At the start of some function, i've created a Date object using:
var day = new Date(date);
in which date is a unix timestamp.
I dont change the day object, but after a while I try to get the day of the month of this object, but day.getDate() keeps giving me the wrong value.
For example:
alert(day.getTime() + "-" + day.getDate() + "-"+ day.getMonth() +"-" + day.getFullYear() + "-" + day.getHours() + "-" + day.getMinutes() + "-" + day.getSeconds());
gives me the following result: 1290297600-15-0-1970-23-24-57
and at some other point the result is: 1290384000-15-0-1970-23-26-24
And this is the weird part, if you lookup the unixtimestamp 1290297600 you'll see that that's the timestamp for the 21st of november 2010 at 00:00:00 gmt (1290384000 is the next day, same time)
The timestamps are correct, but i cant make sense of the dates it gives me.
This happens to me in any browser.
What am i doing wrong?
The issue here is that the Date object in JavaScript doesn't take the Unix timestamp (seconds since the epoch), it actually takes the milliseconds since the epoch. If you just multiply your date variable by 1000 then you get the correct output.
Example here
Time = Unix timestamp format. I added 64800 second to the time so it would be converted to Mountain Standard Time.
*timestamp 24 * 60 * 60
.getTime()//milliseconds 24 * 60 * 60 * 1000
private DateField dateField1; ///////////////////////
dateField1= new DateField("Date:", DateField.DATE); f.append(dateField1);
Date d = new Date(); dateField1.setDate(d);
String TimeSeg = String.valueOf(((dateField1.getDate().getTime()/1000)+64800));

Categories

Resources