Javascript Parse Date Contract_End_Date - javascript

I have Contract_End_Date 2 version : 2020-1-1 and 2020-1-11
Result will be like: 2020-01-01 or 2020-01-11
What is solution here?
var updates = {};
var removes = {};
let Contract_End_Date = '2020-1-11';
if (typeof Contract_End_Date !== 'undefined' && Contract_End_Date != null) {
var arr = Contract_End_Date.split(" ");
if (arr.length == 2) {
var firstPart = arr[0];
var dateParts = firstPart.split("-");
if (dateParts.length == 3) {
var day = parseInt(dateParts[2]);
if (day < 10) {
day = "0" + day;
}
var month = parseInt(dateParts[1]);
if (month < 10) {
month = "0" + month;
}
var year = dateParts[0];
updates["Contract_End_Date"] = year + "-" + month + "-" + day;
}
}
}
console.log(updates);

For working with dates in JS, I can just recommend "Moment.js".
It makes your code much more simple and readable.
In your case:
let Contract_End_Date = '2020-1-11';
let formattedDate = moment(Contract_End_Date, 'YYYY-MM-DD').format('YYYY-MM-DD');
console.log(formattedDate);
// 2020-01-11
For more information: https://momentjs.com/
EDIT: Since Moment.js won't get updated with the newest features, it may be better to use other libaries like Luxon

Related

Count the number of anniversaries between two dates?

What is the easiest way in Javascript to calculate the number of anniversaries between two dates.
My attempt:
module.exports.countAnniversariesBetweenTwoDates = (start_date, end_date, anniversary_date) => {
if (start_date == end_date) {
return 0;
}
let start_date_year = start_date.getFullYear();
let end_date_year = end_date.getFullYear();
let anniversary_year = anniversary_date.getFullYear();
let start_date_month_and_day = Number(('0' + (start_date.getMonth() + 1)).slice(-2) + '' + ('0' + start_date.getDate()).slice(-2));
let end_date_month_and_day = Number(('0' + (end_date.getMonth() + 1)).slice(-2) + '' + ('0' + end_date.getDate()).slice(-2));
let anniversary_date_month_and_day = Number(('0' + (anniversary_date.getMonth() + 1)).slice(-2) + '' + ('0' + anniversary_date.getDate()).slice(-2));
let anniversary_count = 0;
// special case for start year
if (start_date_month_and_day < anniversary_date_month_and_day) {
anniversary_count++;
}
let temp_start_date_year = start_date_year + 1;
while(temp_start_date_year < end_date_year) {
anniversary_count++;
temp_start_date_year++;
}
// special case for end year
if (end_date_month_and_day > anniversary_date_month_and_day) {
anniversary_count++;
}
return anniversary_count;
}
Here's one that accounts for leap years:
function validDate(year, month, day) {
var testDate = new Date(year, month, day);
return testDate.getFullYear() === year && testDate.getMonth() === month && testDate.getDate() === day;
}
function countAnniversaries(begin, end, anniversary) {
var countDate = new Date(anniversary.getTime());
var anniversaries = 0;
var countYear = begin.getFullYear();
var anniversaryMonth = anniversary.getMonth();
var anniversaryDay = anniversary.getDate();
countDate.setFullYear(countYear);
while (countDate.getTime() <= end.getTime()) {
if (validDate(countYear, anniversaryMonth, anniversaryDay) && countDate.getTime() >= begin.getTime()) {
anniversaries++;
}
countYear++;
countDate.setFullYear(countYear);
countDate.setMonth(anniversaryMonth);
countDate.setDate(anniversaryDay);
}
return anniversaries;
}
console.log(countAnniversaries(new Date('Feb 1, 2012'), new Date('Feb 4, 2026'), new Date('Feb 2, 2012')))
console.log(countAnniversaries(new Date('Feb 1, 2012'), new Date('Feb 4, 2026'), new Date('Feb 29, 2012')))
If you use moment.js you can just get the difference between two dates as years, the use Math.floor() to round down to the nearest full number of years:
yearDiff = Math.floor(moment(new Date(endDate)).diff(new Date(startDate),'years'));
Edit: The code above can be simplified a bit more:
yearDiff = moment(endDate).diff(startDate,'years');
You may have to write some additional code to handle time periods of less than a year, or some other special cases.
You could of course loop through the dates similar to how you do it:
var startDate = "03/08/2019";
var endDate = "01/01/2022";
var anniversary = "03/07/2015";
var anniversaryCount = 0;
var counterMoment = moment(startDate);
while (counterMoment.isSameOrBefore(endDate)) {
var anniversaryThisYear = moment(anniversary).year(counterMoment.year());
if (counterMoment.isSame(anniversaryThisYear)) {
anniversaryCount++;
}
counterMoment.add(1,'day');
}
alert("Number of anniversaries: "+anniversaryCount);
It all depends on what the end result is and how you plan to use the value.

convert month-day-year into day-month-year using javascript

I'm trying to convert a MM/DD/YYYY date to a long date. So for example, 02/16/2020 would convert to something like 16/02/2020.
Is there a way to make this date conversion accurately?
You need to specify the original format of the time, and then convert it to a new format.
const date = "02/16/2020";
alert(moment(date, "MM/DD/YYYY").format('DD/MM/YYYY'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Use moment for date formatting:
Sample Code:
moment('02/16/2020').format('16/02/2020');
You can play with date by moment.js. It is very useful tool for javascript developer.
Momemet Js Document
For dynamic value:
moment(yourDate, 'MM/DD/YYYY').format('DD/MM/YYYY');
Here, yourDate is your dynamic value date.
check this. its work.
function formatDate(date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;
return [day,month,year].join('/');
}
document.getElementById('res').innerHTML = formatDate('02/16/2020') ;
<div id="res">res</div>
2 || 1 liners ?
var src = '02/16/2020'
var a = src.split('/');
console.log(a.concat(a.splice(0, 2)).join('/'));
console.log(src.replace(/(\d+)\/(\d+)\/(\d+)/, '$3/$1/$2'));
If you want a conversion just between the exact formats you have mentioned:
function dfConvert(f) {
var farr = f.split("/");
return `${farr[1]}/${farr[0]}/${farr[2]}`;
}
var input = "02/16/2020";
console.log(`input: ${input}`)
console.log(`output: ${dfConvert(input)}`);
If you want the actual date object and from that you want your mentioned format for some reason:
function toDate(f) {
var farr = f.split("/");
return new Date(parseInt(farr[2]), parseInt(farr[0])-1, parseInt(farr[1]))
}
function dfConvert(f) {
var d = toDate(f)
var day = d.getDate()
var month = (d.getMonth() + 1)
var year = d.getFullYear()
return `${((day.toString().length <= 1) ? "0": "")}${day}/${((month.toString().length <= 1) ? "0": "")}${month}/${year}`
}
var input = "02/16/2020"
console.log(`input: ${input}`)
console.log(`output: ${dfConvert(input)}`)
Hope it helps

Javascript add month to variable

I've a variable in Javascript such as:
var a = "2015/05/04";
How do I add/subtract months to the variable such as:
a.getMonths() + 1;
that will result in "2015/06/04"
I tried to do the getMonths() and the alert is not displaying the result.
At first you must include moment.js on your page:
var a = "2015/05/04";
var date = moment(a, "YYYY/MM/DD");
date.add(1, 'months')
var result = date.format("YYYY/MM/DD");+
alert(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/moment.js"></script>
Next, implement that algorithm. IMHO it the easiest and the most correct way.
Create a date object and add months as shown:
var a = new Date("2015/05/04");
a.setMonth(a.getMonth() + 1); // add months
a.setMonth(a.getMonth() - 2); // subtract months
Example:
var a = new Date("2015/05/04");
print();
a.setMonth(a.getMonth() + 1);
print();
a.setMonth(a.getMonth() - 2);
print();
function print() {
stdout.innerHTML += a.toISOString() + '\n';
}
<pre id="stdout"></pre>
If you don't want to or can't use moment.js, here's a plain javascript approach:
var a = "2015/05/04";
var dateparts = a.split("/");
var date = new Date(dateparts[0], dateparts[1], dateparts[2]);
date = new Date(date.setMonth(date.getMonth() + 1));
console.log(date.getFullYear() + '/' + date.getMonth() + '/' + date.getDate());
Have a look at Date, or easier Moment.js.
This may work out for you (https://jsfiddle.net/kL96nhfx/)
var a = "2015/05/04";
var res = '';
function editMonth(date, amount) {
var dateSplit = date.split('/');
var tmp = '';
tmp = parseInt(dateSplit[1]);
tmp += amount;
if (tmp > 12) {
dateSplit[1] = parseInt(tmp / 12);
if (tmp < 10) {
dateSplit[1] = '0' + tmp.toString();
} else {
dateSplit[1] = tmp.toString();
}
} else if (tmp <= 0) {
tmp = 1;
dateSplit[1] = '0' + tmp.toString();
} else {
dateSplit[1] = '0' + tmp.toString();
}
return dateSplit.join('/')
};
res = editMonth(a, 1);
console.log(res);
Only Moment.js is 129KB not compressed (https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/moment.js). Unless you're not doing anything specific IMHO I wouldn't use it.
It's just useless overhead

JavaScript: get all months between two dates?

I have two date strings like this:
var startDate = '2012-04-01';
var endDate = '2014-11-01';
And I want to end up with an array of strings like this:
var dates = ['2012-04-01', '2012-05-01', '2012-06-01' .... '2014-11-01',];
So far this is what I've got, but it's pretty ugly:
var startDate = '2012-04-01';
var endDate = '2014-11-01';
var start = new Date(Date.parse(startDate));
var end = new Date(Date.parse(endDate))
var dates = [];
for (var i = start.getFullYear(); i < end.getFullYear() + 1; i++) {
dates.push(i + '-' + '-01');
}
console.log(dates);
Is there a better way? JSFiddle.
This should produce the desired output:
function dateRange(startDate, endDate) {
var start = startDate.split('-');
var end = endDate.split('-');
var startYear = parseInt(start[0]);
var endYear = parseInt(end[0]);
var dates = [];
for(var i = startYear; i <= endYear; i++) {
var endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
var startMon = i === startYear ? parseInt(start[1])-1 : 0;
for(var j = startMon; j <= endMonth; j = j > 12 ? j % 12 || 11 : j+1) {
var month = j+1;
var displayMonth = month < 10 ? '0'+month : month;
dates.push([i, displayMonth, '01'].join('-'));
}
}
return dates;
}
Just call it with your existing date format:
dateRange('2013-11-01', '2014-06-01')
// ["2013-11-01", "2013-12-01", "2014-01-01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-05-01", "2014-06-01", "2014-07-01", "2014-08-01", "2014-09-01", "2014-10-01", "2014-11-01", "2014-12-01"]
You can also use the excellent moment.js library:
var startDate = moment('2012-04-01');
var endDate = moment('2014-11-01');
var result = [];
if (endDate.isBefore(startDate)) {
throw "End date must be greated than start date."
}
while (startDate.isBefore(endDate)) {
result.push(startDate.format("YYYY-MM-01"));
startDate.add(1, 'month');
}
JSFiddle
If loading an extra library isn't a problem, you could always try the awesome MomentJS.
Gives for very clean and powerful date manipulation.
var startDate = moment('2012-04-01');
var endDate = moment('2014-11-01');
var dates = [];
endDate.subtract(1, "month"); //Substract one month to exclude endDate itself
var month = moment(startDate); //clone the startDate
while( month < endDate ) {
month.add(1, "month");
dates.push(month.format('YYYY-MM-DD'));
}
console.log(dates);
JSFiddle here
const getMonths = (fromDate, toDate) => {
const fromYear = fromDate.getFullYear();
const fromMonth = fromDate.getMonth();
const toYear = toDate.getFullYear();
const toMonth = toDate.getMonth();
const months = [];
for(let year = fromYear; year <= toYear; year++) {
let monthNum = year === fromYear ? fromMonth : 0;
const monthLimit = year === toYear ? toMonth : 11;
for(; monthNum <= monthLimit; monthNum++) {
let month = monthNum + 1;
months.push({ year, month });
}
}
return months;
}
const sample = getMonths(new Date('2022-07-28'), new Date('2023-03-20'));
console.log(sample);
document.write('check the console output');
https://jsfiddle.net/xfayoqvs/
You are handling "logical" jumps, so you doesn't actually need timing arthmetics. So this is a simple counting problem:
var startDate = '2012-04-01';
var endDate = '2014-11-01';
var dates = [];
var d0 = startDate.split('-');
var d1 = endDate.split('-');
for (
var y = d0[0];
y <= d1[0];
y++
) {
for (
var m = d0[1];
m <= 12;
m++
) {
dates.push(y+"-"+m+"-1");
if (y >= d1[0] && m >= d1[1]) break;
};
d0[1] = 1;
};
console.log(dates);
Here is a solution which just uses string manipulation on that specific YYYY-MM-DD format:
function monthsBetween(...args) {
let [a, b] = args.map(arg => arg.split("-").slice(0, 2)
.reduce((y, m) => m - 1 + y * 12));
return Array.from({length: b - a + 1}, _ => a++)
.map(m => ~~(m / 12) + "-" + ("0" + (m % 12 + 1)).slice(-2) + "-01");
}
console.log(monthsBetween('2012-04-01', '2014-11-01'));
Here is another solution, using Date objects:
const enumerateMonths = (from, to) => {
const current = new Date(from)
current.setUTCDate(1)
current.setUTCHours(0, 0, 0, 0)
const toDate = new Date(to)
const months = []
while (current.getTime() <= toDate.getTime()) {
months.push(current.getUTCFullYear() + "-" + `${current.getUTCMonth() + 1}`.padStart(2, "0"))
current.setUTCMonth(current.getUTCMonth() + 1)
}
return months
}
This solution presumes you provide Date objects or ISO 8601 strings. Please mind that an ISO 8601 date does not necessarily have to contain the hours-minutes-seconds part. "2012-01-14" is a valid ISO 8601 date.
An example to get all first days of months between a given date and now using moment.js.
var getMonths = function (startDate) {
var dates = [];
for (var year = startDate.year(); year <= moment().year(); year++) {
var endMonth = year != moment().year() ? 11 : moment().month();
var startMonth = year === startDate.year() ? startDate.month() : 0;
for (var currentMonth = startMonth; currentMonth <= endMonth; currentMonth = currentMonth > 12 ? currentMonth % 12 || 11 : currentMonth + 1) {
var month = currentMonth + 1;
var displayMonth = month < 10 ? '0' + month : month;
dates.push([year, displayMonth, '01'].join('-'));
}
}
return dates;
};
All solutions above run in O(n^2) time complexity, which is not very efficient.
See below solution in O(n) time complexity:
function getAllMonths(start, end){
let startDate = new Date(start);
let startYear = startDate.getFullYear();
let startMonth = startDate.getMonth()+1;
let endDate = new Date(end);
let endYear = endDate.getFullYear();
let endMonth = endDate.getMonth()+1;
let countMonth = 0;
let countYear = 0;
let finalResult = [];
for(let a=startYear; a<=endYear; a++){
if(startYear<endYear){
if(countYear==0){
countMonth += 12-startMonth;
}else
if(countYear>0){
countMonth += 12;
}
countYear+=1;
startYear++;
}else
if(startYear==endYear){
countMonth+=endMonth;
}
}
for(let i=startMonth; i<=countMonth+startMonth; i++){
finalResult.push(startDate.getFullYear()+(Math.floor(i/12)) + "-" + Math.round(i%13) + "-" + "01");
}
return finalResult;
}
getAllMonths('2016-04-01', '2018-01-01');
Might share a much more simpler code
Still not a very elegant answer, but arrives at the array of strings you want:
var startDate = '2012-04-01';
var endDate = '2014-11-01';
var start = new Date(startDate);
var end = new Date(endDate);
var dates = [];
for (var i = start.getFullYear(); i < end.getFullYear() + 1; i++) {
for (var j = 1; j <= 12; j++) {
if (i === end.getFullYear() && j === end.getMonth() + 3) {
break;
}
else if (i === 2012 && j < 4){
continue;
}
else if (j < 10) {
var dateString = [i, '-', '0' + j, '-','01'].join('');
dates.push(dateString)
}
else {
var dateString = [i, '-', j, '-','01'].join('');
dates.push(dateString);
}
}
}
console.log(dates);
jsfiddle link here: http://jsfiddle.net/8kut035a/
This is my solution, with help of math and O(n)
determineMonthInInterval(startDate, endDate) {
let startYear = startDate.getFullYear();
let endYear = endDate.getFullYear();
let startMonth = startDate.getMonth() + 1;
let endMonth = endDate.getMonth() + 1;
let monthAmount = (endMonth - startMonth) + 1 + (12 * (endYear - startYear));
let dates = [];
let currMonth = startMonth;
let currYear = startYear;
for( let i=0; i<monthAmount; i++){
let date = new Date(currYear + "/"+currMonth+"/1");
dates.push(date);
currYear = startYear + Math.floor((startMonth+i) / 12);
currMonth = (currMonth) % 12 +1;
}
return dates;
}
Here is another option:
getRangeOfMonths(startDate: Date, endDate: Date) {
const dates = new Array<string>();
const dateCounter = new Date(startDate);
// avoids edge case where last month is skipped
dateCounter.setDate(1);
while (dateCounter < endDate) {
dates.push(`${dateCounter.getFullYear()}-${dateCounter.getMonth() + 1}`);
dateCounter.setMonth(dateCounter.getMonth() + 1);
}
return dates;
}

Get a list of dates between two dates using javascript

From JavaScript is there a way to get list of days between two dates from MySQL format. I don't want to use any library for this.
This is what i did.
function generateDateList(from, to) {
var getDate = function(date) { //Mysql Format
var m = date.getMonth(), d = date.getDate();
return date.getFullYear() + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
}
var fs = from.split('-'), startDate = new Date(fs[0], fs[1], fs[2]), result = [getDate(startDate)], start = startDate.getTime(), ts, end;
if ( typeof to == 'undefined') {
end = new Date().getTime();
} else {
ts = to.split('-');
end = new Date(ts[0], ts[1], ts[2]).getTime();
}
while (start < end) {
start += 86400000;
startDate.setTime(start);
result.push(getDate(startDate));
}
return result;
}
console.log(generateDateList('2014-2-27', '2014-3-2'));
I test it from chrome and nodejs below are the result.
[ '2014-02-27',
'2014-02-28',
'2014-02-29',
'2014-02-30',
'2014-02-31',
'2014-03-01',
'2014-03-02' ]
yeh big leap year:-D..., how can i fix this? or is there any better way.?
const listDate = [];
const startDate ='2017-02-01';
const endDate = '2017-02-10';
const dateMove = new Date(startDate);
let strDate = startDate;
while (strDate < endDate) {
strDate = dateMove.toISOString().slice(0, 10);
listDate.push(strDate);
dateMove.setDate(dateMove.getDate() + 1);
};
Take the start date and increment it by one day until you reach the end date.
Note: MySQL dates are standard format, no need to parse it by hand just pass it to the Date constructor: new Date('2008-06-13').
const addDays = (date, days = 1) => {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
};
const dateRange = (start, end, range = []) => {
if (start > end) return range;
const next = addDays(start, 1);
return dateRange(next, end, [...range, start]);
};
const range = dateRange(new Date("2014-02-27"), new Date("2014-03-02"));
console.log(range);
console.log(range.map(date => date.toISOString().slice(0, 10)))
Here I use a recursive function, but you could achieve the same thing using a while (see other answers).
I have used this one from
https://flaviocopes.com/how-to-get-days-between-dates-javascript/
const getDatesBetweenDates = (startDate, endDate) => {
let dates = []
//to avoid modifying the original date
const theDate = new Date(startDate)
while (theDate < new Date(endDate)) {
dates = [...dates, new Date(theDate)]
theDate.setDate(theDate.getDate() + 1)
}
dates = [...dates, new Date(endDate)]
return dates
}
Invoke the function as follows:
getDatesBetweenDates("2021-12-28", "2021-03-01")
Note - I just had to fix issues with the Date object creation (new Date()) in the while loop and in the dates array. Other than that the code is pretty much same as seen on the above link
dateRange(startDate, endDate) {
var start = startDate.split('-');
var end = endDate.split('-');
var startYear = parseInt(start[0]);
var endYear = parseInt(end[0]);
var dates = [];
for(var i = startYear; i <= endYear; i++) {
var endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
var startMon = i === startYear ? parseInt(start[1])-1 : 0;
for(var j = startMon; j <= endMonth; j = j > 12 ? j % 12 || 11 : j+1) {
var month = j+1;
var displayMonth = month < 10 ? '0'+month : month;
dates.push([i, displayMonth, '01'].join('-'));
}
}
return dates;
}
var oDate1 = oEvent.getParameter("from"),
oDate2 = oEvent.getParameter("to");
var aDates = [];
var currentDate = oDate1;
while (currentDate <= oDate2) {
aDates.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}
I expanded Công Thắng's great answer to return {years, months, days}, thought it was worth sharing:
function getDates(startDate, endDate) {
const days = [],
months = new Set(),
years = new Set()
const dateMove = new Date(startDate)
let date = startDate
while (date < endDate){
date = dateMove.toISOString().slice(0,10)
months.add(date.slice(0, 7))
years.add(date.slice(0, 4))
days.push(date)
dateMove.setDate(dateMove.getDate()+1) // increment day
}
return {years: [...years], months: [...months], days} // return arrays
}
console.log(getDates('2016-02-28', '2016-03-01')) // leap year
/* =>
{
years: [ '2016' ],
months: [ '2016-02', '2016-03' ],
days: [ '2016-02-28', '2016-02-29', '2016-03-01' ]
}
*/
const {months} = getDates('2016-02-28', '2016-03-01') // get only months
Basically the function just increments the built-in Date object by one day from start to end, while the Sets capture unique months and years.

Categories

Resources