miércoles, 27 de abril de 2011

Diferencia entre 2 fechas (años cumplidos) en java

Obtener los años cumplidos, a partir de una fecha en particular, tiene sus aplicaciones (validar mayoria de edad en las personas, verificar si aun aplica una garantia, a partir de la fecha de compra, etc)

La aproximacion, es la siguiente:


 1 import java.util.Calendar;
 2 import java.util.Date;
 3 
 4 public class DatesDiff {
 5 
 6  public static int calculateAge(Date bornDate) {
 7   Calendar cal = Calendar.getInstance(); // current date
 8   int currYear = cal.get(Calendar.YEAR);
 9   int currMonth = cal.get(Calendar.MONTH);
10   int currDay = cal.get(Calendar.DAY_OF_MONTH);
11   cal.setTime(bornDate); // now born date
12   int years = currYear - cal.get(Calendar.YEAR);
13   int bornMonth = cal.get(Calendar.MONTH);
14   if (bornMonth == currMonth) { // same month
15    return cal.get(Calendar.DAY_OF_MONTH) <= currDay ? years
16      : years - 1;
17   } else {
18    return bornMonth < currMonth ? years - 1 : years;
19   }
20  }
21 
22 }


Explicación:
07-07: Se obtiene la fecha actual, al obtener una instancia del objeto Calendar
08-10: Se obtienen lo valores del año, mes y dia actual (cache)
11-11: Se actualiza el objeto cal, con la fecha de nacimiento
12-12: Se calcula la diferencia de años
13-13: Se obtiene el año de nacimiento (cache)
14-14: Se verifica si el mes actual coincide con el mes de nacimiento
15-15:  Si los meses coinciden, se valida si el los dias coinciden, de ser este el caso, se regresan la diferencia de años, en caso contrario (aun no se cumple otro año) se regresa la diferencia menos uno.
18-18: Si los meses no coinciden, se regresala diferencia de los años menos 1 si el mes de nacimiento es menor que el mes actual y la diferencia de años, en caso contrario

En este codigo, se utiliza un solo objeto Calendar en vez de 2 objetos distintos. En vez de utilizar un objeto Calendar nuevo, obtenemos los valores que se emplearan a posteriormente en variables de tipo nativo, las cuales radican en el pila (stack), en vez de el  (heap).

Una optimizacion posible, es parametrizar la fecha actual, para el tema de internacionalizacion, con respecto a las zonas horarias, ya que se da la posibilidad que tomando en cuenta la fecha de la zona horaria de un pais distnto puede ser que se cumpla o no un año mas.

1 comentario:

  1. return bornMonth < currMonth ? years - 1 : years;

    en esta linea debe ser

    return bornMonth < currMonth ? years : years - 1;

    porque si el mes de nacimiento es menor al mes actual significa que ya cumpliste años este año y se asigna (years) , y si el mes de nacimiento es mayor al mes actual eso quiere decir que tu mes de nacimiento aun no llega por lo tanto no cumples años y es cuando debe asignarse (years - 1)

    o tambien

    return bornMonth > currMonth ? years - 1 : years;

    ResponderBorrar