Javascript date validation - prefixing 19 (century) to two digit date - javascript

I am doing some validations with Date() and I have noticed that if I create a invalid date with a two digit year instead of four Date(01/01/55) then the current century will be prefixed onto the year - 55 becomes 1955 - instead of a invalid date object that I can test with NaN.
This is a problem because I allow users to enter dates without any '/', then I create the date using substr:
// Check date is in correct format
var fDate = val.split('/');
// Should have 3 parts
if (fDate.length != 3) {
var day = val.substr(0, 2);
var month = val.substr(2, 2);
var year = val.substr(4, 4);
val = day + '/' + month + '/' + year;
control.val(val);
}
So if the user enters 010155 my logic turns it into 01/01/55 then Date() creates the date 01/01/1955, but instead I want it to create an invalid date object.

Okay well I developed a solution that does what I'm happy with. momentjs.com seems great, and I probably could of used it, but I am using the jqueryui.com Datepicker which uses Date and I want the use to be able to enter dates with no year, 1 or 2 number years, which defaults to the beginning of this century.
var cYear = new Date().getFullYear();
var c = cYear.toString().substr(0, 2);
day = val.substr(0, 2);
if (day > 31) {
leftOverD = day.charAt(1);
day = "0" + day.charAt(0);
} else if (day.length == 1) {
day = "0" + day;
} else if (day.length == 0) {
day = "01";
}
month = (leftOverD) ? leftOverD + val.charAt(2) : val.substr(2, 2);
if (month > 12) {
leftOverM = month.charAt(1);
month = "0" + month.charAt(0);
} else if (month.length == 1) {
month = "0" + month;
} else if (month.length == 0) {
month = "01";
}
var strYear;
if (leftOverD && leftOverM) {
strYear = val.substr(2, 4);
} else if (leftOverD || leftOverM) {
strYear = val.substr(3, 4);
} else if (!leftOverD && !leftOverM) {
strYear = val.substr(4, 4);
}
year = strYear;
if (year.length == 0) {
year = c + "00";
} else if (year.length == 1) {
var nYear = c + '0' + year;
if (nYear > cYear)
nYear = (c - 1) + '0' + year
year = nYear;
} else if (year.length == 2) {
var nYear = c + year;
if (nYear > cYear)
nYear = (c - 1) + year
year = nYear;
}
ps. Working with dates in JS is a nightmare. Why not simply have a Date() constructor that accepts a culture?

Related

How to write a method which gives me future date time in format YYYY/MM/DD 12:30:50

I have written below method for this but it will fail when the current date will be 31.
I need to check if date is 31 it should return me 1st date of next month. Any help would be appreciated
getFutureDateTime: function () {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate() + 1;// to get current date remove "+1"
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
if (month.toString().length == 1) {
month = '0' + month;
}
if (day.toString().length == 1) {
day = '0' + day;
}
if (hour.toString().length == 1) {
hour = '0' + hour;
}
if (minute.toString().length == 1) {
minute = '0' + minute;
}
if (second.toString().length == 1) {
second = '0' + second;
}
var dateTime = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
return dateTime;
},
It looks like you're trying to get the next day as a string. Your best bet is to let the Date object do the rollover between months and years for you, like this:
getFutureDateTime: function () {
var dt = new Date();
dt.setDate(dt.getDate() + 1); // Will handle rollover for you
var year = dt.getFullYear();
var month = dt.getMonth() + 1;
var day = dt.getDate();
var hour = dt.getHours();
var minute = dt.getMinutes();
var second = dt.getSeconds();
if (month.toString().length == 1) {
month = '0' + month;
}
if (day.toString().length == 1) {
day = '0' + day;
}
if (hour.toString().length == 1) {
hour = '0' + hour;
}
if (minute.toString().length == 1) {
minute = '0' + minute;
}
if (second.toString().length == 1) {
second = '0' + second;
}
var dateTime = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
return dateTime;
},
Note that if you're doing this in any vaguely modern environment, you can use padStart on the string (and padStart is easily polyfilled):
getFutureDateTime: function () {
var dt = new Date();
dt.setDate(dt.getDate() + 1); // Will handle rollover for you
var dateTime =
year.toString().padStart(2, "0") +
"/" +
month.toString().padStart(2, "0") +
"/" +
day.toString().padStart(2, "0") +
" " +
hour.toString().padStart(2, "0") +
":" +
minute.toString().padStart(2, "0") +
":" +
second.toString().padStart(2, "0");
return dateTime;
},
You could give yourself a utility function for the padding, to avoid repeating yourself:
function padZero2(val) {
return String(val).padStart(2, "0");
}
// ...
getFutureDateTime: function () {
var dt = new Date();
dt.setDate(dt.getDate() + 1); // Will handle rollover for you
var dateTime =
padZero2(year) +
"/" +
padZero2(month) +
"/" +
padZero2(day) +
" " +
padZero2(hour) +
":" +
padZero2(minute) +
":" +
padZero2(second);
return dateTime;
},
Similarly, if you use an ES2015 template literal, it may be a bit clearer:
getFutureDateTime: function () {
const dt = new Date();
dt.setDate(dt.getDate() + 1); // Will handle rollover for you
const dateTime = `${padZero2(year)}/${padZero2(month)}/${padZero2(day)} ${padZero2(hour)}:${padZero2(minute)}:${padZero2(second)}`;
return dateTime;
},
You don't need to have that complex function, look at this:
function getFutureDateTime() {
const regex = /(^[0-9-]+)(t)([^Z.]+)/i;
const date = new Date();
const isoFutureDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).toISOString();
const matches = iso.match(regex);
return matches[1] + ' ' + matches[3];
}
m= require("moment")
console.log(m().add("months",2).format("YYYY/MM/DD HH:MM:SS"))
use momentjs why to reinvent wheel when you already have some nodejs library for that you can change months to days , years etc to add days,houts,years etc instead of month
https://momentjs.com/guides/#/warnings/add-inverted-param/
You sould probably add an if statement before adding the '0' to test if day==32 => day = 1 and month = month+1
getFutureDateTime: function () {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate() + 1;// to get current date remove "+1"
if (day==32){
day = 1;
month = month + 1;
}
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
if (month.toString().length == 1) {
month = '0' + month;
}
if (day.toString().length == 1) {
day = '0' + day;
}
if (hour.toString().length == 1) {
hour = '0' + hour;
}
if (minute.toString().length == 1) {
minute = '0' + minute;
}
if (second.toString().length == 1) {
second = '0' + second;
}
var dateTime = year + '/' + month + '/' + day + ' ' + hour + ':' + minute + ':' + second;
return dateTime;
},

Add future days to Javascript excluding on sunday

I have the following javascript code that allows a user to only select four days in future from today's date.
$(function() {
var dtToday = new Date();
var month = dtToday.getMonth() + 1;
if (dtToday.getDay() === 0) {
var day = dtToday.getDate() + 5;
} else {
var day = dtToday.getDate() + 4;
}
var year = dtToday.getFullYear();
if (month < 10)
month = '0' + month.toString();
if (day < 10)
day = '0' + day.toString();
var maxDate = year + '-' + month + '-' + day;
$('.datepicker').attr('max', maxDate);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I would like the code to skip Sunday while incrementing the future days by four. I have tried using if statements but they only check if today's date is sunday while i would like to achieve a situation whereby if any of the future 4 days is Sunday, it should skip it.
Thanks
If today is Wednesday (3), Thursday (4), Friday (5), or Saturday (6), then your 4-day window would include Sunday (hence you should add 1 to days).
So do this:
var day = dtToday.getDate() + 4;
if(dtToday.getDay() > 2) {
day += 1;
}
So your script would be:
$(function(){
var dtToday = new Date();
var month = dtToday.getMonth() + 1;
var day = dtToday.getDate() + 4;
if(dtToday.getDay() > 2) {
day += 1;
}
var year = dtToday.getFullYear();
if(month < 10)
month = '0' + month.toString();
if(day < 10)
day = '0' + day.toString();
var maxDate = year + '-' + month + '-' + day;
$('.datepicker').attr('max', maxDate);
});

Javascript increment and decrement YYYY-MM-DD by 1 day

I got this from another stack question
incr_date(date_str){
let parts = date_str.split("-");
let dt = new Date(
parseInt(parts[0], 10), // year
parseInt(parts[1], 10) - 1, // month (starts with 0)
parseInt(parts[2], 10) // date
);
dt.setDate(dt.getDate() + 1);
parts[0] = "" + dt.getFullYear();
parts[1] = "" + (dt.getMonth() + 1);
if (parts[1].length < 2) {
parts[1] = "0" + parts[1];
}
parts[2] = "" + dt.getDate();
if (parts[2].length < 2) {
parts[2] = "0" + parts[2];
}
return parts.join("-");
}
It works but how can I convert this function to decrement the date instead of increment?
I'm doing this on a react native component so I dont want to import any javascript libraries like moment.js
function dateAdd(dte){
var date = new Date(dte);
date.setDate(date.getDate() + 1);
console.log("add one day= "+date)
}
function datesub(dte){
var date = new Date(dte);
date.setDate(date.getDate() - 1);
console.log("minus one day = "+ date)
}
dateAdd("01-01-2017")
datesub("01-01-2017")
I'd convert the string to Javascript understandable format, increment a day and convert it back to user understandable format. I'm using the flag(Boolean) to determine weather to Increment the date and vice versa.
var convertDate = function(dt, flag) {
var dateArr = dt.split('-');
var tempDate = new Date();
var mm = dateArr[1] - 1; //Javascript considers 0 as Jan
tempDate.setFullYear(dateArr[0]);
tempDate.setMonth(mm);
tempDate.setDate(dateArr[2]);
if (flag) {
tempDate.setDate(tempDate.getDate(dateArr[2]) + 1);//Add's one day
} else {
tempDate.setDate(tempDate.getDate(dateArr[2]) - 1);//Sub's one day
}
var userFriendlyMonth = (Number(tempDate.getMonth()) + 1); //user considers 1 as Jan
return tempDate.getFullYear() + '-' + userFriendlyMonth + '-' + tempDate.getDate();
}
document.getElementById("increment").innerHTML = convertDate('2018-11-30', true);
document.getElementById("decrement").innerHTML = convertDate('2018-11-30', false);
<div>Increment: <span id="increment"></span></div>
<div>Decrement: <span id="decrement"></span></div>

Javascript time and date change by timezone difference in hours

I have this code, which is to change the time and date - according to timezone difference for example 5 hours (indicated by /////TIME ZONE DIFFERECEN/////), but it is not working how i would expect it to run; e.g: not changing the date and time when applicable. Can anyone help.
var dateObj = new Date();
var month = dateObj.getUTCMonth() + 1; //months from 1-12
var day = dateObj.getUTCDate();
var year = dateObj.getUTCFullYear();
var months = ["31"];
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
months.push("29");
} else {
months.push("28");
}
monthsappend = ["31", "30", "31", "30", "31", "31", "30", "31", "20", "31"];
months.concat(monthsappend);
time = "7:00pm";
var hours = Number(time.match(/^(\d+)/)[1]);
var minutes = Number(time.match(/:(\d+)/)[1]);
var AMPM = time.match(/\s?([AaPp][Mm]?)$/)[1];
var pm = ['P', 'p', 'PM', 'pM', 'pm', 'Pm'];
var am = ['A', 'a', 'AM', 'aM', 'am', 'Am'];
if (pm.indexOf(AMPM) >= 0 && hours < 12) hours = hours + 12;
if (am.indexOf(AMPM) >= 0 && hours == 12) hours = hours - 12;
var sHours = hours.toString();
var sMinutes = minutes.toString();
if (hours < 10) sHours = "0" + sHours;
if (minutes < 10) sMinutes = "0" + sMinutes;
timearr = [sHours, sMinutes];
timearr[0] += 5;
/////////////////////////////// TIME ZONE DIFFERENCE////////////////////////////
if (time.toLowerCase().includes("pm")) {
}
if (timearr < 0) {
day -= 1;
if (day == 0) {
month -= 1;
if (month == 0) {
month = 12;
year = dateObj.getFullYear() - 1;
}
day = months[month - 1];
}
} else {
if (timearr => 24) {
timearr[0] = 24 - timearr[0];
if (day == months[month - 1]) {
day = 1;
month += 1;
if (month == 12) {
month = 1;
year += 1;
}
}
}
}
newdate = day + "/" + month + "/" + year;
console.log(newdate);
console.log(timearr[0]);
Well, first I'll point out the bugs:
You have an arrow function => instead of a greater-than-or-equal-to operator >= (Thanks RobG).
You treat timearr as both an array, and later as a single number. I think you meant to compare timearr[0].
When you add the 5 hours, you're concatenating strings. "19" + 5 === "195". You need to work with numbers here, not strings.
You forgot to adjust timearr[0] in the first section of the large if statement.
You have subtraction in opposite order when you adjust timearr[0] in the second section of the large if. (24 - 26 === -2, you probably meant 26 - 24 === 2).
At the end, you increment month += 1 before checking if (month == 12). Either that needs to be in an else, or you'd have to check for month === 13.
You're using == in places where === would be more appropriate.
You forgot var when you declared timearr.
You took the current date, but hard-coded the time.
Overall, it looks like you are trying to output the current date, in day/month/year format, at UTC+5. There are many simpler ways to do what you're asking. For example:
// Get the current moment in time, as a Date object.
var d = new Date();
// Add 5 hours of absolute duration. The setter handles the bubbling for you.
// Be sure to use UTC here, to avoid interference from transitions of the local time zone.
d.setUTCHours(d.getUTCHours() + 5);
// Get the properties we want to display.
var year = d.getUTCFullYear();
var month = d.getUTCMonth() + 1;
var day = d.getUTCDate();
// Construct the string for output in the desired format.
var s = day + '/' + month + '/' + year;
Or with Moment.js:
var s = moment().utcOffset(5).format('D/M/YYYY');
Do keep in mind also "Time Zone != Offset". It just so happens that all the places in the world that currently use UTC+5 use it year-round (ex, Pakistan) but if you were talking about US Eastern Time, it would be UTC-5 for some parts of the year, and UTC-4 for other parts of the year.

Date format change

I would like to change the date format in my code like that - > 19.7.2016
Could anyone help me, please?
function calcWorkingDays(fromDate, days) {
var count = 0;
var m = new Date();
while (count < days) {
fromDate.setDate(fromDate.getDate() + 1);
if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
count++;
}
return fromDate;
}
alert(calcWorkingDays(new Date(), 4));
You need to format the dateobject to your likeness:
Extract the Day, Month and Year from your DateObject:
var month = fromDate.getUTCMonth() + 1; //months from 1-12
//January=0, February=1, etc
var day = fromDate.getUTCDate();
var year = fromDate.getUTCFullYear();
newdate = day + "." + month + "." + year;
Complete Example:
function calcWorkingDays(fromDate, days) {
var count = 0;
var m = new Date();
while (count < days) {
fromDate.setDate(fromDate.getDate() + 1);
if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
count++;
}
var month = fromDate.getUTCMonth() + 1;
var day = fromDate.getUTCDate();
var year = fromDate.getUTCFullYear();
newdate = day + "." + month + "." + year;
return newdate;
}
alert(calcWorkingDays(new Date(), 4));
Other possible examples are:
new Date().toISOString()
"2016-02-18T23:59:48.039Z"
new Date().toISOString().split('T')[0];
"2016-02-18"
new Date().toISOString().replace('-', '/').split('T')[0].replace('-', '/');
"2016/02/18"
new Date().toLocaleString().split(',')[0]
"2/18/2016"
source
You should convert date to string:
function calcWorkingDays(fromDate, days) {
var count = 0;
var m = new Date();
while (count < days) {
fromDate.setDate(fromDate.getDate() + 1);
if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
count++;
}
return fromDate.getDate() + "." + (fromDate.getMonth()+1) + "." + fromDate.getFullYear();
}
alert(calcWorkingDays(new Date(), 4));

Categories