Reversing an object handle to its creation date

As a handle is created from the date when an object is created, is it possible to reverse the operation in order to know this creation date?

I’ve tried this with Supertool but it don’t work:

init:

from datetime import date as dt

statement:

hand = float.fromhex(obj.handle[0:10])
print(hand, dt.fromtimestamp(((hand / 864000000.0 ) + 2440587.5)), ((hand / 864000000.0 ) + 2440587.5 ))

I’ve tried to vary hex extraction from [0:8] to [0:16] but that doesn’t work too:
3967677919.0 1970-01-29 2440592.0922198137
1015725547344.0 1970-01-29 2441763.108272389
260025740120242.0 1970-02-01 2741543.2177317617
6.656658947078206e+16 1972-07-09 79485251.2393311
1.7041046904520208e+19 2595-02-01 19725874504.76876

Yes, see here.

Thanks George, I think I use (I’ve translated) the formula DATE ( ( 0xd897668328b / 864000000.0 ) + 2440587.5 ) as exposed in my first post but it doesn’t give me satisfaction.

With 11 hex it give me this and I’m sure I don’t created anything in 1972

6.656658947078206e+16 1972-07-09 79485251.2393311

So I’ve surely made a mistake somewhere but I don’t know where

I’m not sure that formula is correct. From our code the handle is:

“%08x%08x” % (int(time.time()*10000), _rand.randint(0, sys.maxsize))

So the observation that its the first 11 hex digits that of interest is probably correct.

And from the Python docs the time.time() is:
time. time () → float

Return the time in seconds since the epoch as a floating point number. The specific date of the epoch and the handling of leap seconds is platform dependent. On Windows and most Unix systems, the epoch is January 1, 1970, 00:00:00 (UTC) and leap seconds are not counted towards the time in seconds since the epoch.

The description of date.fromtimestamp() is:
classmethod date. fromtimestamp (timestamp )

Return the local date corresponding to the POSIX timestamp, such as is returned by time.time().

This may raise OverflowError, if the timestamp is out of the range of values supported by the platform C localtime() function, and OSError on localtime() failure. It’s common for this to be restricted to years from 1970 through 2038. Note that on non-POSIX systems that include leap seconds in their notion of a timestamp, leap seconds are ignored by fromtimestamp().

So I don’t think you need to perform any arithmetic to get the local time, just run the first 11 hex digits converted to float to date.fromtimestamp.

2 Likes

Thanks Paul !

Yes, it still requires a little calculation: dividing handle[0:11] by 10000.

This SuperTool script allow you to retrieve any object creation date (don’t care about people category warning):

[Gramps SuperTool script file]
version=1

[title]
SuperTool - Object Creation Date

[category]
People

[initial_statements]
from datetime import date as dt

[statements]
hand: float = float.fromhex(obj.handle[0:11])

creation = dt.fromtimestamp(hand/10000)

[filter]

[expressions]
creation

[scope]
selected

[unwind_lists]
False

[commit_changes]
False

[summary_only]
False


Just to clarify, the formula in my post is what worked for me in sqlite3, for example:

sqlite> select DATE ( ( 0xd897668328b / 864000000.0 ) + 2440587.5 );
2017-03-01

Added some “See also” cross-references to this information on the Wiki section on Using the Database API:Handles.

Seems inadequate to me (since there would be too much bouncing from link to link)

What should be added to make the Wikipage a useful reference page?