locke14
locke14

Reputation: 1375

pymongo convert mongoDB date to python datetime

I have a MongoDB database which has some time entries (eg. creation dates of some entities). When I look at them in the database, they seem to be in a 64-bit integer BSON format. The database entry was originally created using C# (ASP.NET Core) using the following representation:

[BsonRepresentation(MongoDB.Bson.BsonType.Decimal128)]

I want to access that database using a Python script to get some stats. I can get that entry in my python code using pymongo. A typical value looks like this: [637013892303590646, 0]. How can I convert it into a python datetime value that is human readable?

If I print the variable type which I get from pymongo, it says: bson.int64.Int64

I looked at the bson module documentation here: https://api.mongodb.com/python/current/api/bson/index.html, but I couldn't find a suitable function to do the conversion. Can someone please point me the right call to convert the bson.int64.Int64 to a datetime value?

Thanks!

Upvotes: 2

Views: 4257

Answers (1)

Belly Buster
Belly Buster

Reputation: 8814

Your data is in ticks; defined as:

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 in the Gregorian calendar, which represents MinValue. It does not include the number of ticks that are attributable to leap seconds. If the DateTime object has its Kind property set to Local, its ticks represent the time elapsed time since 12:00:00 midnight, January 1, 0001 in the local time as specified by the current time zone setting. If the DateTime object has its Kind property set to Utc, its ticks represent the time elapsed time since 12:00:00 midnight, January 1, 0001 in the Coordinated Universal Time. If the DateTime object has its Kind property set to Unspecified, its ticks represent the time elapsed time since 12:00:00 midnight, January 1, 0001 in the unknown time zone.

so we can write a ticks_to_datetime() function which uses a timedelta based on midnight Jan 1 0001, dividing by 10 to convert from 100-nanoseconds to microseconds.

import pymongo
from datetime import datetime, timedelta
from bson import Int64

def ticks_to_datetime(ticks):
    return datetime(1, 1, 1) + timedelta(microseconds=ticks / 10)

mydb = pymongo.MongoClient()['mydatabase']

mydb.mycollection.insert_one({'old_time': [Int64(637013892303590646), 0]})
record = mydb.mycollection.find_one({})
old_time = record['old_time'][0]
new_time = ticks_to_datetime(old_time)
print(new_time)

gives:

2019-08-14 14:20:30.359062

Upvotes: 2

Related Questions