Converting a timestamp from ticks (Windows) to epoch (Linux) at ingestion time in Apache Druid

To convert from c# ticks to Unix Epoch-based time, we will ingest the ticks and then use a transform to apply a simple calculation.

Design the transform expression

f = (c#Ticks - epoch_offset) / granularityRequired

c#Ticks

Whatever the column setting is in the timestampSpec , it will always store it as __time . We can then refer to __time in a transform expression and overwrite it with a different value. So, in the ingestion spec, just set the timestamp field as usual - we’ll then refer to __time in a transform and overwrite it.

epoch_offset

621355968000000000 is the difference between the base time of c# Epoch and the Unix Epoch - the number of nanoseconds between 1st Jan 0001 and 1st Jan 1970. We must subtract this from the incoming c# tick time value as the first step.

granularityRequired

As c# ticks are very granular (there is one tick every 100 nanoseconds) we can maintain good resolution inside Druid. Druid supports a number of levels of time accuracy, so first find out which one your business needs.

We divide the result of the epoch differences by the appropriate 10th power in order to get the accuracy that you want. For each timestampSpec/format, the divisor is as follows:

nano = 100
millis = 10000
posix = 10000000

Add to the Ingestion Spec

You must set the granularity you will achieve inside the timestampSpec/format value.

Then put your transform formula into the the list of transforms at transformSpec/transforms . We use a simple expression -based transform to do the calculation, noting that it reads from, and writes back to, the __time field.

Here’s what the expression looks like to convert to milliseconds:

"type": "expression", "name": "__time", "expression": "(__time - 621355968000000000) / 10000"

Example

Here’s an example of a conversion from c# ticks to Unix Epoch-based milliseconds in Druid.

    :
    "timestampSpec": {
      "column": "incomingTime_dimensionName",
      "format": "millis"
    },
    "transformSpec": {
        "transforms": [
            { "type": "expression", "name": "__time", "expression": "(__time - 621355968000000000) / 10000" }
          ]
    },
    :