Esta es la decimotercera entrega de la serie sobre utilidades para Business Central. En esta ocasión comparto un bloque completo de funciones para calcular diferencias entre fechas y datetimes. Cada función viene con dos sobrecargas: una con un parámetro (compara contra la fecha base 01/01/1900) y otra con dos parámetros (compara entre dos valores concretos).
¡Vamos manos a la obra! 📆
📅 Diferencia entre fechas en días: SubtractTwoDateReturnDays
procedure SubtractTwoDateReturnDays(ValueDate1: Date) ReturnValue: Integer
var
ValueDate2: Date;
begin
Clear(ValueDate2);
ReturnValue := this.SubtractTwoDateReturnDays(ValueDate1, ValueDate2);
end;
procedure SubtractTwoDateReturnDays(ValueDate1: Date; ValueDate2: Date) ReturnValue: Integer
begin
if ValueDate1 = 0D then
ValueDate1 := DMY2Date(1, 1, 1900);
if ValueDate2 = 0D then
ValueDate2 := DMY2Date(1, 1, 1900);
ReturnValue := ValueDate1 - ValueDate2;
end;
¿Qué hace esta función?
Devuelve la diferencia en días entre dos fechas como un Integer. Si alguna de las fechas es vacía (0D), se sustituye automáticamente por el 01/01/1900 como valor base.
- Sobrecarga con 1 parámetro: compara
ValueDate1contra el 01/01/1900. - Sobrecarga con 2 parámetros: compara
ValueDate1contraValueDate2.
📅 Diferencia entre fechas como Date: SubtractTwoDatesReturnAsDate
procedure SubtractTwoDatesReturnAsDate(ValueDate1: Date) ReturnValue: Date
var
ValueDate2: Date;
begin
Clear(ValueDate2);
ReturnValue := this.SubtractTwoDatesReturnAsDate(ValueDate1, ValueDate2);
end;
procedure SubtractTwoDatesReturnAsDate(ValueDate1: Date; ValueDate2: Date) ReturnValue: Date
var
DaysDiff: Integer;
begin
DaysDiff := this.SubtractTwoDateReturnDays(ValueDate1, ValueDate2);
ReturnValue := DMY2Date(1, 1, 1900) + DaysDiff;
end;
¿Qué hace esta función?
Similar a la anterior, pero el resultado se devuelve como un tipo Date en lugar de Integer. Internamente calcula los días de diferencia y los suma a la fecha base 01/01/1900, generando así un valor Date que representa la duración.
Útil cuando se necesita mostrar la diferencia como fecha en un campo o página, o cuando se quiere operar sobre ella con funciones de fecha de AL.
⏱ Diferencia entre DateTimes en milisegundos: SubtractTwoDateTimesReturnMilliseconds
procedure SubtractTwoDateTimesReturnMilliseconds(ValueDateTime1: DateTime) ReturnValue: BigInteger
var
ValueDateTime2: DateTime;
begin
Clear(ValueDateTime2);
ReturnValue := this.SubtractTwoDateTimesReturnMilliseconds(ValueDateTime1, ValueDateTime2);
end;
procedure SubtractTwoDateTimesReturnMilliseconds(ValueDateTime1: DateTime; ValueDateTime2: DateTime) ReturnValue: BigInteger
var
DurationDiff: Duration;
begin
Clear(ReturnValue);
if ValueDateTime1 = 0DT then
ValueDateTime1 := CreateDateTime(DMY2Date(1, 1, 1900), 000000T);
if ValueDateTime2 = 0DT then
ValueDateTime2 := CreateDateTime(DMY2Date(1, 1, 1900), 000000T);
DurationDiff := ValueDateTime1 - ValueDateTime2;
ReturnValue := (DurationDiff div 1); // Duration en milisegundos
end;
¿Qué hace esta función?
Calcula la diferencia entre dos valores DateTime y la devuelve en milisegundos como BigInteger. El tipo Duration en AL es precisamente la diferencia entre dos DateTime, expresada en milisegundos.
- Los valores vacíos (
0DT) se sustituyen por el DateTime base: 01/01/1900 00:00:00. - El resultado puede ser negativo si
ValueDateTime1es anterior aValueDateTime2.
⏱ Diferencia entre DateTimes como DateTime: SubtractTwoDateTimesReturnAsDateTimeFromMilliseconds
procedure SubtractTwoDateTimesReturnAsDateTimeFromMilliseconds(ValueDateTime1: DateTime) ReturnValue: DateTime
var
ValueDateTime2: DateTime;
begin
Clear(ValueDateTime2);
ReturnValue := this.SubtractTwoDateTimesReturnAsDateTimeFromMilliseconds(ValueDateTime1, ValueDateTime2);
end;
procedure SubtractTwoDateTimesReturnAsDateTimeFromMilliseconds(ValueDateTime1: DateTime; ValueDateTime2: DateTime) ReturnValue: DateTime
var
MillisecondsDiff: BigInteger;
BaseDateTime: DateTime;
begin
Clear(ReturnValue);
MillisecondsDiff := this.SubtractTwoDateTimesReturnMilliseconds(ValueDateTime1, ValueDateTime2);
BaseDateTime := CreateDateTime(DMY2Date(1, 1, 1900), 000000T);
ReturnValue := (BaseDateTime + (MillisecondsDiff * 1));
end;
¿Qué hace esta función?
Es la variante que devuelve la diferencia en milisegundos representada de nuevo como DateTime. Calcula los milisegundos de diferencia con la función anterior y los suma al DateTime base (01/01/1900 00:00:00), obteniendo un DateTime que "representa" esa duración.
Especialmente útil cuando necesitas almacenar o mostrar la duración en un campo de tipo DateTime.
💡 Beneficios y aplicaciones prácticas
Este conjunto de funciones es ideal en escenarios como:
- Calcular la antigüedad de un registro (días desde su creación).
- Medir el tiempo transcurrido entre dos eventos en un proceso.
- Calcular duraciones de órdenes de producción, albaranes o documentos.
- Integraciones que necesitan enviar diferencias de tiempo en milisegundos.
- Mostrar la diferencia de fechas en campos calculados de páginas o informes.
El diseño con dos sobrecargas por función aporta flexibilidad: si solo tienes una fecha de referencia, llamas con un parámetro; si tienes las dos, las pasas ambas.
Conclusión
En esta decimotercera entrega de la serie Utils, presento un bloque completo de funciones para calcular diferencias entre fechas y datetimes en AL. Cada función viene en dos variantes para adaptarse a distintos casos de uso, devolviendo el resultado como entero, como fecha o como DateTime según la necesidad.
Para seguir todos los posts de esta serie, puedes encontrarlos bajo la etiqueta #UtilsBc.
Si quieres ver el código completo, está en GitHub.
¡Nos vemos en la próxima!