maia_modificado/.svn/pristine/cf/cf1a8ac3b18dba09d1a1a11a273...

508 lines
17 KiB
Plaintext
Executable File
Raw Permalink Blame History

package com.fp.persistence.commondb.helper;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import com.fp.common.helper.CalculationBase;
import com.fp.common.logger.APPLogger;
import com.fp.persistence.commondb.exception.CommondbException;
/**
* Clase utilitaria para el manejo de fechas.
*
* @author Jorge Vaca
* @version 2.1
*/
public class APPDates implements Comparable {
/* Fecha base para las Operaciones */
private Date date;
/* Base de Calculo */
private CalculationBase base;
/* Calendario Encargado de las operaciones con las Fechas */
private final GregorianCalendar calendar;
/* Formateador de Fechas para transporte */
private final SimpleDateFormat formateador;
/**
* Crea una nueva instancia de Dates
*
* @param pDate Fecha base
* @param pBase Base de Calculo;
*/
public APPDates(String pDate, CalculationBase pBase) throws Exception {
this(new Date(FormatDates.getInstance().getTransportDateFormat().parse(pDate).getTime()), pBase);
}
/**
* Crea una nueva instancia de Dates
*
* @param pDate Fecha base como string formato yyyy-MM-dd
*/
public APPDates(String pDate) throws Exception {
this(pDate, CalculationBase.B360365);
}
/**
* Crea una nueva instancia de Dates
*
* @param pDate Fecha base
* @param pBase Base de Calculo;
*/
public APPDates(Date pDate, CalculationBase pBase) throws Exception {
this.date = pDate;
this.base = pBase;
this.calendar = new GregorianCalendar();
this.calendar.setTime(this.date);
this.formateador = FormatDates.getInstance().getTransportDateFormat();
}
/**
* Crea una nueva instancia de Dates
*
* @param pDate Fecha base
* @param pBase Base de Calculo;
*/
public APPDates(Date pDate, CalculationBase pBase, SimpleDateFormat sdf) throws Exception {
this.date = pDate;
this.base = pBase;
this.calendar = new GregorianCalendar();
this.calendar.setTime(this.date);
this.formateador = sdf;
}
/**
* Crea una nueva instancia de Dates con base 360/365
*
* @param pDate Fecha base
*/
public APPDates(Date pDate) throws Exception {
this(pDate, CalculationBase.B360365);
}
/**
* Entrega el Valor de date.
*
* @return Date
*/
public Date getDate() {
return this.date;
}
/**
* Entrega el Valor de date.
*
* @return Timestamp
*/
public Timestamp getTimestamp() {
return new Timestamp(this.date.getTime());
}
/**
* Metodoq ue resta un mes a una fecha y le pone el ultimo dia del mes en la misma.
*
* @throws Exception
*/
public void substractOneMonth365() throws Exception {
this.calendar.add(Calendar.MONTH, -1);
int max1 = this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
this.calendar.set(Calendar.DAY_OF_MONTH, max1);
this.date = new Date(this.calendar.getTimeInMillis());
}
/**
* Clase que se encarga de restar dos fechas, a la fecha mayor se resta una fecha menor.
*
* @param pInicialdate Feinicial a restar de una fecha final.
* @return int
* @throws Exception
*/
public int substract(APPDates pInicialdate) throws Exception {
int days = 0;
if (pInicialdate.getDate().after(this.date)) {
throw new CommondbException("COMMONDB-0001", "FECHA A RESTAR: {0,date,yyyy-MM-dd} ES MAYOR A: {1,date,yyyy-MM-dd}",
pInicialdate.getDate(), this.date);
}
if (pInicialdate.getDate().compareTo(this.date) == 0) {
return 0;
}
if (this.base.getMonthBase() == 365) {
days = this.substract365(pInicialdate);
} else {
days = this.substract360(pInicialdate);
}
return days;
}
/**
* Metodo que resta fechas en base cuando la base es 365/xxx
*
* @param pInicialdate Fecha inicia a restar.
* @return int
* @throws Exception
*/
private int substract365(APPDates pInicialdate) throws Exception {
int days = 0;
GregorianCalendar cal1 = new GregorianCalendar();
cal1.setTime(pInicialdate.getDate());
do {
cal1.add(Calendar.DATE, 1);
days++;
} while (this.date.compareTo(cal1.getTime()) != 0);
return days;
}
/**
* Metodo que se encarga de restar dos fehcas en base 360.
*
* @param pInicialdate
* @return
* @throws Exception
*/
private int substract360(APPDates pInicialdate) throws Exception {
int days = 0;
int nYears = this.getField(Calendar.YEAR) - pInicialdate.getField(Calendar.YEAR);
int nMonths = this.getField(Calendar.MONTH) - pInicialdate.getField(Calendar.MONTH);
int dayone = this.getField(Calendar.DAY_OF_MONTH);
if (dayone == 31) {
dayone = 30;
}
int daytwo = pInicialdate.getField(Calendar.DAY_OF_MONTH);
if (daytwo == 31) {
daytwo = 30;
}
int nMonth = this.getField(Calendar.MONTH);
if (nMonth == 1) { // 0 enero, 1 febrero , 2 marzo
// si el dia de la fecha es igual al maximo dia del mes
if (this.getField(Calendar.DAY_OF_MONTH) == this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) {
int day = pInicialdate.getField(Calendar.DAY_OF_MONTH);
if ((day == 30) || (day == 31)) {
dayone = 30;
}
}
}
nMonth = pInicialdate.getField(Calendar.MONTH);
if (nMonth == 1) { // 0 enero, 1 febrero , 2 marzo
// si el dia de la fecha es igual al maximo dia del mes
if (pInicialdate.getField(Calendar.DAY_OF_MONTH) == pInicialdate.calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) {
int day = this.getField(Calendar.DAY_OF_MONTH);
if ((day == 30) || (day == 31)) {
daytwo = 30;
}
}
}
nYears = nYears * 12 * 30;
nMonths = nMonths * 30;
days = dayone - daytwo;
days = nYears + nMonths + days;
/* v_dias_resultado := (nvl(v_anios,0) * 12 * 30) + (nvl(v_meses,0) * 30) + (nvl(v_dia1,0) - nvl(v_dia2,0)); */
return days;
}
/**
* Aniadir dias a una Fecha
*
* @param days Numero de dias a aniadir
*/
public void addYearBased(int days) throws Exception {
if (this.base.getYearBase() == 365) {
this.calendar.add(Calendar.DATE, days);
} else {
if (Math.abs(days) >= 30) {
int month = (int) Math.floor(days / 30);
this.calendar.add(Calendar.MONTH, month);
this.calendar.add(Calendar.DATE, days % 30);
} else {
this.calendar.add(Calendar.DATE, days);
}
}
this.date = new Date(this.calendar.getTime().getTime());
}
/**
* Aniadir dias a una Fecha, amteniendo un dia fijo en la fecha.
*
* @param days Numero de dias a adicionar.
* @param payDay Fecha de pago.
* @throws Exception
*/
public void addDaysBased(int days, Integer payDay) throws Exception {
if (this.base.getMonthBase() == 365) {
/*
* if( days == 31 || this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH) >= days){
* this.calendar.add(Calendar.MONTH,1); }else{ this.calendar.add(Calendar.DATE, days); }
*/
this.calendar.add(Calendar.DATE, days);
} else {
if (Math.abs(days) >= 30) {
int diff = 0;
if (this.calendar.get(Calendar.MONTH) == Calendar.FEBRUARY) {
if (this.calendar.get(Calendar.DATE) >= 28) {
if ((payDay != null) && (this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH) < payDay)) {
// diff= (this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH)==29)?1:2;
diff = payDay - this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}
}
}
int month = (int) Math.floor(days / 30);
this.calendar.add(Calendar.MONTH, month);
int d = days % 30;
this.calendar.add(Calendar.DATE, d);
if (diff > 0) {
this.calendar.add(Calendar.DATE, diff);
}
} else {
this.calendar.add(Calendar.DATE, days);
}
}
this.date = new Date(this.calendar.getTime().getTime());
}
/**
* Aniadir dias a una Fecha
*
* @param days Numero de dias a aniadir
*/
public void addMonthBased(int days) throws Exception {
if (this.base.getMonthBase() == 365) {
this.calendar.add(Calendar.DATE, days);
} else {
if (Math.abs(days) >= 30) {
int diff = 0;
if (this.calendar.get(Calendar.MONTH) == Calendar.FEBRUARY) {
if (this.calendar.get(Calendar.DATE) >= 28) {
diff = (this.calendar.getActualMaximum(Calendar.DAY_OF_MONTH) == 29) ? 1 : 2;
}
}
int month = (int) Math.floor(days / 30);
this.calendar.add(Calendar.MONTH, month);
this.calendar.add(Calendar.DATE, days % 30);
if (diff > 0) {
this.calendar.add(Calendar.DATE, diff);
}
} else {
this.calendar.add(Calendar.DATE, days);
}
}
this.date = new Date(this.calendar.getTime().getTime());
}
/**
* Entrega el Valor de base de calculo.
*
* @return CalculationBase.
*/
public CalculationBase getBase() {
return this.base;
}
/**
* Fija el valor de base de calculo
*
* @param base Nuevo valor de base.
*/
public void setBase(CalculationBase base) {
this.base = base;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.formateador.format(this.date).toString();
}
public int getField(int pField) throws Exception {
return this.calendar.get(pField);
}
/**
* Entrega el Valor de calendar.
*
* @return GregorianCalendar.
*/
public GregorianCalendar getGregorianCalendar() {
return this.calendar;
}
public APPDates dateFrecuency(Frequency pFrecuency) throws Exception {
this.calendar.add(Calendar.DATE, pFrecuency.getNumDays(this.getDate(), this.formateador));
return new APPDates(new Date(this.calendar.getTime().getTime()));
}
public APPDates nextDateofSequence(Frequency pFrecuency, int pDay) throws Exception {
int days = pFrecuency.getNumDays(this.getDate(), this.formateador);
if (days > 31) {
// TODO Incluiy las frecuanias superiores a mensual
throw new CommondbException("COMMONDB-0002", "LA FRECUENCIA DEBE SER MENOR O IGUAL A MENSUAL");
}
if (pDay > days) {
if ((pFrecuency == Frequency.MONTHLY) && (pDay == 31)) {
pDay = days;
} else {
throw new CommondbException("COMMONDB-0003", "El DIA {0} NO PUEDE MAYOR AL NUMEOR DE DIAS DE LA FRECUENCIA{1}", pDay, days);
}
}
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(this.date);
if (pFrecuency == Frequency.WEEKLY) {
while (cal.get(Calendar.DAY_OF_WEEK) != pDay) {
cal.add(Calendar.DAY_OF_WEEK, 1);
}
return new APPDates(new Date(cal.getTime().getTime()));
}
cal.set(Calendar.DATE, pDay);
APPLogger.getLogger().debug("Calendario base ==> " + cal.getTime());
APPLogger.getLogger().debug("Maximo dia del mes ==> " + cal.getActualMaximum(Calendar.DAY_OF_MONTH));
while (cal.getTime().before(this.date)) {
cal.add(Calendar.DATE, days);
}
while ((cal.get(Calendar.MONTH) != this.getField(Calendar.MONTH)) && (pDay != cal.get(Calendar.DATE))) {
cal.add(Calendar.DATE, -1);
}
if ((cal.get(Calendar.DATE) == 30) && (cal.getActualMaximum(Calendar.DAY_OF_MONTH) == 31)) {
cal.add(Calendar.DATE, 1);
}
return new APPDates(new Date(cal.getTime().getTime()));
}
public int getJulianDate() throws Exception {
GregorianCalendar c = new GregorianCalendar();
c.setTime(this.date);
return this.toJulian(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
}
private int toJulian(int year, int month, int day) throws Exception {
int julianYear = year;
if (year < 0) {
julianYear++;
}
int julianMonth = month;
if (month > 2) {
julianMonth++;
} else {
julianYear--;
julianMonth += 13;
}
double julian = (java.lang.Math.floor(365.25 * julianYear) + java.lang.Math.floor(30.6001 * julianMonth) + day + 1720995.0);
if ((day + (31 * (month + (12 * year)))) >= JGREG) {
int ja = (int) (0.01 * julianYear);
julian += (2 - ja) + (0.25 * ja);
}
return (int) Math.floor(julian);
}
public static final int JGREG = 15 + (31 * (10 + (12 * 1582)));
/**
* Adiciona anios, meses, dias, semanas ..Etc a una fecha.
*
* @param field Constante de anio, mes, dia...Etc
* @param value Numero de anios, dias, meses a adicionar puese der un valor negativo.
* @throws Exception
*/
public void addField(int field, int value) throws Exception {
getGregorianCalendar().add(field, value);
this.date = new Date(getGregorianCalendar().getTimeInMillis());
}
/**
* Adiciona anios, meses, dias, semanas ..Etc a una fecha.
*
* @param field Constante de anio, mes, dia...Etc
* @param value Numero de anios, dias, meses a adicionar puese der un valor negativo.
* @throws Exception
*/
public void setField(int field, int value) throws Exception {
if (field == Calendar.DAY_OF_MONTH) {
int maxday = getGregorianCalendar().getActualMaximum(Calendar.DAY_OF_MONTH);
if (value > maxday) {
value = maxday;
}
}
getGregorianCalendar().set(field, value);
this.date = new Date(getGregorianCalendar().getTimeInMillis());
}
/**
* Compara dos Dates.
*
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
if (!(o instanceof APPDates)) {
return -1;
}
APPDates d = (APPDates) o;
return this.date.compareTo(d.date);
}
/**
* Entrega el dia del anio al correspondiente a la Fecha
*
* @return Dia del Anio
* @throws Exception
*/
public int getDayOfYear() throws Exception {
GregorianCalendar gcal = new GregorianCalendar();
gcal.setTime(this.date);
return gcal.get(Calendar.DAY_OF_YEAR);
}
/**
* Entrega lso dias del mes correspondiente a la fecha.
*
* @return int
* @throws Exception
*/
public int getDaysOfMonth() throws Exception {
if (this.base.getMonthBase() == 360) {
return 30;
}
GregorianCalendar gcal = new GregorianCalendar();
gcal.setTime(this.date);
return gcal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/**
* Fija el ultimo dia del mes corespondiente a la fecha.
*
* @return
* @throws Exception
*/
public void setLastDateOfMonth() throws Exception {
Calendar gcal = new GregorianCalendar();
gcal.setTime(this.date);
gcal.set(Calendar.DAY_OF_MONTH, this.getDaysOfMonth());
this.date = new Date(gcal.getTimeInMillis());
}
/**
* Entrega el mes del a<>o correspondiente a la Fecha
*
* @return mes del a<>o
* @throws Exception
*/
public String getMonthOfYear() throws Exception {
int month = this.getField(Calendar.MONTH) + 1;
if (month < 10) {
return "0" + month;
} else {
return "" + month;
}
}
}