una restar meses horas habiles fechas fecha entre dias con calcular años javascript date datediff

restar - Diferencia entre dos fechas en años, meses, días en JavaScript



restar dias a una fecha javascript (17)

¿Qué tan preciso necesitas ser? Si necesita tener en cuenta los años comunes y años bisiestos, y la diferencia exacta en días entre meses, entonces tendrá que escribir algo más avanzado, pero para un cálculo básico y aproximado, esto debería ser el truco:

today = new Date() past = new Date(2010,05,01) // remember this is equivalent to 06 01 2010 //dates in js are counted from 0, so 05 is june function calcDate(date1,date2) { var diff = Math.floor(date1.getTime() - date2.getTime()); var day = 1000 * 60 * 60 * 24; var days = Math.floor(diff/day); var months = Math.floor(days/31); var years = Math.floor(months/12); var message = date2.toDateString(); message += " was " message += days + " days " message += months + " months " message += years + " years ago /n" return message } a = calcDate(today,past) console.log(a) // returns Tue Jun 01 2010 was 1143 days 36 months 3 years ago

Tenga en cuenta que esto es impreciso, para calcular la fecha con total precisión, uno debería tener un calendario y saber si un año es bisiesto o no, también la forma en que estoy calculando el número de meses es solo aproximada. .

Pero puedes mejorarlo fácilmente.

He estado buscando durante 4 horas y no he encontrado una solución para obtener la diferencia entre dos fechas en años, meses y días en JavaScript, como por ejemplo: el 10 de abril de 2010 fue de 3 años, x mes y días atrás.

Hay muchas soluciones, pero solo ofrecen la diferencia en el formato de días O meses O años, o no son correctas (es decir, no se ocupan de la cantidad real de días en un mes o años bisiestos, etc.). ¿Es realmente tan difícil hacer eso?

He echado un vistazo a:

En php es fácil, pero desafortunadamente solo puedo usar scripts del lado del cliente en ese proyecto. Cualquier biblioteca o marco que pueda hacerlo estaría bien, también.

Aquí hay una lista de resultados esperados para las diferencias de fechas:

//Expected output should be: "1 year, 5 months". diffDate(new Date(''2014-05-10''), new Date(''2015-10-10'')); //Expected output should be: "1 year, 4 months, 29 days". diffDate(new Date(''2014-05-10''), new Date(''2015-10-09'')); //Expected output should be: "1 year, 3 months, 30 days". diffDate(new Date(''2014-05-10''), new Date(''2015-09-09'')); //Expected output should be: "9 months, 27 days". diffDate(new Date(''2014-05-10''), new Date(''2015-03-09'')); //Expected output should be: "1 year, 9 months, 28 days". diffDate(new Date(''2014-05-10''), new Date(''2016-03-09'')); //Expected output should be: "1 year, 10 months, 1 days". diffDate(new Date(''2014-05-10''), new Date(''2016-03-11''));


Algunas matemáticas están en orden.

Puede restar un objeto Date de otro en Javascript, y obtendrá la diferencia entre ellos en milisseconds. A partir de este resultado, puede extraer las otras partes que desee (días, meses, etc.)

Por ejemplo:

var a = new Date(2010, 10, 1); var b = new Date(2010, 9, 1); var c = a - b; // c equals 2674800000, // the amount of milisseconds between September 1, 2010 // and August 1, 2010.

Ahora puedes obtener cualquier parte que quieras. Por ejemplo, cuántos días han transcurrido entre las dos fechas:

var days = (a - b) / (60 * 60 * 24 * 1000); // 60 * 60 * 24 * 1000 is the amount of milisseconds in a day. // the variable days now equals 30.958333333333332.

Eso es casi 31 días. Luego puede redondear durante 30 días y usar lo que quede para obtener las cantidades de horas, minutos, etc.


Creo que estás buscando lo mismo que yo quería. Intenté hacer esto usando la diferencia en milisegundos que javascript proporciona, pero esos resultados no funcionan en el mundo real de las fechas. Si desea la diferencia entre el 1 de febrero de 2016 y el 31 de enero de 2017, el resultado que deseo es 1 año, 0 meses y 0 días. Exactamente un año (suponiendo que cuente el último día como un día completo, como en un contrato de arrendamiento de un apartamento). Sin embargo, el enfoque en milisegundos le daría 1 año 0 meses y 1 día, ya que el rango de fechas incluye un año bisiesto. Así que aquí está el código que utilicé en javascript para mi formulario de adobe (puede nombrar los campos): (editado, hubo un error que corregí)

var f1 = this.getField("LeaseExpiration"); var g1 = this.getField("LeaseStart"); var end = f1.value var begin = g1.value var e = new Date(end); var b = new Date(begin); var bMonth = b.getMonth(); var bYear = b.getFullYear(); var eYear = e.getFullYear(); var eMonth = e.getMonth(); var bDay = b.getDate(); var eDay = e.getDate() + 1; if ((eMonth == 0)||(eMonth == 2)||(eMonth == 4)|| (eMonth == 6) || (eMonth == 7) ||(eMonth == 9)||(eMonth == 11)) { var eDays = 31; } if ((eMonth == 3)||(eMonth == 5)||(eMonth == 8)|| (eMonth == 10)) { var eDays = 30; } if (eMonth == 1&&((eYear % 4 == 0) && (eYear % 100 != 0)) || (eYear % 400 == 0)) { var eDays = 29; } if (eMonth == 1&&((eYear % 4 != 0) || (eYear % 100 == 0))) { var eDays = 28; } if ((bMonth == 0)||(bMonth == 2)||(bMonth == 4)|| (bMonth == 6) || (bMonth == 7) ||(bMonth == 9)||(bMonth == 11)) { var bDays = 31; } if ((bMonth == 3)||(bMonth == 5)||(bMonth == 8)|| (bMonth == 10)) { var bDays = 30; } if (bMonth == 1&&((bYear % 4 == 0) && (bYear % 100 != 0)) || (bYear % 400 == 0)) { var bDays = 29; } if (bMonth == 1&&((bYear % 4 != 0) || (bYear % 100 == 0))) { var bDays = 28; } var FirstMonthDiff = bDays - bDay + 1; if (eDay - bDay < 0) { eMonth = eMonth - 1; eDay = eDay + eDays; } var daysDiff = eDay - bDay; if(eMonth - bMonth < 0) { eYear = eYear - 1; eMonth = eMonth + 12; } var monthDiff = eMonth - bMonth; var yearDiff = eYear - bYear; if (daysDiff == eDays) { daysDiff = 0; monthDiff = monthDiff + 1; if (monthDiff == 12) { monthDiff = 0; yearDiff = yearDiff + 1; } } if ((FirstMonthDiff != bDays)&&(eDay - 1 == eDays)) { daysDiff = FirstMonthDiff; } event.value = yearDiff + " Year(s)" + " " + monthDiff + " month(s) " + daysDiff + " days(s)"


El siguiente es un algoritmo que da una respuesta correcta pero no totalmente precisa ya que no tiene en cuenta el año bisiesto. También asume 30 días en un mes. Un buen uso, por ejemplo, es que si alguien vive en una dirección del 11/12/2010 al 11/10/2011 , puede decir rápidamente que la persona vive allí durante 10 meses y 29 días. Del 12/11/2010 al 11/12/2011 es 11 meses y 1 día. Para ciertos tipos de aplicaciones, ese tipo de precisión es suficiente. Esto es para esos tipos de aplicaciones porque apunta a la simplicidad:

var datediff = function(start, end) { var diff = { years: 0, months: 0, days: 0 }; var timeDiff = end - start; if (timeDiff > 0) { diff.years = end.getFullYear() - start.getFullYear(); diff.months = end.getMonth() - start.getMonth(); diff.days = end.getDate() - start.getDate(); if (diff.months < 0) { diff.years--; diff.months += 12; } if (diff.days < 0) { diff.months = Math.max(0, diff.months - 1); diff.days += 30; } } return diff; };

Pruebas unitarias


En realidad, hay una solución con un plugin moment.js y es muy fácil.

Puede usar http://momentjs.com/

No reinventes la rueda otra vez.

Simplemente conecte el plugin de rango de fechas de Moment.js .

Ejemplo:

var starts = moment(''2014-02-03 12:53:12''); var ends = moment(); var duration = moment.duration(ends.diff(starts)); // with ###moment precise date range plugin### // it will tell you the difference in human terms var diff = moment.preciseDiff(starts, ends, true); // example: { "years": 2, "months": 7, "days": 0, "hours": 6, "minutes": 29, "seconds": 17, "firstDateWasLater": false } // or as string: var diffHuman = moment.preciseDiff(starts, ends); // example: 2 years 7 months 6 hours 29 minutes 17 seconds document.getElementById(''output1'').innerHTML = JSON.stringify(diff) document.getElementById(''output2'').innerHTML = diffHuman

<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script> <script src="https://raw.githubusercontent.com/codebox/moment-precise-range/master/moment-precise-range.js"></script> </head> <body> <h2>Difference between "NOW and 2014-02-03 12:53:12"</h2> <span id="output1"></span> <br /> <span id="output2"></span> </body> </html>



He creado, una más, una función para este propósito:

function dateDiff(date) { date = date.split(''-''); var today = new Date(); var year = today.getFullYear(); var month = today.getMonth() + 1; var day = today.getDate(); var yy = parseInt(date[0]); var mm = parseInt(date[1]); var dd = parseInt(date[2]); var years, months, days; // months months = month - mm; if (day < dd) { months = months - 1; } // years years = year - yy; if (month * 100 + day < mm * 100 + dd) { years = years - 1; months = months + 12; } // days days = Math.floor((today.getTime() - (new Date(yy + years, mm + months - 1, dd)).getTime()) / (24 * 60 * 60 * 1000)); // return {years: years, months: months, days: days}; }

No requiere ninguna biblioteca de terceros. Toma un argumento - fecha en formato YYYY-MM-DD.

https://gist.github.com/lemmon/d27c2d4a783b1cf72d1d1cc243458d56


Hilo muy antiguo, lo sé, pero aquí está mi contribución, ya que el hilo no está resuelto todavía.

Toma años bisiestos en consideración y no asume ningún número fijo de días por mes o año.

Puede ser defectuoso en casos fronterizos ya que no lo he probado a fondo, pero funciona para todas las fechas proporcionadas en la pregunta original, por lo tanto estoy seguro.

function calculate() { var fromDate = document.getElementById(''fromDate'').value; var toDate = document.getElementById(''toDate'').value; try { document.getElementById(''result'').innerHTML = ''''; var result = getDateDifference(new Date(fromDate), new Date(toDate)); if (result && !isNaN(result.years)) { document.getElementById(''result'').innerHTML = result.years + '' year'' + (result.years == 1 ? '' '' : ''s '') + result.months + '' month'' + (result.months == 1 ? '' '' : ''s '') + ''and '' + result.days + '' day'' + (result.days == 1 ? '''' : ''s''); } } catch (e) { console.error(e); } } function getDateDifference(startDate, endDate) { if (startDate > endDate) { console.error(''Start date must be before end date''); return null; } var startYear = startDate.getFullYear(); var startMonth = startDate.getMonth(); var startDay = startDate.getDate(); var endYear = endDate.getFullYear(); var endMonth = endDate.getMonth(); var endDay = endDate.getDate(); // We calculate February based on end year as it might be a leep year which might influence the number of days. var february = (endYear % 4 == 0 && endYear % 100 != 0) || endYear % 400 == 0 ? 29 : 28; var daysOfMonth = [31, february, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; var startDateNotPassedInEndYear = (endMonth < startMonth) || endMonth == startMonth && endDay < startDay; var years = endYear - startYear - (startDateNotPassedInEndYear ? 1 : 0); var months = (12 + endMonth - startMonth - (endDay < startDay ? 1 : 0)) % 12; // (12 + ...) % 12 makes sure index is always between 0 and 11 var days = startDay <= endDay ? endDay - startDay : daysOfMonth[(12 + endMonth - 1) % 12] - startDay + endDay; return { years: years, months: months, days: days }; }

<p><input type="text" name="fromDate" id="fromDate" placeholder="yyyy-mm-dd" value="1999-02-28" /></p> <p><input type="text" name="toDate" id="toDate" placeholder="yyyy-mm-dd" value="2000-03-01" /></p> <p><input type="button" name="calculate" value="Calculate" onclick="javascript:calculate();" /></p> <p /> <p id="result"></p>


Intervalo de tiempo completo Días, Horas, Minutos, Segundos, Milisegundos:

// Extension for Date Date.difference = function (dateFrom, dateTo) { var diff = { TotalMs: dateTo - dateFrom }; diff.Days = Math.floor(diff.TotalMs / 86400000); var remHrs = diff.TotalMs % 86400000; var remMin = remHrs % 3600000; var remS = remMin % 60000; diff.Hours = Math.floor(remHrs / 3600000); diff.Minutes = Math.floor(remMin / 60000); diff.Seconds = Math.floor(remS / 1000); diff.Milliseconds = Math.floor(remS % 1000); return diff; }; // Usage var a = new Date(2014, 05, 12, 00, 5, 45, 30); //a: Thu Jun 12 2014 00:05:45 GMT+0400 var b = new Date(2014, 02, 12, 00, 0, 25, 0); //b: Wed Mar 12 2014 00:00:25 GMT+0400 var diff = Date.difference(b, a); /* diff: { Days: 92 Hours: 0 Minutes: 5 Seconds: 20 Milliseconds: 30 TotalMs: 7949120030 } */


La respuesta de @RajeevPNadig fue lo que estaba buscando, pero el código devuelve valores incorrectos tal como están escritos.

Mi edición de su respuesta fue rechazada y me dijeron que la publicara como mi propia respuesta. Esto puede devolver algunos resultados que se sienten un poco raros, pero no son técnicamente incorrectos.

// startDate must be a function dateAgo(date) { var startDate = new Date(date); var diffDate = new Date(new Date() - startDate); return ((diffDate.toISOString().slice(0, 4) - 1970) + "Y " + diffDate.getMonth() + "M " + (diffDate.getDate()-1) + "D"); }

Entonces puedes usarlo así:

// based on a current date of 2018-03-09 dateAgo(''1972-11-30''); // "45Y 3M 9D" dateAgo(''2017-03-09''); // "1Y 0M 0D" dateAgo(''2018-01-09''); // "0Y 2M 0D" dateAgo(''2018-02-09''); // "0Y 0M 28D" -- a little odd, but not wrong dateAgo(''2018-02-01''); // "0Y 1M 5D" -- definitely "feels" wrong dateAgo(''2018-03-09''); // "0Y 0M 0D"

Las cosas pueden ponerse un poco raras si llamas a dateAgo con la fecha actual y no estás usando una cadena AAAA-MM-DD, es decir:

oneMinuteAgo = Date.now() - 60000; dateAgo(oneMinuteAgo); // "0Y 11M 30D" -- ???

Si su caso de uso es solo cadenas de fecha, entonces esto debería funcionar bastante bien para la mayoría de las personas.


Ninguno de los códigos funciona para mí, así que lo uso en su lugar durante meses y días:

function monthDiff(d2, d1) { var months; months = (d2.getFullYear() - d1.getFullYear()) * 12; months -= d1.getMonth() + 1; months += d2.getMonth() + 1; return months <= 0 ? 0 : months; } function daysInMonth(date) { return new Date(date.getYear(), date.getMonth() + 1, 0).getDate(); } function diffDate(date1, date2) { if (date2 && date2.getTime() && !isNaN(date2.getTime())) { var months = monthDiff(date1, date2); var days = 0; if (date1.getUTCDate() >= date2.getUTCDate()) { days = date1.getUTCDate() - date2.getUTCDate(); } else { months--; days = date1.getUTCDate() - date2.getUTCDate() + daysInMonth(date2); } // Use the variables months and days how you need them. } }


Otra solución más, basada en algún código PHP. La función strtotime, también basada en PHP, se puede encontrar aquí: http://phpjs.org/functions/strtotime/ .

Date.dateDiff = function(d1, d2) { d1 /= 1000; d2 /= 1000; if (d1 > d2) d2 = [d1, d1 = d2][0]; var diffs = { year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0 } $.each(diffs, function(interval) { while (d2 >= (d3 = Date.strtotime(''+1 ''+interval, d1))) { d1 = d3; ++diffs[interval]; } }); return diffs; };

Uso:

> d1 = new Date(2000, 0, 1) Sat Jan 01 2000 00:00:00 GMT+0100 (CET) > d2 = new Date(2013, 9, 6) Sun Oct 06 2013 00:00:00 GMT+0200 (CEST) > Date.dateDiff(d1, d2) Object { day: 5 hour: 0 minute: 0 month: 9 second: 0 year: 13 }


Para calcular la diferencia entre dos fechas en Años, Meses, Días, Minutos, Segundos, Milisegundos usando TypeScript / JavaScript

dateDifference(actualDate) { // Calculate time between two dates: const date1 = actualDate; // the date you already commented/ posted const date2: any = new Date(); // today let r = {}; // object for clarity let message: string; const diffInSeconds = Math.abs(date2 - date1) / 1000; const days = Math.floor(diffInSeconds / 60 / 60 / 24); const hours = Math.floor(diffInSeconds / 60 / 60 % 24); const minutes = Math.floor(diffInSeconds / 60 % 60); const seconds = Math.floor(diffInSeconds % 60); const milliseconds = Math.round((diffInSeconds - Math.floor(diffInSeconds)) * 1000); const months = Math.floor(days / 31); const years = Math.floor(months / 12); // the below object is just optional // if you want to return an object instead of a message r = { years: years, months: months, days: days, hours: hours, minutes: minutes, seconds: seconds, milliseconds: milliseconds }; // check if difference is in years or months if (years === 0 && months === 0) { // show in days if no years / months if (days > 0) { if (days === 1) { message = days + '' day''; } else { message = days + '' days''; } } else if (hours > 0) { if (hours === 1) { message = hours + '' hour''; } else { message = hours + '' hours''; } } else { // show in minutes if no years / months / days if (minutes === 1) { message = minutes + '' minute''; } else {message = minutes + '' minutes'';} } } else if (years === 0 && months > 0) { // show in months if no years if (months === 1) { message = months + '' month''; } else {message = months + '' months'';} } else if (years > 0) { // show in years if years exist if (years === 1) { message = years + '' year''; } else {message = years + '' years'';} } return ''Posted '' + message + '' ago''; // this is the message a user see in the view }

Sin embargo, puede actualizar la lógica anterior para que el mensaje muestre segundos y milisegundos también o use el objeto ''r'' para formatear el mensaje de la manera que desee.

Si desea copiar directamente el código, puede ver mi esencia con el código anterior here


Para un uso rápido y fácil escribí esta función hace algún tiempo. Devuelve la diferencia entre dos fechas en un formato agradable. Siéntete libre de usarlo (probado en webkit).

/** * Function to print date diffs. * * @param {Date} fromDate: The valid start date * @param {Date} toDate: The end date. Can be null (if so the function uses "now"). * @param {Number} levels: The number of details you want to get out (1="in 2 Months",2="in 2 Months, 20 Days",...) * @param {Boolean} prefix: adds "in" or "ago" to the return string * @return {String} Diffrence between the two dates. */ function getNiceTime(fromDate, toDate, levels, prefix){ var lang = { "date.past": "{0} ago", "date.future": "in {0}", "date.now": "now", "date.year": "{0} year", "date.years": "{0} years", "date.years.prefixed": "{0} years", "date.month": "{0} month", "date.months": "{0} months", "date.months.prefixed": "{0} months", "date.day": "{0} day", "date.days": "{0} days", "date.days.prefixed": "{0} days", "date.hour": "{0} hour", "date.hours": "{0} hours", "date.hours.prefixed": "{0} hours", "date.minute": "{0} minute", "date.minutes": "{0} minutes", "date.minutes.prefixed": "{0} minutes", "date.second": "{0} second", "date.seconds": "{0} seconds", "date.seconds.prefixed": "{0} seconds", }, langFn = function(id,params){ var returnValue = lang[id] || ""; if(params){ for(var i=0;i<params.length;i++){ returnValue = returnValue.replace("{"+i+"}",params[i]); } } return returnValue; }, toDate = toDate ? toDate : new Date(), diff = fromDate - toDate, past = diff < 0 ? true : false, diff = diff < 0 ? diff * -1 : diff, date = new Date(new Date(1970,0,1,0).getTime()+diff), returnString = '''', count = 0, years = (date.getFullYear() - 1970); if(years > 0){ var langSingle = "date.year" + (prefix ? "" : ""), langMultiple = "date.years" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (years > 1 ? langFn(langMultiple,[years]) : langFn(langSingle,[years])); count ++; } var months = date.getMonth(); if(count < levels && months > 0){ var langSingle = "date.month" + (prefix ? "" : ""), langMultiple = "date.months" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (months > 1 ? langFn(langMultiple,[months]) : langFn(langSingle,[months])); count ++; } else { if(count > 0) count = 99; } var days = date.getDate() - 1; if(count < levels && days > 0){ var langSingle = "date.day" + (prefix ? "" : ""), langMultiple = "date.days" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (days > 1 ? langFn(langMultiple,[days]) : langFn(langSingle,[days])); count ++; } else { if(count > 0) count = 99; } var hours = date.getHours(); if(count < levels && hours > 0){ var langSingle = "date.hour" + (prefix ? "" : ""), langMultiple = "date.hours" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (hours > 1 ? langFn(langMultiple,[hours]) : langFn(langSingle,[hours])); count ++; } else { if(count > 0) count = 99; } var minutes = date.getMinutes(); if(count < levels && minutes > 0){ var langSingle = "date.minute" + (prefix ? "" : ""), langMultiple = "date.minutes" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (minutes > 1 ? langFn(langMultiple,[minutes]) : langFn(langSingle,[minutes])); count ++; } else { if(count > 0) count = 99; } var seconds = date.getSeconds(); if(count < levels && seconds > 0){ var langSingle = "date.second" + (prefix ? "" : ""), langMultiple = "date.seconds" + (prefix ? ".prefixed" : ""); returnString += (count > 0 ? '', '' : '''') + (seconds > 1 ? langFn(langMultiple,[seconds]) : langFn(langSingle,[seconds])); count ++; } else { if(count > 0) count = 99; } if(prefix){ if(returnString == ""){ returnString = langFn("date.now"); } else if(past) returnString = langFn("date.past",[returnString]); else returnString = langFn("date.future",[returnString]); } return returnString; }


Sé que es un hilo viejo, pero me gustaría poner mis 2 centavos basados ​​en la respuesta de @Pawel Miech.

Es cierto que necesita convertir la diferencia en milisegundos, luego debe hacer algunos cálculos matemáticos. Pero tenga en cuenta que debe realizar las operaciones matemáticas de forma inversa, es decir, debe calcular los años, los meses, los días, las horas y los minutos.

Solía ​​hacer algo como esto:

var mins; var hours; var days; var months; var years; var diff = new Date() - new Date(yourOldDate); // yourOldDate may be is coming from DB, for example, but it should be in the correct format ("MM/dd/yyyy hh:mm:ss:fff tt") years = Math.floor((diff) / (1000 * 60 * 60 * 24 * 365)); diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 365)); months = Math.floor((diff) / (1000 * 60 * 60 * 24 * 30)); diff = Math.floor((diff) % (1000 * 60 * 60 * 24 * 30)); days = Math.floor((diff) / (1000 * 60 * 60 * 24)); diff = Math.floor((diff) % (1000 * 60 * 60 * 24)); hours = Math.floor((diff) / (1000 * 60 * 60)); diff = Math.floor((diff) % (1000 * 60 * 60)); mins = Math.floor((diff) / (1000 * 60));

Pero, por supuesto, esto no es preciso porque supone que todos los años tienen 365 días y todos los meses tienen 30 días, lo que no es cierto en todos los casos.


Utilicé este código simple para obtener la diferencia en Años, Meses, días con fecha actual.

var sdt = new Date(''1972-11-30''); var difdt = new Date(new Date() - sdt); alert((difdt.toISOString().slice(0, 4) - 1970) + "Y " + (difdt.getMonth()+1) + "M " + difdt.getDate() + "D");