5

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.

7
  • 1
    What output do you actually want? Milliseconds since the epoch? Please edit your question and show us an example of the correct output.
    – terdon
    Oct 21, 2015 at 10:32
  • you could try adding an explicit u suffix to the number so it is recognised by InfluxDB as an absolute time, eg echo ${d}u $line.
    – meuh
    Oct 21, 2015 at 10:33
  • The epoch is 0. By definition. It doesn't really matter whether that's ns, ms, or any other measure - it's still zero. So presumably you're trying to do something other than "prepending the Unix epoch with "nanosecond" precision". Please can you clarify what you are really trying to do. Oct 21, 2015 at 11:04
  • @terdon I intend to add epoch with millisecond accuracy to each line of my output file. For nanoseconds it works perfectly fine with Influxdb but when I use millisecond epoch the Influxdb assumes all 0 (1970-01-01T00:24:05.419982325Z).
    – hossein
    Oct 21, 2015 at 14:05
  • Again, please edit your question and show us your desired output.
    – terdon
    Oct 21, 2015 at 14:06

3 Answers 3

6

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
3

nano is 10−9 and milli 10−3. Hence, we can use the 3 first characters of nanoseconds to get the milli:

date +%s%3N

From man date:

%N nanoseconds (000000000..999999999)

%s seconds since 1970-01-01 00:00:00 UTC

Source: Server Fault's How do I get current Unix time in milliseconds using bash?. Note I posted this same answer in Stack Overflow's equal question Linux command to get time in milliseconds.

2

You nearly had it right, just a couple of back ticks too many

$ d=$(($(date +%s%N)/1000000))
$ echo $d
1445422618527
$ d=$(date +%s%N)
$ echo $d $(( d / 10 )) $(( d / 1000000 ))
1445422673712321597 144542267371232159 1445422673712

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .