Last active
May 4, 2024 05:48
-
-
Save Dog/272225a5b22a393d2088 to your computer and use it in GitHub Desktop.
Converting between Javascript date and Python datetime with bson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bson.tz_util import utc | |
from datetime import datetime, timedelta | |
# This file is to impliment date related helper functions | |
# | |
# This is mainly needed because bson uses the javascript date class. | |
# The javascript Date() class represents timestamps in milliseconds. | |
# For some documentation on how Bson, Json, and Date work together, refer to: | |
# http://blog.mongohq.com/from-json-to-bson-and-back/ | |
# | |
# The python datetime class represents timestamps in seconds. | |
# | |
# Furthermore, the python bson class uses its own time zone. | |
# What this means is that uses datetime.utcfromtimestamp alone is not enough. | |
# This is because utcfromtimestamp will represent the time zone as None. | |
# You also can't create your own UTC class, because the datetime comparator | |
# just checks that the time zone object is of the same ID. | |
# | |
# You must use datetime.fromtimestamp(<timestamp>, <tz>) | |
# Where <timestamp> is the converted timestamp, and <tz> is bson.tz_util.utc | |
# Precondition: timestamp represented in milliseconds | |
# timestamp could be either a string or integer | |
# Returns: DateTime object representing the timestamp given | |
# | |
# Possible ToDo: Allow an optional time zone parameter | |
def bsonToDateTime(timestamp): | |
# Make sure we are dealing with an integer. If not convert it. | |
timestamp = int(timestamp) | |
# Save the milliseconds so they aren't lost in conversion | |
# due to datetime.fromtimestamp only being as precise as seconds | |
milliseconds = timestamp % 1000 | |
timestampInSeconds = timestamp / 1000 | |
time = datetime.fromtimestamp(timestampInSeconds, utc) | |
# convert our milliseconds to microseconds so we can store it in our | |
# new datetime object to the correct precision | |
time = time + timedelta(0, 0, 0, milliseconds) | |
return time | |
# Precondition: timestamp represented in milliseconds | |
# timestamp could be either a string or integer | |
# Returns: DateTime object representing the timestamp given | |
def dateTimeToBson(dateTimeObject): | |
# Find the time delta since the epoch | |
epoch = dateTimeEpoch() | |
delta = dateTimeObject - epoch | |
# 60 seconds 60 minutes 24 hours 86400 seconds | |
# ---------- * ---------- * ---------- = -------------- | |
# 1 minutes 1 hour 1 day 1 day | |
secondsInDay = 86400 | |
deltaDaysInSeconds = delta.days * secondsInDay | |
deltaSeconds = delta.seconds | |
totalSeconds = deltaDaysInSeconds + deltaSeconds | |
# 1000 milliseconds | |
# ----------------- | |
# 1 second | |
totalSecondsToMilliseconds = totalSeconds * 1000 | |
# 1000 microseconds | |
# ----------------- | |
# 1 millisecond | |
deltaMilliseconds = delta.microseconds/1000 | |
totalMilliseconds = totalSecondsToMilliseconds + deltaMilliseconds | |
return totalMilliseconds | |
def dateTimeEpoch(): | |
return datetime.fromtimestamp(0, utc) | |
def now(): | |
currentDateTime = datetime.utcnow() | |
# Use division to round down to correct precision | |
# Use multiplication to replace the lost zeros | |
millisecondsRoundedDown = currentDateTime.microsecond/1000*1000 | |
return currentDateTime.replace(tzinfo=utc, microsecond=millisecondsRoundedDown) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment