it-swarm-es.tech

Herramienta en UNIX para restar fechas

¿Hay alguna herramienta en Solaris UNIX (entonces no GNU disponible) para restar fechas? Sé que en Linux tenemos gawk que puede restar una fecha de otra. Pero en Solaris lo máximo que tenemos es nawk (mejorado awk) que no puede realizar cálculos de fechas. Tampoco puedo usar Perl.

¿Hay alguna manera de hacer cálculos de fechas como 20100909 - 20001010?

ACTUALIZACIÓN: ¿Puede bc realizar cálculos de fechas?

23
jyz

Aquí hay un script awk que acabo de escribir, debería funcionar con un POSIX awk. Tendrá que probar la versión de Solaris; recuerde que también hay dos versiones de Awk en Solaris, una en/bin y otra en/usr/xpg4/bin/awk (que creo que es nawk).

BEGIN {
    daysofmonth["01"] = 0; daysofmonth["02"] = 31; daysofmonth["03"] = 59;
    daysofmonth["04"] = 90; daysofmonth["05"] = 120; daysofmonth["06"] = 151;
    daysofmonth["07"] = 181; daysofmonth["08"] = 212; daysofmonth["09"] = 243;
    daysofmonth["10"] = 273; daysofmonth["11"] = 304; daysofmonth["12"] = 334;
    fullday = 86400;
}
/[12][09][0-9][0-9][01][0-9][0123][0-9]/ {
    year = substr($0, 1, 4); month = substr($0, 5, 2); day = substr($0, 7, 2);
    date = ((year - 1970) * 365.25) + daysofmonth[month] + day - 1;
    if ((year % 4) == 0 && month > 2) { date = date + 1; }
    print date * fullday - (25200);
}
{}

Pase una cadena de fecha AAAAMMdd y se convertirá a la cantidad de segundos desde la Época (con un poco de donación por estar en los límites del día). Entonces podrás restar los dos.

today=`echo 20110210 | awk -f convdate.awk`
then=`echo 20001231 | awk -f convdate.awk`
sincethen=`expr $today - $then`
10
Arcege

Desafortunadamente, ninguna de las utilidades de línea de comando POSIX proporciona aritmética en fechas. date -d y date +%s son el camino a seguir si los tiene, pero son GNU extensiones.

Hay un truco torpe con touch que funciona para comprobar que una fecha tiene al menos n días en el pasado:

touch -t 201009090000 stamp
if [ -n "$(find stamp -mtime +42)" ]; then ...

(Tenga en cuenta que este código puede estar desactivado por uno si el horario de verano comenzó o se detuvo en el intervalo y el script se ejecuta antes de la 1 a.m.)

Varias personas han terminado implementando bibliotecas de manipulación de fechas en Bourne o POSIX Shell. Hay algunos ejemplos y enlaces en comp.unix.Shell FAQ .

Instalar las herramientas GNU) puede ser la forma de menos dolor.

Intentaría usar el comando date que es parte de POSIX, por lo que está en casi todas partes. ACTUALIZACIÓN: Desafortunadamente, parece que -d no es parte de la fecha POSIX y probablemente no esté en Solaris. Por lo tanto, esto probablemente no responderá a la pregunta de los OP.

d1=`date -d 20100909 +%s`
d2=`date -d 20001010 +%s`

Ahora d1 Y d2 Son enteros que corresponden a segundos desde la época de Unix. Por lo tanto, para obtener la diferencia entre los dos, restamos ($((d1-d2)) en bash) y ocultamos las unidades que queramos. Los días son los más fáciles:

echo "$(((d1-d2)/86400)) days"

La forma de hacer la conversión probablemente será diferente si no tienes bash. La forma más portátil puede ser usar expr ( página de manual de posix de expr ).

11
Steven D

Para el registro, dateutils es mi intento de proporcionar un conjunto de herramientas portátiles que cubran la aritmética de fechas. Tu ejemplo se reduce a

ddiff -i '%Y%m%d' 20001010 20100909
=>
  3621

Los -i especifica el formato de entrada.

8
hroptatyr

Es probable que se instale Perl, y es bastante fácil tomar módulos de CPAN , instalarlos en su directorio de inicio y consultarlos en su programa. En este caso, el módulo Fecha :: Calc tiene un Delta_Days subrutina que ayudará.

4
glenn jackman

Wrt GNU fecha en Solaris:

Digo esto otra vez:

Demasiados Solaris SysAdmins se enorgullecen de no instalar deliberadamente los paquetes oficiales de Sun (ahora Oracle) que hacen que un sistema Solaris sea "compatible con GNU" cuando configuran un nuevo Host. Me gana por qué.

GNU Date es excelente y debería estar disponible de forma predeterminada en cualquier host Solaris, en mi humilde opinión.

En Solaris 10

Instale el paquete SFWcoreu desde el CD Solaris Companion. Después de la instalación, encontrará GNU fecha en /opt/sfw/bin/date

En Solaris 11

Es posible que ya lo tenga, ya que creo que es parte de la instalación estándar. Sin embargo, se llama gdate para distinguirlo de la versión de fecha de Sun.

Haga esto si no está instalado:

pkg install // solaris/file/gnu-coreutils
3
peterh

Si tienes Python:

from time import *
date1 = strptime("20100909","%Y%m%d")
date2 = strptime("20001010","%Y%m%d")
diff = mktime(date1) - mktime(date2)
print repr(d/86400) + " days"

Etiquetó su pregunta "gawk" pero dice "no GNU tools". Gawk tiene aritmética de fechas).

pitón:

 from datetime import datetime as dt
 a = dt(2010, 9, 9)
 b = dt(2000, 10, 10)
 print (a - b).days
2
akira

1. Defina date1 y date2 en %j formato del día del año (001..366)

[email protected]:~$ date1=`date -d 20100909 +%j` 
[email protected]:~$ date2=`date -d 20001010 +%j`

2. Calcule la diferencia con expr

[email protected]:~$ datediff=`expr $date2 - $date1`

. Entonces, la respuesta es 32 días

[email protected]:~$ echo $datediff days
32 days
[email protected]:~$ 

... o solución de una línea

[email protected]:~$ echo $(( $(date -d 20001010 +%j) - $(date -d 20100909 +%j) )) days
32 days
[email protected]:~$ 

o

[email protected]:~$ expr $(date -d 20001010 +%j) - $(date -d 20100909 +%j)
32
[email protected]:~$

o

[email protected]:~$ expr `date -d 20001010 +%j` - `date -d 20100909 +%j`
32
[email protected]:~$ 
1
Sabrina

Puede usar awk Velour library para devolver la diferencia en segundos:

$ velour -n 'print t_utc(2010, 9, 9) - t_utc(2000, 10, 10)'
312854400

O días:

$ velour -n 'print t_secday(t_utc(2010, 9, 9) - t_utc(2000, 10, 10))'
3621
0
Steven Penny

Con fecha BSD para macOS:

echo "Quelle est la date de début ?"
read DATE_DE_DEBUT
echo "Quelle est la date de fin ?"
read DATE_DE_FIN
ANNEE=$(($(echo $DATE_DE_FIN | awk -F "/" '{print $3}')-$(echo $DATE_DE_DEBUT  | awk -F "/" '{print $3}')))

echo " "

if [[ $ANNEE > 0 ]]; then

for((annee=$ANNEE-1 ; $ANNEE ; annee++))

  do
  #echo $annee  
  for((mois=0 ; 13 - $mois ; mois++))
      do
  #   echo année:$annee mois:$mois
          for((jour=0 ; 32 - $jour ; jour++))
              do
 #             echo année:$annee mois:$mois jour:$jour
           TEST=$(date -Rjf"%d/%m/%Y" -v +"$annee"y -v +"$mois"m -v +"$jour"d $DATE_DE_DEBUT +"%d/%m/%Y")
           if [[ $TEST = $DATE_DE_FIN ]]; then
                  echo "Différence entre le $DATE_DE_DEBUT et le $DATE_DE_FIN";
                  echo "est de :";
                  echo "$annee année(s) $mois mois $jour jour(s)";
             exit 0;
            fi


          done 
  done
  done

 else 
 annee=0
 for((mois=0 ; 13 - $mois ; mois++))
      do
#      echo année:$annee mois:$mois
          for((jour=0 ; 32 - $jour ; jour++))
              do
              #echo année:$annee mois:$mois jour:$jour
              TEST=$(date -Rjf"%d/%m/%Y" -v +"$annee"y -v +"$mois"m -v +"$jour"d $DATE_DE_DEBUT +"%d/%m/%Y")
              if [[ $TEST = $DATE_DE_FIN ]]; then 
                      echo "Différence entre le $DATE_DE_DEBUT et le $DATE_DE_FIN";
                     echo "est de :";
                     echo "$annee année(s) $mois mois $jour jour(s)";
              exit 0;
              fi
              done
      done

fi
0
OlivierOR