Averigüe si el archivo tiene más de 4 horas en el archivo por lotes

Simplemente, ¿cómo puedo averiguar si un archivo específico en una carpeta es anterior a X horas? El nombre y la ubicación del archivo siempre serán los mismos.

Gracias

Al comparar los tiempos de archivo con el siguiente código de lote debe tenerse en cuenta:

  1. Configuraciones de formato de fecha y hora
  2. Sistema de archivos de medios de almacenamiento
  3. Huso horario, horario de verano
  4. Ajuste automático para el horario de verano
  5. Versión de Windows

1. Configuraciones de formato de fecha y hora

Existen las variables de entorno DATE y TIME, que al acceder (y no al inicio de la ejecución por lotes) devuelven la fecha y la hora actuales en un formato que depende de la configuración regional de región y de idioma de Windows . El país define el formato de fecha y hora.

Incluso es posible definir, por ejemplo, el formato de fecha corta alemán con DD.MM.YYYY (día y mes con cero DD.MM.YYYY ) y el formato de hora con HH:mm:ss (formato de 24 horas con cero inicial para hora, minuto y segundo ) Pero esto no significa que el valor de DATE y TIME realmente esté usando este formato. Por ejemplo, TIME está en formato H:mm:ss,ms al seleccionar un país alemán incluso con HH:mm:ss definido, lo que significa cero cero en hora, pero en minutos y segundos, y adicionalmente milisegundos después de una coma en tiempo cadena . La cadena de fecha también puede estar con o sin día de la semana, dependiendo de la configuración de la región.

Y existe el patrón %~t para obtener la última fecha y hora de modificación de un directorio o archivo. Ejecutar en una ventana de símbolo del sistema call /? y for /? y lea todas las páginas de ayuda mostradas para esos dos comandos para más detalles. El formato de la cadena de fecha y hora devuelto por %~t , así como también se muestra en la salida del comando DIR, también depende de la configuración regional de Windows, pero generalmente no es igual al formato de las variables DATE y TIME . La hora de la última modificación de tiempo de un archivo o directorio generalmente se devuelve sin un segundo valor en la cadena de fecha y hora.

Lo mejor es averiguar con el siguiente archivo por lotes que se ejecuta mejor antes de las 10:00 a.m., cuáles son los formatos en la máquina actual para el usuario actual.

 @echo off echo Current date/time: %DATE% %TIME% for %%I in ("%~f0") do echo Batch file time: %%~tI pause 

2. Sistema de archivos de medios de almacenamiento

En los sistemas de archivos de Windows, se utilizan dos formatos de almacenamiento para los tiempos del archivo :

  • En los medios de almacenamiento que utilizan NTFS se utiliza el tiempo de precisión NTFS, que es un número de 64 bits de intervalos de 100 nanosegundos que han transcurrido desde las 12:00 AM del 1 de enero de 1601 Hora universal coordinada (UTC).

  • En los medios de almacenamiento que utilizan FAT, FAT16, FAT32 o exFAT, los tiempos del archivo se almacenan utilizando el formato de fecha y hora de DOS con dos valores de 16 bits con una resolución de 2 segundos y usando la hora local actual.

Esto significa que un segundo impar no es posible para un archivo en medios FAT, sino en medios NTFS. Copiar un archivo en una unidad NTFS con un segundo impar en la última modificación a una unidad FAT32 da como resultado tener archivos idénticos con una diferencia de 1 segundo en la última modificación.

Las horas de archivo en medios NTFS se almacenan en UTC. Entonces, lo que devuelve %~t o el comando DIR , así como lo que se muestra, por ejemplo, en el Explorador de Windows depende de

  • zona horaria actual,
  • horario de verano para esta zona horaria,
  • si la hora actual está dentro del período de horario de verano,
  • y si el ajuste automático para el horario de verano está habilitado actualmente.

Al cambiar cualquiera de estos 4 parámetros, se produce un cambio inmediato de TODOS los archivos mostrados de los archivos y directorios en los medios de almacenamiento NTFS.

Los tiempos de archivo en los medios FAT son más o menos constantes, ya que utilizan la hora local en la creación, modificación o último acceso, pero continúen leyendo para más detalles.


3. Zona horaria, horario de verano

Como las horas de archivo en medios NTFS se almacenan en UTC, pero se muestran en la hora local, la zona horaria actual y el horario de verano para esta zona horaria son importantes para las comparaciones de tiempo de archivo, especialmente cuando se realizan archivos en unidades NTFS y FAT32.

Pero también para archivos en un medio FAT, la configuración de zona horaria y horario de verano podría ser importante dependiendo de la versión de Windows. Lea a continuación para más detalles.


4. Ajuste automático para el horario de verano

Existe la configuración para el ajuste automático del horario de verano, que se vuelve importante cuando se habilita de manera predeterminada y la zona horaria configurada actualmente define un ajuste de horario de verano.

Por ejemplo, el horario de verano está activo actualmente en Europa. Al deshabilitar esta opción en la configuración de reloj de Windows, se produce un cambio inmediato de las horas de archivo mostradas en medios NTFS por -1 hora, y también muchos archivos en medios FAT dependiendo de la versión de Windows.

Esta diferencia horaria de 1 hora causada por el ajuste del horario de verano debe tenerse en cuenta al comparar las horas de archivo en los medios NTFS y FAT.


5. Versión de Windows

NTFS es compatible con todas las versiones de Windows NT. El comportamiento de los tiempos de archivo es igual para los archivos y directorios en todas las versiones de Windows compatibles con NTFS.

Pero cómo se interpretan los tiempos de archivo en los medios FAT depende de la versión de Windows. Con anterioridad a Windows Vista, las horas de archivo en los medios FAT son independientes en el cambio de zona horaria, la configuración del horario de verano y el ajuste automático del horario de verano. La última fecha / hora de modificación de un archivo es constante en Windows 2000 y Windows XP.

Pero en Windows Vista y posteriores, los tiempos de archivo visualizados en los medios FAT dependen del horario de verano y del ajuste automático del horario de verano. La zona horaria no importa directamente. Seleccionar otra zona horaria como se usa actualmente no cambia los tiempos de archivo mostrados de los archivos en medios FAT como lo hace para los archivos en medios NTFS. Pero si la hora actual está dentro del período de horario de verano de la zona horaria activa y el ajuste automático del horario de verano está habilitado y la hora local del archivo o directorio está dentro del período de horario de verano, Windows Vista agrega +1 hora y después. Los archivos modificados por última vez en unidades FAT dentro del tiempo estándar son constantes a lo largo del año; solo los archivos modificados por última vez dentro del período de DST se muestran con o sin +1 hora, dependiendo de la hora actual con el ajuste de horario de verano automático habilitado.

Esa gestión de tiempo de archivos FAT diferente puede ser extremadamente confusa cuando se tiene, por ejemplo, una participación pública de una carpeta en una unidad FAT32 en una máquina con Windows 7 y se está conectado a esta carpeta pública con una máquina con Windows XP. Un archivo modificado por última vez en 2015-09-19 17:39:08 almacenado en la unidad FAT32 en Windows 7 PC se muestra hoy en día por Windows 7 con zona horaria alemana con fecha de archivo 19.09.2015 17:39:08, pero en 2 meses aunque no modificado con 19.09.2015 16:39:08, y Windows XP muestra el mismo archivo en PC con Windows 7 conectado hoy y en el futuro constante con tiempo de archivo 19.09.2015 17:39:08.

Comparar los tiempos de archivo de los archivos almacenados en archivos (ZIP, RAR, …) con archivos en medios NTFS o FAT puede ser realmente una pesadilla.


6. Comparando la hora del archivo con la hora actual

Para esta tarea que compara el tiempo de última modificación de un archivo con la hora actual, debería ser suficiente para tener en cuenta las configuraciones de formato de fecha y hora.

El código de lote que se muestra a continuación usa el código explicado en detalle en mi respuesta en el archivo por lotes para eliminar archivos anteriores a N días . Esta explicación debe leerse antes de usar el código a continuación.

Dependiendo del formato de fecha / hora de las variables DATE y TIME y de la cadena de fecha / hora devuelta por %~tI para el archivo en la PC con Windows local, podría ser necesario hacer pequeñas modificaciones al código. Se dan sugerencias apropiadas en las líneas de comentario del código de lote.

 @echo off setlocal EnableExtensions rem Get seconds since 1970-01-01 for current date and time. rem From date string only the last 10 characters are passed to GetSeconds rem which results in passing dd/mm/yyyy or dd.mm.yyyy in expected format rem to this subroutine independent on date string of environment variable rem DATE is with or without abbreviated weekday at beginning. call :GetSeconds "%DATE:~-10% %TIME%" rem Subtract seconds for 4 hours (4 * 3600 seconds) from seconds value. set /A "CompareTime=Seconds-4*3600" rem Define batch file itself as the file to compare time by default. set "FileToCompareTime=%~f0" rem If batch file is started with a parameter and the parameter rem specifies an existing file (or directory), compare with last rem modification date of this file. if not "%~1" == "" ( if exist "%~1" set "FileToCompareTime=%~1" ) rem Get seconds value for the specified file. for %%F in ("%FileToCompareTime%") do call :GetSeconds "%%~tF:0" rem Compare the two seconds values. if %Seconds% LSS %CompareTime% ( echo File %FileToCompareTime% was last modified for more than 4 hours. ) else ( echo File %FileToCompareTime% was last modified within the last 4 hours. ) endlocal goto :EOF rem No validation is made for best performance. So make sure that date rem and hour in string is in a format supported by the code below like rem MM/DD/YYYY hh:mm:ss or M/D/YYYY h:m:s for English US date/time. :GetSeconds rem If there is " AM" or " PM" in time string because of using 12 hour rem time format, remove those 2 strings and in case of " PM" remember rem that 12 hours must be added to the hour depending on hour value. set "DateTime=%~1" set "Add12Hours=0" if "%DateTime: AM=%" NEQ "%DateTime%" ( set "DateTime=%DateTime: AM=%" ) else if "%DateTime: PM=%" NEQ "%DateTime%" ( set "DateTime=%DateTime: PM=%" set "Add12Hours=1" ) rem Get year, month, day, hour, minute and second from first parameter. for /F "tokens=1-6 delims=,-./: " %%A in ("%DateTime%") do ( rem For English US date MM/DD/YYYY or M/D/YYYY set "Day=%%B" & set "Month=%%A" & set "Year=%%C" rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY rem set "Day=%%A" & set "Month=%%B" & set "Year=%%C" set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F" ) rem Remove leading zeros from the date/time values or calculation could be wrong. if "%Month:~0,1%" EQU "0" ( if "%Month:~1%" NEQ "" set "Month=%Month:~1%" ) if "%Day:~0,1%" EQU "0" ( if "%Day:~1%" NEQ "" set "Day=%Day:~1%" ) if "%Hour:~0,1%" EQU "0" ( if "%Hour:~1%" NEQ "" set "Hour=%Hour:~1%" ) if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" ) if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" ) rem Add 12 hours for time range 01:00:00 PM to 11:59:59 PM, rem but keep the hour as is for 12:00:00 PM to 12:59:59 PM. if "%Add12Hours%" == "1" ( if %Hour% LSS 12 set /A Hour+=12 ) set "DateTime=" set "Add12Hours=" rem Must use 2 arrays as more than 31 tokens are not supported rem by command line interpreter cmd.exe respectively command FOR. set /A "Index1=Year-1979" set /A "Index2=Index1-30" if %Index1% LEQ 30 ( rem Get number of days to year for the years 1980 to 2009. for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y" for /F "tokens=%Index1% delims= " %%L in ("YNNNYNNNYNNNYNNNYNNNY NNNYNNNYN") do set "LeapYear=%%L" ) else ( rem Get number of days to year for the years 2010 to 2038. for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y" for /F "tokens=%Index2% delims= " %%L in ("NNYNNNYNNNYNNNYNNNYNN NYNNNYNN") do set "LeapYear=%%L" ) rem Add the days to month in year. if "%LeapYear%" == "N" ( for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M" ) else ( for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M" ) rem Add the complete days in month of year. set /A "Days+=Day-1" rem Calculate the seconds which is easy now. set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second" rem Exit this subroutine goto :EOF 

rojo agregó información sobre cómo se pueden ignorar las configuraciones de formato de fecha y hora, el sistema de archivos y la versión de Windows utilizando wmic , la utilidad de línea de comandos de Windows Management Instrumentation.

El uso de wmic tiene la ventaja de tener un formato fijo para las cadenas de fecha / hora y, por lo tanto, el código de lote funciona en todas las computadoras con Windows sin adaptaciones al formato de fecha / hora local.

Además, la versión de Windows no importa el uso de wmic debido al uso interno de la función GetFileTime (lo más probable).

El sistema de archivos solo es importante al evaluar también el desplazamiento de minutos de hora local / hora de archivo a UTC. El comando wmic regresa en las unidades FAT solo +*** para la compensación de minutos a UTC, mientras que la compensación de minutos es correcta para la última hora del archivo de modificación de un archivo en una unidad NTFS.

Ejemplo para el mismo archivo en la unidad NTFS y FAT32:

 NTFS: 20071011192622.000000+120 FAT32: 20071011192622.000000+*** 

+120 es la sum de +60 minutos para CET (hora de Europa Central) y +60 minutos para el horario de verano activo, o en otras palabras, +120 minutos para CEST (horario de verano de Europa Central).

Por lo tanto, el código de lote siguiente no evalúa los minutos compensados ​​con UTC, que no es necesario al comparar la última hora del archivo de modificación de un archivo con la hora local actual.

Además, el nombre del archivo debe especificarse siempre con la ruta completa en la línea de comandos de wmic . Solo especificar el nombre de archivo para un archivo en el directorio actual o un nombre de archivo con ruta relativa no funciona. Y cada barra invertida se debe escapar con una barra invertida más en el nombre del archivo con la ruta.

La principal desventaja en el uso de wmic es la velocidad. El código de lote anterior necesita en mi computadora unos 50 ms para terminar de acuerdo con el registro del Monitor de procesos (promedio de varias ejecuciones). El código del lote que se encuentra debajo de llamar a wmic dos veces necesita para la misma tarea aproximadamente 1500 ms para finalizar (también un valor promedio). Por lo tanto, usar wmic en una gran cantidad de archivos definitivamente no es una buena idea si se puede evitar porque se conoce el formato de fecha / hora local.

 @echo off setlocal EnableExtensions rem Get seconds since 1970-01-01 for current date and time. for /F "tokens=2 delims==." %%T in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do call :GetSeconds %%T rem Subtract seconds for 4 hours (4 * 3600 seconds) from seconds value. set /A "CompareTime=Seconds-4*3600" rem Define batch file itself as the file to compare time by default. set "FileToCompareTime=%~f0" rem If batch file is started with a parameter and the parameter rem specifies an existing file (or directory), compare with last rem modification date of this file. if not "%~1" == "" ( if exist "%~f1" set "FileToCompareTime=%~f1" ) rem Get seconds value for the specified file. set "DataFile=%FileToCompareTime:\=\\%" for /F "usebackq tokens=2 delims==." %%T in (`%SystemRoot%\System32\wbem\wmic.exe DATAFILE where "name='%DataFile%'" GET LastModified /VALUE`) do echo call :GetSeconds %%T rem Compare the two seconds values. if %Seconds% LSS %CompareTime% ( echo File %FileToCompareTime% was last modified for more than 4 hours. ) else ( echo File %FileToCompareTime% was last modified within the last 4 hours. ) endlocal goto :EOF rem Date/time format used by the command line utility of Windows rem Management Instrumentation is always YYYYMMDDHHmmss with a rem dot and a 6 digit microsecond value and plus/minus 3 digit rem time offset to UTC in minutes independent on region and rem language settings. Microsecond is always 000000 for a file rem time. The minutes offset including time zone offset and rem current daylight saving time offset is returned for a file rem time only for a file on an NTFS drive. Minutes offset is rem +*** for a file on a FAT drive (at least on Windows XP). :GetSeconds rem Get year, month, day, hour, minute and second from first parameter. set "DateTime=%~1" set "Year=%DateTime:~0,4%" set "Month=%DateTime:~4,2%" set "Day=%DateTime:~6,2%" set "Hour=%DateTime:~8,2%" set "Minute=%DateTime:~10,2%" set "Second=%DateTime:~12,2%" rem echo Date/time is: %Year%-%Month%-%Day% %Hour%:%Minute%:%Second% rem Remove leading zeros from the date/time values or calculation could be wrong. if "%Month:~0,1%" EQU "0" ( if "%Month:~1%" NEQ "" set "Month=%Month:~1%" ) if "%Day:~0,1%" EQU "0" ( if "%Day:~1%" NEQ "" set "Day=%Day:~1%" ) if "%Hour:~0,1%" EQU "0" ( if "%Hour:~1%" NEQ "" set "Hour=%Hour:~1%" ) if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" ) if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" ) rem Must use 2 arrays as more than 31 tokens are not supported rem by command line interpreter cmd.exe respectively command FOR. set /A "Index1=Year-1979" set /A "Index2=Index1-30" if %Index1% LEQ 30 ( rem Get number of days to year for the years 1980 to 2009. for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y" for /F "tokens=%Index1% delims= " %%L in ("YNNNYNNNYNNNYNNNYNNNY NNNYNNNYN") do set "LeapYear=%%L" ) else ( rem Get number of days to year for the years 2010 to 2038. for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y" for /F "tokens=%Index2% delims= " %%L in ("NNYNNNYNNNYNNNYNNNYNN NYNNNYNN") do set "LeapYear=%%L" ) rem Add the days to month in year. if "%LeapYear%" == "N" ( for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M" ) else ( for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M" ) rem Add the complete days in month of year. set /A "Days+=Day-1" rem Calculate the seconds which is easy now. set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second" rem Exit this subroutine goto :EOF 

Alternativamente, podrías crear un progtwig simple usando C # por ejemplo así:

 // compile using c:\Windows\Microsoft.NET\Framework\v3.5\csc FileByAge.cs using System; using System.IO; public static class Program { public static void Main(string[] args) { double age = double.Parse(args[0]); string fileName; while ((fileName = Console.ReadLine()) != null) { if(age >= (DateTime.Now - new FileInfo(fileName).CreationTime).TotalHours) { continue; } Console.WriteLine(fileName); } } } 

Ese progtwig podría usarse para encontrar todos los archivos que tienen más de 2 horas dentro de un archivo por lotes como ese:

 for /F "delims=" %f in ('dir /B *.txt^|FileByAge.exe 2') do echo %f 

Una versión mejorada y auto comstackda

Como lo menciona @Paul, uno podría incluso crear un archivo híbrido hacky batch / c # que se comstackrá y ejecutará solo:

 @echo off setlocal set CsFile=%TEMP%\%~n0.cs set ExeFile=%TEMP%\%~n0.exe pushd %SystemRoot%\Microsoft.NET\Framework for /F %%f in ('dir /B /O:-N v*') do cd %%f & goto :BreakLoop; :BreakLoop (echo /* & type "%~f0") > "%CsFile%" csc.exe /nologo /out:"%ExeFile%" "%CsFile%" del "%CsFile%" popd more | "%ExeFile%" %* del "%ExeFile%" endlocal goto:eof */ using System; using System.IO; public static class Program { public static void Main(string[] args) { var olderThen = args[0].Contains("older"); var targetAge = double.Parse(args[1]); string fileName; while ((fileName = Console.ReadLine()) != null) { if (string.Empty == fileName) { continue; } var fileAge = (DateTime.Now - new FileInfo(fileName).CreationTime).TotalHours; if (olderThen ? targetAge > fileAge : targetAge < fileAge) { continue; } Console.WriteLine(fileName); } } } 

Y se puede usar así:

 for /F "delims=" %f in ('dir /B *.txt^|FileByAge.bat older 2') do echo %f 

La solución a esto dependerá en gran medida del intervalo de tiempo esperado, ya que AFAIK no obtiene el tiempo como un entero en un archivo por lotes sin progtwigs externos. Esto significa que debe analizar el valor del tiempo en su secuencia de comandos, y la cantidad de análisis y la cantidad de cálculos necesarios dependen del rango para el que lo necesite. Aquí hay una solución simple. Supone que el archivo NO puede tener más de 24 horas.

 set "filename=myfile.txt" rem extract current date and time for /f "tokens=1-5 delims=.:, " %%a in ("%date% %time%") do ( set day=%%a&set mon=%%b&set yr=%%c&set hr=%%d&set min=%%e ) rem extract file date and time for /f "tokens=1-5 delims=.:, " %%a in ('"dir %filename%|find "%filename%""') do ( set fday=%%a&set fmon=%%b&set fyr=%%c&set fhr=%%d&set fmin=%%e ) rem calculate age of file (in minutes) set /a "age=((hr*60+min)-(fhr*60+fmin)+(24*60))%%(24*60)" set /a "max=4*60" if %age% geq %max% echo.file is older than 4 hours 

El lote puro es horrible en matemáticas de fecha. ¿Qué sucede si tu script se ejecuta poco después de la medianoche? ¿Qué pasa si la verificación de tiempo abarca un cambio en el horario de verano?

Propongo invocar Windows Script Host y tomar prestado de un lenguaje que maneja mejor las matemáticas de fecha / hora. Aquí hay una secuencia de comandos híbrida por lotes / JScript que calculará la edad de un archivo o directorio con bastante facilidad. Guárdalo con una extensión .bat y pruébalo.

 @if (@CodeSection==@Batch) @then @echo off setlocal set "file=C:\Path\To\File.ext" for /f %%I in ('cscript /nologo /e:JScript "%~f0" "%file%"') do ( rem // value contained in %%I is in minutes. if %%I gtr 240 ( echo %file% is over 4 hours old. rem // do stuff here to take whatever actions you wish rem // if the file is over 4 hours old. ) ) goto :EOF @end // end batch portion / begin JScript hybrid chimera var fso = new ActiveXObject("scripting.filesystemobject"), arg = WSH.Arguments(0), file = fso.FileExists(arg) ? fso.GetFile(arg) : fso.GetFolder(arg); // Use either DateCreated, DateLastAccessed, or DateLastModified. // See http://msdn.microsoft.com/en-us/library/1ft05taf%28v=vs.84%29.aspx // for more info. var age = new Date() - file.DateLastModified; WSH.Echo(Math.floor(age / 1000 / 60)); 

Para obtener más información sobre scripts híbridos batch / JScript, consulte esta página de GitHub . El estilo utilizado anteriormente es similar a Hybrid.bat en esa página. Esta respuesta se basa en otra . Por lo que vale, PowerShell también es bueno en el manejo de las matemáticas de fecha; pero WSH se ejecuta mucho más rápido.