Diferencia entre fechas


([N1] aguinet1) #1

Buenas a todos, en la open App Día juliano hay una funcion DIC_FEC (Diferencia entre Fechas) en la que si ingreso un rango de fechas tal como 15/08/2014 al 01/09/2014 la respuesta es 44 días debiendo ser 16 días donde esta la falla?
Lo quise utilizar para calcular la edad


([N4] informatica) #2

Hola, tienes razón, si utilizas el formato AMD ó AMDH para que te descomponga la diferencia en Años, Meses, Dias y Horas la función DIF_FEC no lo hace bien. Si solo quieres los días transcurridos, formato D, entonces si lo hace bien, ya que utiliza realmente las funciones de cálculo juliano.

Si quieres arreglarlo, sustituye debajo de:

if (FORMATO = “AMD”) | (FORMATO = “AMDH”) | (FORMATO = “A”) | (FORMATO = “AF”) | (FORMATO = “M”) | (FORMATO = “MF”) | (FORMATO = “”)
set B fun:DIAS_MES@Dia Juliano.dat( AÑO_H, MES_H )

todas las lineas hasta

set DIAS = DIA_H - DIA_D

por las siguientes lineas:

set AÑOS = AÑO_H - AÑO_D
set MESES = MES_H - MES_D
set DIAS = DIA_H - DIA_D
if DIAS < 0
set MESES = MESES - 1
if MES_H = 1
set DIAS_MES_ANT = daysInMonth( setDate ( AÑO_H - 1, 1, 1 ) )
else
set DIAS_MES_ANT = daysInMonth( setDate ( AÑO_H, MES_H - 1, 1 ) )
if MESES < 0
set AÑOS = AÑOS - 1
set MESES = MESES + 12

Así ya te funcionará bien el calculo de Años, Meses y Dias entre fechas.

Un saludo,


([N1] aguinet1) #3

Muchas gracias por tu pronta respuesta hice la modificación, tal vez no lo hice correctamente pero el resultado comparado con el original y el modificado salen así, la variable DIAS_MES_ANT recién creado no veo la finalidad. Te muestro gráficamente los resultados.

Gracias.




([N3] Humber) #4

Yo hice una función en javascript que hace estos calculos, te paso el enlace en caso de que quieras probarla aunque solo calcula como el ejemplo que muestras en las imágenes, dias, meses, años.

https://gist.github.com/xploshioOn/742af7bc0f7927fda4e2

Saludos.


([N1] aguinet1) #5

Gracias amigo Humber por tu aporte, pero como lo llamo desde un botón, como parámetros un campo y la fecha actual.


([N3] ereitmann) #6

Te dejo una funcion que calcula el periodo la saque de este foro aportado por jorgevelasco, y yo la moifique para que si el perído era mayor a tre años solo calcula los años de edad y si es menor, solo años meses y dias, (asi lo hice por pedido del cliente) pero puedes modificarla a tu antojo



([N4] informatica) #7

Hola de nuevo, la variable DIA_MES_ANT contiene los días del mes anterior al mes de la fecha, Asegúrate que sea numérica. Te adjunto una captura de lo que me sale a mí.



([N3] Humber) #8

Buenas @aguinet1 te comentaré paso a paso como utilizarla por ejemplo en un formulario.

  1. creas un nuevo archivo javascript en tu proyecto con el nombre que desees, por ejemplo duration.js y pegas el contenido de la función. de esta manera tienes el script para utilzarlo en cualquier evento, proceso o donde necesites.

  2. en tu formulario creas un evento tipo javascript, haces el include del js que acabas de crear para que puedas ejecutar la función

  3. ejecutas la función pasandole como parametro dos fechas y ya tienes el resultado en una variable

por ejemplo, mi evento podría ser así:

//hago el include del archivo js donde está la función
#include "4jvvwuki.vca/plugins/duration.js"
//creo una variable donde almacenaré el resultado del calculo y ejecuto la función de esta manera duration(fecha1,fecha2)
var resultado = duration(theRoot.varToDate('DESDE'),theRoot.varToDate('HASTA'));
//aquí solo convierto el resultado que viene en json a un string para imprimirlo
resultado = JSON.stringify(resultado);
//mando un mensaje con el resultado
alert(resultado);

En tu caso solo necesitas utilizar estas dos lineas, y en vez de pasar variables, pasas los campos que necesites

#include "4jvvwuki.vca/plugins/duration.js"
var resultado = duration(theRoot.varToDate('DESDE'),theRoot.varToDate('HASTA'));

y en la variable resultado tienes un json con esta estructura {years:1 months:3 days:15}, puedes modificar en la función la linea del return para que te devuelva una cadena formateada o de la manera que te parezca mas comoda.

saludos.


([N1] aguinet1) #9

Gracias amigo @ereitmann justamente eso es lo primero que probé con diferencia de días no hay problema le puse diferencia de 11 meses y después de 8 minutos esperando tuve que abortarlo pues no respondía lo tengo en la nube y revise el código nuevamente y es identico a la fuente.

Amigo @informatica la variable DIA_MES_ANT lo tengo numérico pero no se donde se utiliza puesto que solo se le asigna un valor según las ultimas lineas para modificar que me enviaste, por favor una revisada a la imagen que le envié anteriormente de una parte de la función justo la corregida quizás los if, else no estén como debiera, tal vez a mi me sale “49 años, 6 meses, -7 dia” según su ejemplo último.

Amigo @Humber logré correr pero le pongo las fechas 13/11/2013 y 13/11/2014 me sale años: 0, meses: 0, dias: 31


([N3] pacosatu) #10

Hola Humber.

Por favor, revisa ese código JavaScript.
A primera vista hay errores en el cálculo de los Años, faltan paréntesis en la función getFullYear, etc …

Saludos
Paco Satué


([N3] Humber) #11

Efectivamente tenía ese detalle @aguinet1, ya está corregido ese caso. La función básicamente son un motón de if así que puede que algún caso me lo haya saltado, justamente con las pruebas es que me voy dando cuenta que falta una u otra cosa o hay algún detalle y lo voy corrigiendo.

Te dejo el gist actualizado
https://gist.github.com/xploshioOn/742af7bc0f7927fda4e2
y en codepen para que la puedas probar en ejecución, si quieres probar muchos casos para estar seguro antes de pasarlo a tu fuente
http://codepen.io/xploshioOn/pen/gHBAy?editors=101

@seh, gracias, si faltaban parentesis en 2 getfullyear(), no había actualizado la función de mi fuente al gist, saludos.


([N1] aguinet1) #12

Hola amigo @Humber falta revisar el código:

con 13/11/2013, 14/11/2014 = años: 0,mes: 0,dia: 1
con 13/11/2014, 14/11/2014 = años:-1,mes: 0,dia: 1


([N3] pacosatu) #13

Hola Humber.

Si me permites y para no marear más con el código javascript, adjunto el código que yo usaba en otro lenguaje y que he convertido a javascript. He usado tu función de DiasDelMes() y devuelve igualmente un JSON.
He añadido el cálculo de la diferencia en días, el cual es inmediato.


// *****************************************************************
// Objeto DifFechas - devuelve la diferencia entre 2 fechas 

var DifFechas = {};

// Diferencia en dias entre 2 fechas: dIni, dFin
DifFechas.D = function(dIni, dFin) {
	var dAux, nDias, cRetorno
	// La fecha final siempre mayor que la inicial
	if (dIni > dFin) {
		dAux = dIni
		dIni = dFin
		dFin = dAux
	}
	// Convertimos los milisegundos a Días
	nDias = parseInt(((dFin - dIni)/(60*60*24))/1000)
	cRetorno = {"dias":nDias}
	return cRetorno	
}

// Diferencia en años, meses y dias entre 2 fechas: dIni, dFin
DifFechas.AMD = function(dIni, dFin) {
	var dAux, nAnos, nMeses, nDias, cRetorno
	// La fecha final siempre mayor que la inicial
	if (dIni > dFin) {
		dAux = dIni
		dIni = dFin
		dFin = dAux
	}
	// Calculamos Años
	nAnos = dFin.getFullYear() - dIni.getFullYear()
	// Trasladamos la fecha inicial al mismo año que la fecha final
	dAux = new Date(dIni.getFullYear() + nAnos, dIni.getMonth(), dIni.getDate())
	// Comprobamos si tenemos que quitar un Año porque no está entero
	if (dAux > dFin) {
		--nAnos
	}
	// Calculamos Meses
	nMeses = dFin.getMonth() - dIni.getMonth()
	// Sumamos en meses la parte del Año incompleta
	if (nMeses < 0) {
		nMeses = nMeses + 12
		}
	// Calculamos Días
	nDias = dFin.getDate() - dIni.getDate()
	// Sumamos en días la parte del Mes incompleta
	if (nDias < 0) {
		nDias = nDias + this.DiasDelMes(dIni)
	}
	// Si el día es mayor, quitamos un mes
	if (dFin.getDate() < dIni.getDate()) {
		if (nMeses == 0) {
			nMeses = 11
		}
		else {
			--nMeses
		}
	}
	cRetorno = {"años":nAnos,"meses":nMeses,"dias":nDias}
	return cRetorno
}

DifFechas.DiasDelMes = function (date) {
	date = new Date(date);
	return 32 - new Date(date.getFullYear(), date.getMonth(), 32).getDate();
}

Adjunto imagen para que veáis que se puede llamar al objeto JavaScript directamente en una fórmula usando #include.

Saludos
Paco Satué



([N3] Humber) #14

Ya corregí tambien ese caso @aguinet1.

@seh no te preocupes, estamos aquí para compartir y ayudar :slight_smile:

por cierto, el calculo de días completos con esa formula puede no ser exacto, que pasaría con los años bisiestos?


([N1] aguinet1) #15

Hola amigo @Humber sigue con fallas:

13/11/2014, 14/11/2014 = años: 0,mes: 0,dia: 1 Ok
12/11/2014, 14/11/2014 = años: 1,mes: 0,dia: 2 si disminuimos los dias desde 12
02/11/2014, 14/11/2014 = años: 1,mes: 0,dia: 12 hasta este día 02 calcula mal
01/11/2014, 14/11/2014 = años: 0,mes: 0,dia: 13 Ok


([N1] aguinet1) #16

Gracias amigo @seh por tu código, hasta ahora va bien incluso con un bisiesto.

Muchas gracias a todos da gusto estar en una comunidad activa por su ayuda desinteresada.


([N1] aguinet1) #17

Retomo este hilo porque quiero parsear los años, meses y días porque quiero que cuando por ejemplo sea la fecha Años: 30, meses: 0, días: 20, desechar el mes: 0
Partiendo del siguiente retorno de la función:
cRetorno = {“anos”:nAnos,“meses”:nMeses,“dias”:nDias};

Hago la prueba de los años con el código siguiente:

var cadena = DifFechas.AMD(theRoot.varToDate(‘FECHA_DESDE’), theRoot.varToDate(‘FECHA_HASTA’));
var resultado = JSON.parse(cadena);
for(var i=0; i<resultado.length; i++)
alert('Años: ’ + resultado[i].anos);

Sale el error: Error en script: SyntaxError: Unable to parse JSON string <anonymous>()@/DIFFEC/DIFFECHAS:68

Gracias por la respuesta.


([N3] pacosatu) #18

Hola aguinet1.

La función DifFechas.AMD devuelve un valor resul que ya es un objeto JSON, por lo tanto no es necesario parsearlo.

Prueba lo siguiente:


var resul = DifFechas.AMD(theRegister.varToDate("DFECHA_INI"),theRegister.varToDate("DFECHA_FIN"))
var años = resul["años"]>0?"Años=" + resul["años"]:""
var meses = resul["meses"]>0?"Meses=" + resul["meses"]:""
var dias = resul["dias"]>0?"Días=" + resul["dias"]:""
String( años + " " + meses + " " + dias ).trim()

Saludos
Paco Satué


([N1] Spicer) #19

Estimado Paco,

Muchas gracias por tu script, me viene como anillo al dedo.
Sin embargo, no sé cómo ejecutarlo… la foto que pones, en la cual en el editor de fórmulas pones el #include y luego la función, me genera un error…

Todavía no tengo mucha soltura en esto de los scripts de vJavaScript.

¿Cómo lo podría hacer para, a través de un botón de un formulario, obtener el número de períodos entre dos fechas? entendiendo como período, un mes o fracción…?

Saludos