Tiempo en milisegundos desde época en el terminal

¿Cómo obtengo el tiempo desde la época, en milisegundos, en la terminal OSX?

El equivalente de Linux/Ubuntu es date +%s.%N:

Linux $ date +%s.%N
1403377762.035521859

Que no funciona en mi terminal OSX:

OSX $ date +%s.%N
1403377800.N

Respuestas (4)

El dateprograma en OS X es diferente al dateprograma coreutils de GNU. Puede instalar coreutils (incluido gnu-date), luego tendrá una versión dateque admite milisegundos.

Como la instalación desde la fuente puede ser una molestia para los usuarios nativos de OS X, le aconsejo que use Homebrew .

Para instalar estas herramientas usando Homebrew , ejecute este oneliner en su terminal:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Homebrew ahora está instalado (es aconsejable seguir las sugerencias del instalador después de la instalación). Ahora instalaremos coreutils usando brew.

brew install coreutils

Como dice la instalación, todos los comandos se han instalado con el prefijo 'g' (por ejemplo, gdate, gcat, gln, etc etc). Si realmente necesita usar estos comandos con sus nombres normales, puede agregar un directorio "gnubin" a su RUTA ( ~/.bash_profile) como:

PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"

Ahora puedes ejecutar

gdate +%s.%N

y esto generará su tiempo desde la época en milisegundos.

Bonito. Ni siquiera tuve que agregar la ruta, gdatese instaló en /usr/local/bin/gdate.
Eso es lo que esperarías. Todos los binarios se instalan con el prefijo g. En la ruta que proporcioné, todos los mismos gnu-coreutils están sin el prefijo g. Entonces, si lo agrega en su ruta como PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" reemplazará a los originales. Entonces OS X datese convierte en GNU date(en lugar de gdate)
Bien que funcionó.
Técnicamente, el +%s.%Nformato da los segundos con precisión de nanosegundos, no milisegundos. Después de usar brew para instalar gdate, revisé la página de manual para ver si había milisegundos disponibles. No es. Tampoco decía que %Nse podía especificar una precisión para, pero lo intenté de todos modos. Encontré que el comando para obtener los segundos con precisión de milisegundos solamente (es decir, tres lugares decimales) es gdate +%s.%3N.

En OS X, simplemente ejecute date +%sya que OS X no admite más precisión que esta en datela salida de y cualquier exceso de precisión no admitido por la representación interna se trunca hacia menos infinito.

Si desea una salida en milisegundos, puede usar el siguiente comando, aunque la salida solo se corrige agregando ceros en lugar de agregar precisión debido a la razón mencionada anteriormente. Lo siguiente genera milisegundos correctos en sistemas que admiten la precisión necesaria.

echo $(($(date +'%s * 1000 + %-N / 1000000')))

Fuente para el comando anterior: Unix.SE: cómo obtener milisegundos desde la época de Unix

Si solo desea un comando que agregue la cantidad correcta de ceros en OS X, puede usar:

date +%s000
OS X no admite %-N, por lo que no hace nada (y podría causar problemas si $Nse establece la variable de shell). Solo usa date +%s000(o date +%s.000si quieres el punto decimal).
@Gordon Sí, mencioné esto, pero si OP está buscando una solución portátil que funcione correctamente en sistemas que son capaces de esa precisión, el comando anterior funciona. Por supuesto, podría simplemente agregar ceros a la salida, pero copiar eso a otros sistemas que pueden admitir la precisión adicional no sería lo ideal.
Ah, ya veo. datePero dado que el comando de OS X solo pasa %-Ncomo N, puede interferir con el cálculo. Intente configurar N=7000000000000000000, luego pruebe el comando... Este es un caso poco probable en la práctica, pero me sentiría más seguro con algo que no dependiera del entorno.
@Gordon De hecho, configurar la variable lo rompería; supongo que la variable específica podría restablecerse justo antes de ejecutar el comando, pero restablecer variables como esa es algo que todo buen script debería hacer antes de ejecutar los comandos de todos modos, imo, por si acaso. Por supuesto, todo esto se basa en mi suposición de que el OP quiere una respuesta editada por secuencia de comandos para incluir la adición literal de ceros.
El OP solicitó "tiempo desde la época, en milisegundos", esta es una respuesta sobre cómo agregar ceros a una cadena. No es el mísmo. Aunque se explica en la publicación, no es una respuesta a la pregunta.
@CousinCocaine Esta respuesta es para secuencias de comandos. Instalar uno propio datefunciona bien en su máquina, pero es inútil frente a las secuencias de comandos portátiles. Para la portabilidad, esto proporciona el valor más cercano posible.
@GeorgeGarside para secuencias de comandos y portabilidad en OS X, tiene razón.
👎 No estoy de acuerdo con el fundamento "para secuencias de comandos portátiles" para esta respuesta. Esta no es una respuesta completa por sí sola. Debería ser una adición a la respuesta aceptada. Dado que homebrew instala la herramienta de fecha GNU como gdate, no entra en conflicto con la dateherramienta existente. Un script portátil que necesita tiempos de milisegundos podría probar su presencia gdatey usarlo. dateSi fuera necesario, recurriría a utilizar el +%s.000formato. Un script muy portátil probaría la salida datey verificaría que contiene la información necesaria, lo que le permitiría ejecutarse en varios sistemas operativos.

Perl es omnipresente.

$ perl -MTime::HiRes=time -e 'printf "%.9f\n", time'
1557390839.244920969
respuesta subestimada

esta solución funciona en macOS.

si considera usar un script bash y tiene python disponible, puede usar este código:

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'

O escribe un pythonguión directamente:

#!/usr/bin/python

from time import time
print int(round(time() * 1000)) 
Lo anterior solo funciona con Python 2. Ejecutarlo con Python 3 genera un error. Si usa la print()función en lugar de la printdeclaración, funcionará con ambas versiones: python -c 'from time import time; print(int(round(time() * 1000)))'esto le permite usar el pythoncomando común sin tener que preocuparse de si se resolverá en una ruta para la versión 2 o la versión 3 de Python.
buen hallazgo @CoryGross. gracias por compartir.