Bash – Unix epoch in milliseconds

bashdateshell-scripttimetimestamps

I'm prepending the Unix epoch with "nanosecond" precision into output of my command as below:

$ command | while read line; do d=`date +%s%N`; echo $d $line; done > file

I looked around to find out how to turn "nanosecond" into "millisecond". For example, I followed the solution given here. So, I tried both suggested approaches:

$ command | while read line; do d=`echo $(($(date +%s%N)/1000000))`; echo $d $line; done > file
$ command | while read line; do d=`date +%s%N | cut -b1-13`; echo $d $line; done > file

However, in both cases when I insert the file into InfluxDB and query my database I get this:

time    
1970-01-01T00:24:05.419982325Z  
1970-01-01T00:24:05.419982344Z  
1970-01-01T00:24:05.419982371Z  
1970-01-01T00:24:05.419982378Z  
1970-01-01T00:24:05.419982388Z  
1970-01-01T00:24:05.419982401Z

Update

When I use epoch with nanosecond accuracy date +%s%N, I get this:

time
2015-10-21T08:59:59.978902683Z  
2015-10-21T08:59:59.982615836Z  
2015-10-21T08:59:59.983958069Z  
2015-10-21T08:59:59.98805317Z   
2015-10-21T08:59:59.99717678Z   
2015-10-21T09:00:00.028624495Z  

I'm expecting such an output:

2015-10-21T09:12:10.001327Z

Please let me know if you have any solution.

Best Answer

You could use bc and printf:

printf "%0.f" "$(bc <<<"$(date +"%s.%N")*1000")"

This gives the number of miliseconds since january 1970. I didn't use the scale=n option of bc on purpose, because that would not round the value, instead it cuts the rest away (I know, it's pedantic). bc reads from file or from the standard input. <<< is a here string which expands the contents and supplies them as standard input to bc. This is given to printf to round the value.


See this as an example:

$ d=$(date "+%s.%N")
$ echo $d; bc <<<"scale=0; ($d*1000)/1"; printf "%0.f" "$(bc <<<"$d*1000")"
1445423229.512731661 # plain date
1445423229512 # bc with scale
1445423229513 # bc/printf

In the loop it would then look like this:

command | while read line; do
  d=$(printf "%0.f" "$(bc <<<"$(date +"%s.%N")*1000")")
  echo "$d $line"
done >file
Related Question