51 lines
1.8 KiB
Python
51 lines
1.8 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# @copyright this code is the property of Ubertone.
|
|
# You may use this code for your personal, informational, non-commercial purpose.
|
|
# You may not distribute, transmit, display, reproduce, publish, license, create derivative works from, transfer or sell any information, software, products or services based on this code.
|
|
# @author Stéphane Fischer
|
|
|
|
from datetime import datetime, timezone, timedelta
|
|
from time import mktime
|
|
from struct import pack, unpack, calcsize
|
|
|
|
# temps ZERO (Ubertone Epoch)
|
|
UBT_EPOCH = datetime(2020, 1, 1, tzinfo=timezone.utc)
|
|
|
|
def encode_timestamp(_datetime):
|
|
"""Encode timestamp in words
|
|
|
|
Args:
|
|
_datetime: timestap
|
|
|
|
Returns:
|
|
bytearray representing the encoded timestamp
|
|
|
|
ubertone's epoch :
|
|
- 01/01/2020 starting from version 2.01
|
|
"""
|
|
|
|
timestamp = mktime(_datetime.timetuple()) + _datetime.microsecond/1e6 - mktime(UBT_EPOCH.timetuple())
|
|
# timestamp (epoch) 2*int16 Epoch en secondes MSB + LSB (*)
|
|
# timestamp extension int16 En millisecondes
|
|
|
|
# DIRECTIVE WARNING : attention à ne pas mélanger int16 et int32. En effet la machine est susceptible d'aligner les données sur 32 bits.
|
|
# du coup un pack "hih" vas donner le premier short (16 bits) suivi par 0x0000 puis le second entier (int32) !!!
|
|
# TODO forcer l'endianness ?
|
|
return pack("hhh", int((int(timestamp)>>15)&0x0000FFFF), int(int(timestamp)&0x00007FFF),\
|
|
int(1000.*(timestamp%1)))
|
|
|
|
def decode_timestamp(_encoded_datetime):
|
|
"""Extract timestamp from a byte array
|
|
|
|
Args:
|
|
_encoded_datetime:
|
|
|
|
Returns:
|
|
timestamp and offset
|
|
"""
|
|
timestamp_size = calcsize('hhh')
|
|
nsec_pF, nsec_pf, msec = unpack('hhh', _encoded_datetime[0:timestamp_size])
|
|
return UBT_EPOCH+timedelta(seconds=(int(nsec_pF)<<15)|nsec_pf, milliseconds=msec), timestamp_size
|