Search code examples
datetimeencodingcompressioniotbit

Is it possible to encode date AND time (with some caveats) into 12 bits?


I have at my disposal 16 bits. Of them, 4 bits are the header and cannot be touched. This leaves us with 12 bits. I would like to encode date and time data into them. These are essentially logs being sent over LPWAN.

Obviously, it's impossible to encode proper generic date and time into it. Since the unix timestamp uses 32 bits, and projects like Compact Time Format use 5 bytes.

Let's say we don't really need the year, because this information is available elsewhere. Let's also say the time resolution of seconds doesn't have to be super accurate, so we can split the seconds into 30 second intervals. If we were to simply encode the data as is then:

 4 bits month          (0-11)
 5 bits day            (0-31)
 5 bits hour           (0-23)
 6 bits minute         (0-59)
 1 bit  second         (0,30)
-----------------------------
21 bits

21 bits is much better than 32. But it's still not 12. I could subtract one bit from the minutes (rounding to the nearest even minute), and remove the seconds but that still leaves us with 19 bits. Which is still far from 12.

Just wondering if it's possible, and if anyone has any ideas.


Solution

  • 12 bits can hold 2^12 = 4096 values, which feels pretty tight for a task. Not sure much can be done in terms of compressing a date time into a 4096 number. It is too little space to represent this data.

    There are some workarounds, none of them able to achieve what you want, but maybe something you could use anyway:

    • Split date and time. Alternate with some algorithm between sending date/time, one bit can be used to indicate what data is being sent. This leaves 11 bits to encode either date or time. You could go a bit further and split time like this as well. Receiving side can then reconstruct a full date time having access to the previously received data.

    • You could have a schema where one date packet is sent as a starting point, and subsequent packets are incremented in N-second intervals from the start of the epoch

    • Remove date time from data completely, saving 12 bits, but send it periodically as a stand-alone heartbeat/datetime packet.

    • You could try compressing the whole data packet which could allow using more bits to represent date time and still fit into a smaller overall packet size

    • If data is sent at reasonable fixed intervals, you could use a circular counter of an interval of N seconds, this may work if you have few devices and you can keep track of when they start transmitting. For example a satellite was launched on XYZ date time, it send counter every 30 seconds, we received counter value of 100, to calculate date we use simple math XYZ + 30*100 seconds