Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   diferencia de dias , suponiendo que los meses son de 30 dias. (https://www.clubdelphi.com/foros/showthread.php?t=69816)

ingabraham 29-07-2010 22:23:28

Dias360 en delphi
 
en excel para calcular el numero de dias es asi:
pero ojo excel toma como 360 dias por año.

DIAS360(fecha_inicial;fecha_final;método)

quiero hacer igual a excel, q me arroje el mismo resultado de dias pero en delphi.

ecfisa 29-07-2010 22:29:01

Hola ingabraham.

La función DaysBetween que esta en la unit DateUtils, te da la cantidad de días entre dos fechas.


Saludos.

delphi.com.ar 29-07-2010 22:31:53

Supongo que será algo como:
Código Delphi [-]
function DaysBetween360(const ANow, AThen: TDateTime): Integer;
begin
  Result := (DaysBetween(ANow, AThen) div 30) *  30;
end;

Saludos!

delphi.com.ar 29-07-2010 23:06:45

Después de responder, me di cuenta que la funcion DAYS360 / DIAS360 no cuenta simplemente meses de 30 días, sino que es algo mas complejo:

http://office.microsoft.com/en-us/ex...005209047.aspx


Encontre en la web este código en VB: http://www.experts-exchange.com/Data..._24634023.html
Y lo traduje a esto SIN PROBARLO:

Código Delphi [-]
function Days360(const ANow, AThen: TDateTime; Method: boolean): Integer;
var
  dStartDate,
  dEndDate: TDateTime;
  wStartDay,
  wStartMonth,
  wStartYear,
  wEndDay: Word;
  FebruaryAdjustment: Integer;
begin
  { Local copy }
  dStartDate := ANow;
  dEndDate := AThen;

  DecodeDate(dStartDate, wStartYear, wStartMonth, wStartDay);
  wEndDay := DayOf(dEndDate);

  if not Method Then
  begin
    { U.S. (NASD) method.
      If the starting date is the 31st of a month, it becomes equal to the 30th of the same month.
      If the ending date is the 31st of a month and the starting date is earlier than the 30th of a month,
      the ending date becomes equal to the 1st of the next month;
      otherwise the ending date becomes equal to the 30th of the same month.
    }

    if wStartDay > 30 then
      dStartDate := dStartDate - 1;

    if (wEndDay = 31) and (wStartDay < 30) then
      dEndDate := dEndDate + 1
    else
    if(wEndDay = 31) and (wStartDay >= 30) then
      dEndDate := dEndDate - 1;

    // adjust for February
    if (wStartMonth = 2) and (wStartDay = DaysInAMonth(wStartYear, wStartMonth)) then
      FebruaryAdjustment := 30 - wStartDay // Last day of February (either 28 or 29)
    else
      FebruaryAdjustment := 0;

  end else
  begin
    {
     European method.
     Starting dates and ending dates that occur on the 31st of a month become
     equal to the 30th of the same month.
    }

    if wStartDay > 30 Then
      dStartDate := dStartDate - 1;

    if wEndDay > 30 Then
      dEndDate := dEndDate - 1;

    FebruaryAdjustment := 0;
  end;

  Result := (MonthsBetween(dStartDate, dEndDate) * 30) + (wStartDay - wStartDay) - FebruaryAdjustment;
end;

ingabraham 16-08-2010 17:52:14

como se llama esta función?
Method: boolean
que es?
que se le pasa por parametro.

ecfisa 16-08-2010 22:15:15

Cita:

Empezado por ingabraham (Mensaje 373645)
como se llama esta función?
Method: boolean
que es?
que se le pasa por parametro.

Hola ingabraham.

El nombre de la función es Days360, como lo expuso Delphi.com.ar.

Method es un parámetro de tipo Boolean (Verdadero o Falso). Aparentemente, sirve para indicarle
a la función por que método se va a realizar el cálculo: U.S. (NASD) method ó European method



Saludos.

afunez2007 16-08-2010 22:29:04

Cita:

Empezado por delphi.com.ar (Mensaje 372055)
Supongo que será algo como:
Código Delphi [-]function DaysBetween360(const ANow, AThen: TDateTime): Integer; begin Result := (DaysBetween(ANow, AThen) div 30) * 30; end;


Saludos!

La funcion DasyBetween es bastante simple de usar y devuelve la cantidad de dias entre 2 fechas, si tuevieramos dos datetimepcikers por ejemplo seria asi:

Código Delphi [-]
Var
dias: Integer
Begin
 dias:=DaysBetween(Dtp1.Date, Dtp2.date);
end;

Saludos

ingabraham 18-08-2010 22:47:39

NO ME FUNCIONA NINGUNO DE LOS DOS CODIGOS :confused:
Ingresen a excel dos fechas

y en la celda resultado escriban =dias360(f1,f2);

esto es lo que yo quiero obtener en delphi

?????
ayudenme.

afunez2007 18-08-2010 23:31:57

1 Archivos Adjunto(s)
Cita:

Empezado por afunez2007 (Mensaje 373682)
La funcion DasyBetween es bastante simple de usar y devuelve la cantidad de dias entre 2 fechas, si tuevieramos dos datetimepcikers por ejemplo seria asi:

Código Delphi [-]Var dias: Integer Begin dias:=DaysBetween(Dtp1.Date, Dtp2.date); end;


Saludos

Lo probe en excel y en delphi 7, en ambos funciona pero dan 1 dia de diferencia debiado a que excel utiliza meses de 30 dias y delphi utiliza dias reales.

Código Delphi [-]
IntEdit1.Value:=DaysBetween(dtp1.Date , dtp2.Date);
No olvidar poner en las uses DateUtils

Saludos

Caral 18-08-2010 23:56:37

Hola
Código Delphi [-]
procedure TForm1.btn1Click(Sender: TObject);
begin
IntEdit1.Value:=DaysBetween(dtp1.Date , dtp2.Date + 1);
end;
Saludos

ecfisa 19-08-2010 09:42:56

A ver ingabraham... probá con esta función:

Código Delphi [-]
function Dias360(FechaIni,FechaFin: TDateTime; MetodoEuro: Boolean): Longint;
var
  DiaIni, DiaFin: Longint;
begin
  DiaIni:= DayOf(FechaIni);
  DiaFin:= DayOf(FechaFin);
  if not MetodoEuro then
  begin
   if DiaIni = 31 then
     FechaIni:= IncDay(FechaIni, -1);
   if (DiaFin = 31)and(DiaIni = 31) then
     FechaFin:= IncDay(FechaFin, -1)
   else
     if DiaFin = 31 then
       FechaFin:= IncDay(FechaFin, 1);
  end
  else
  begin
    if DiaIni = 31 then
      FechaIni:= IncDay(FechaIni, -1);
    if DiaFin = 31 then
      FechaFin:= IncDay(FechaFin, -1);
  end;
  DiaIni:= DayOf(FechaIni);
  DiaFin:= DayOf(FechaFin);
  if YearOf(FechaFin) > YearOf(FechaIni)  then
    FechaFin:= IncMonth(FechaFin, 1);
  Result:= MonthsBetween(FechaIni, FechaFin)* 30 + DiaFin - DiaIni;
end;

Al igual que la de Federico es una traducción.

No uso Microsoft Office por lo que no puedo probarla con Excel, pero pareciera funcionar.

De no ser así, con todo lo que te han posteado, tenés una buena base para desarrollarla
por vos mismo. Al fín y al cabo, sos el interesado ¿no ? :D

Por supuesto, cuando esté funcionando, todos te vamos a agradecer el aporte si decidís compartirlo. :)

Saludos.

ingabraham 20-08-2010 00:11:58

hola gracias por el codigo, lo probare.
a mis compañeros que me mencionan la funcion DaysBetween

prueben con 22 febrero del 2010 y 10 agosto 2010

dias360 excel da 168

DaysBetween delphi da 169


casi pega en el blanco, lo que no se es si con un rango de fecha mas grande existan más dias de diferencia.

ingabraham 20-08-2010 00:56:29

hola gracias por el codigo, pero nda, no me funciona.

a mis compañeros que me mencionan la funcion DaysBetween

prueben con
22 -02--2010 y 10-08-2010
dias360 excel da 168
DaysBetween delphi da 169

diferencia 1 dia

06 -11-2009 y 30-07-2010
dias360 excel da 264
DaysBetween delphi da 266

diferencia 2 dias


28-03-2010 y 10-08-2010
dias360 excel da 132
DaysBetween delphi da 135

diferencia 3 dias

ingabraham 10-09-2010 17:50:57

diferencia de dias , suponiendo que los meses son de 30 dias.
 
necesito un algoritmo para calcular la diferencia de dias entre dos fechas

partiendo de que cada mes tiene 30 dias y año 360.

Casimiro Notevi 10-09-2010 17:52:46

Pues entonces sólo has de dividir entre 30 :)

ingabraham 10-09-2010 18:03:20

Cita:

Empezado por Casimiro Notevi (Mensaje 376008)
Pues entonces sólo has de dividir entre 30 :)

como asi,
ej.

31.01.2010
al
15.09.2010

o

27.02.2010
al
15.09..2010

ecfisa 10-09-2010 18:18:50

Hola.

Este tema ya se trató aca .

Saludos.

Casimiro Notevi 10-09-2010 18:29:33

ingabraham, si no has conseguido resolver el problema, no inicies un nuevo hilo, sigue con el que estabas, gracias.

Ya he unido los dos en uno sólo.

ecfisa 10-09-2010 18:37:35

Gracias Casimiro.

Avisé para evitar múltiples resultados de un mismo tema en las busquedas.

Saludos. :)

Casimiro Notevi 10-09-2010 18:48:23

Cita:

Empezado por ecfisa (Mensaje 376018)
Gracias Casimiro.
Avisé para evitar múltiples resultados de un mismo tema en las busquedas.
Saludos. :)

Claro, de la otra forma nos quedamos con temas sin solucionar, hay que continuar en el mismo hasta que esté resuelto el problema. Gracias.

ingabraham 10-09-2010 21:55:39

y si nadi me da la idea de como hacer un algoritmo para esto, lo planteo de otra forma.

ingabraham 10-09-2010 22:14:04

los dias son 30 dias de cada mes.
de los 12 meses.

existen 360 dias al año-

hay q hacer un algoritmo para obtener la dif de dias basandose en estos datos.

Hellpppp.-

Casimiro Notevi 10-09-2010 23:08:03

El problema es que no sabemos qué hace exactamente esa función days360.
Pero se supone que si cuentas los días que hay entre dos fechas, qué hace, calcular todos los meses a 30 días?, es que si es así, entonces no se puede usar daysbetween, salvo que luego restemos los días de meses de 31 días y sumemos las de febrero, teniendo en cuenta si ese año es bisiesto.
No sé, me da la sensación de estar sumando peras y manzanas, algo no cuadra.

ingabraham 11-09-2010 03:26:10

tengo una idea, es la siguiente

supongamos que las fechas son 1 enero a al 31 agosto.
algoritmo seria

diferencia de dias con el DaysBetween

luego
recorrer desde la fi, hasta la final
y hacer lo siguiente

ciclo

if fi[mes1 ( maximo dia ) ]== 31
cuentadias = cuentadias -1

fi[mes1 ( maximo dia ) ]== 28
cuentadias = cuentadias +2

fi[mes1 ( maximo dia ) ]== 29
cuentadias = cuentadias + 1

fciclo
dias+cuenta
y creo q ya.

pero como recorro estos meses de la fi, a la ff.?

espero q me hayan entendido.

nota: la idea es calcular sin importar los 30 dias de cada mes
luego recorrer esos meses y si hay q agregarle se agrega y si hay q quitarles se le quita.

ecfisa 11-09-2010 06:50:26

Hola ingabraham.

Busqué y encontré código de días360, sobre todo en VB, y ningúno funcionó. Es más, ni siquiera arrimaban a un resultado coherente, DaysBetween aproximaba mejor.

Así que pasé el borrador sobre lo leido, dejé de perder el tiempo e hice la función desde cero.
No sé si es buen código... seguramente algún compañero con mas luces que yo ( y reconozco que son muchos :o ) pueda optimizarlo.

Pero bueno, hace lo que tiene que hacer. Al menos hasta que se demuestre lo contrario... :p
Código Delphi [-]
function Dias360(Des,Has: TDateTime): Integer;
begin
  if Abs(YearOf(Has)-YearOf(Des)) = 0 then
    Result:= 30-DayOf(Des)+
             (Abs(MonthOf(Des)-MonthOf(Has))-1)*30+DayOf(Has)
  else
  begin
    Result:= Abs(YearOf(Has)-YearOf(Des)-1)*360+
             360-MonthOf(Des)*30+30-DayOf(Des)+
             (MonthOf(Has)-1)*30+DayOf(Has)
  end
end;

Saludos.:)

Casimiro Notevi 11-09-2010 10:05:36

Cita:

Empezado por ecfisa (Mensaje 376064)
[..] Busqué y encontré código de días360, sobre todo en VB, y ningúno funcionó. Es más, ni siquiera arrimaban a un resultado coherente, DaysBetween aproximaba mejor.[..]

Incluso microsoft se equivocó en algunas versiones de excel con su función days360 y luego lo han modificado varias veces hasta dejarlo como está ahora.

ecfisa 11-09-2010 18:02:08

Cita:

Empezado por Casimiro Notevi (Mensaje 376065)
Incluso microsoft se equivocó en algunas versiones de excel con su función days360 y luego lo han modificado varias veces hasta dejarlo como está ahora.

Como verás Casimiro, equivocarse no es exclusividad de microsof, pero mía sí ... :D

Acabo de corregir un pif de la función que escribí. Lo dá cuando el día ingresado en la fecha inicial es 31, por suerte es fácil de corregir.

Queda así:
Código Delphi [-]
function Dias360(Des,Has: TDateTime): Integer;
begin
  if DayOf(Des) = 31 then Des:= IncDay(Des, -1); // Línea agregada
  if Abs(YearOf(Has)-YearOf(Des)) = 0 then
    Result:= 30-DayOf(Des)+
             (Abs(MonthOf(Des)-MonthOf(Has))-1)*30+DayOf(Has)
  else
  begin
    Result:= Abs(YearOf(Has)-YearOf(Des)-1)*360+
             360-MonthOf(Des)*30+30-DayOf(Des)+
             (MonthOf(Has)-1)*30+DayOf(Has)
  end
end;

Saludos. :)

Casimiro Notevi 11-09-2010 20:28:22

Cita:

Empezado por ecfisa (Mensaje 376083)
Como verás Casimiro, equivocarse no es exclusividad de microsof, pero mía sí ... :D

La diferencia es que ellos son tropecientos mil programadores que cobran una barbaridad, que tienen control de calidad, testeadores, revisores, probadores... o como se les quiera llamar, etc. :)
Por lo tanto, tu código es mucho mejor, más seguro, más eficiente, más económico y no hay que esperar a una versión nueva del programa para solucionar el problemilla, jejeje :)
Y por si fuese poco, tu código es libre como el viento, el de ellos no lo verás jamás aunque pagues por un excel.

ecfisa 12-09-2010 00:35:43

En los parrafos 1 y 3 estoy totalmente de acuerdo con vos.
Ahora en el 2 tengo mis dudas... :D

Gracias Casimiro.:)

ingabraham 12-09-2010 20:57:28

gracias, lo he probado con varias fechas
hasta el momento todo esta bien, no se si depronto con algun rango de fechas podra fallar-

muchas gracias esto era lo que esperaba,
pero me podrias dar una breve explicacion de lo q hicistes q no entendi nda de la funcion de la logica q tiene.

ecfisa 12-09-2010 22:37:48

Hola.

Mirá te documento el código que es la mejor manera que se me ocurre para explicarlo.
Creo que, como a mí, tener un calendario en la mano te va ayudar a entender como es la lógica de dias360.
Código Delphi [-]
function Dias360(Des,Has: TDateTime): Integer;
var
  dd,dm,dh,da: Integer;
begin
  if DayOf(Des) = 31 then Des:= IncDay(Des, -1); // mes de 30 días
  if Abs(YearOf(Has)-YearOf(Des)) = 0 then  // mismo año
  begin
    // días que faltan para completar mes (Des)
    dd:= 30 - DayOf(Des);
    // días comprendidos entre meses
    dm:= (Abs(MonthOf(Des)-MonthOf(Has))-1)*30;
    // días transcurridos del mes (Has)
    dh:= DayOf(Has);
    // sumar días
    Result:= dd + dm + dh;
  end
  else    // años diferentes
  begin
    // días transcurridos entre años
    da:= Abs(YearOf(Has)-YearOf(Des)-1)*360;
    // (total dias del 1 año) - dias transcurridos fecha (Des)
    dd:= 360 - MonthOf(Des)*30;
    // total días transcurridos meses fecha Has + los días fecha (Has)
    dm:= (MonthOf(Has)-1)*30 + DayOf(Has);
    // diás faltantes  para completar mes (Des)
    dh:= 30 - DayOf(Des);
    // sumar días
    Result:= da + dd + dm + dh;
  end
end;

A la reducción de la fórmula llegué simplemente reemplazando las variables por su equivalente, como por ejemplo en:
Código Delphi [-]
     Result:= dd + dm + dh
     // es igua a:
    Result:= 30-DayOf(Des)+(Abs(MonthOf(Des)-MonthOf(Has))-1)*30+DayOf(Has)

Por último, los resultados los cotejé contra el OpenOffice.org.calc.

Saludos.:)


La franja horaria es GMT +2. Ahora son las 18:57:31.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi