warnings.warn("DateTimeField %s received a naive datetime (%s)" - python

I use django simple-history to get history on my models
I then search the history results by date but I get the error below. How can I format the date?
RuntimeWarning: DateTimeField HistoricalIssue.history_date received a naive datetime (2022-04-13 10:34:32) while time zone support is active.
warnings.warn("DateTimeField %s received a naive datetime (%s)"
def SearchByDate(request):
date_search = request.POST['date-search']
if date_search:
admin_hist_search_results = Issue.history.filter(history_date=date_search)

First, keep in mind that this is not an error, but "only" a warning. It mentions that the incoming timestamp (which you store in variable date_search) does not have timezone information, while you compare it with a timestamp field (history_date on model Issue) that does have timezone information. This could potentially lead to issues.
If you know the timezone coming in from the request, you can add that information to the timestamp, for example:
import pytz
date_as_string = request.POST['date-search']
parsed_date = datetime.strptime(date_as_string, '%Y-%m-%d')
amsterdam_timezone = pytz.timezone('Europe/Amsterdam')
date_search = amsterdam_timezone.localize(parsed_date)

Related

localize date time in python

Overview I receive the timestamp from server_x, my application is on server_y, both are in different regions, my application calls server_x api and receives json which has timestamp, now i need to perform some calculation on server_y, for that i need to make sure that the timestamp i receive from server_x could be used to covert the local datetime of server_y , so both are in sync
I want to convert datetime.now() to the timezone I receive from server for e.g., UTC-07:00
Current solution, I pass server_timestamp to the function and then I pass its zone info to the datetime.now
Server_timestamp = "2020-04-04T10:24:49.000-0700"
dt = datetime.strptime(Server_timestamp, "%Y-%m-%dT%H:%M:%S.%f%z")
convert_local = datetime.now(dt.tzinfo)
Problem:
I need to save the timezone of the server in db and then use that instead of passing server_timestamp everytime, the tzinfo gives a type datetime.timezone = UTC-07:00, after storing this string how can I use it to change the localtime.
Here's a function that utilizes the datetime library to convert a datetime object from one timezone to another:
from datetime import datetime
import pytz
def convert_tz(dt, current_tz, out_tz):
return dt.replace(tzinfo=current_tz).astimezone(tz=out_tz)
now = datetime.now(tz=pytz.timezone('US/Eastern'))
convert = datetime.now().astimezone().tzinfo
print(now)
print(utc_to_local(now, now.tzinfo, convert))
Output:
2020-05-10 17:02:44.245703-04:00
2020-05-10 16:02:44.245703-05:00
I used the pytz library for demonstration purposes. For you, to get the server's timezone, use the line datetime.now().astimezone().tzinfo.
I implemented a solution.
I now save the last 5 char of the timestamp in the db "-0700".
time_zone = query_from_db
tz = datetime.strptime(time_zone, "%z")
datetime_now = datetime.now(tz.tzinfo)

How to get date in correct format for YouTube upload?

I am running a python script on OSX to upload video file (single_file) to YouTube:
# define recording date as date of file modification
# https://developers.google.com/youtube/v3/docs/videos#resource
recordingDate = datetime.fromtimestamp(os.path.getctime(single_file)).isoformat("T")+"Z"
# define video title as file name
filename, file_extension = os.path.splitext(os.path.basename(single_file))
try:
initialize_upload(youtube, args, single_file, title, recordingDate)
except HttpError, e:
print " An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
in some cases it works well, but in others Google returns the following error -
Invalid value for: Invalid format: \"2017-09-22T22:50:55Z\" is malformed at \"Z\"
How should I fix it to get correct date from the file? YouTube expects the value in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
The link you shared in your question clearly states the format
The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.
So your issue is when then the microsecond info is not available, the isoformat will not have microsecond. Below code shows the difference
>>> current_date = datetime.now()
>>> current_date.isoformat()
'2018-05-20T10:18:26.785085'
>>> current_date.replace(microsecond=0).isoformat()
'2018-05-20T10:18:26'
So for the files which it works the microsecond would be coming is non-zero. So solution is simple
recordingDate = datetime.fromtimestamp(os.path.getctime(single_file)).replace(microsecond=0).isoformat("T")+".0Z"
This will make sure the microsecond is always truncated and set as .0 later

Dealing with timezone dates in MongoDB and pymongo

I do not seem to be able to query records and get what I expect. For example I am searching
today = datetime.datetime.today()
past = today + timedelta(days=-200)
results = mongo.stuff.find({"date_added": {"gt": past}}, {"id":1})
I have the following date specified in MongoDB:
"date_added": {
"$date": "2016-04-19T18:47:54.101Z"
},
But I get no results! Is this down to the timezone which appears in the MongoDB date which is screwing things up.
This is just a typing error:
Try with the following code:
results = mongo.stuff.find({"date_added": {"$gt": past}}, {"id":1})
You forgot about the $ sign in $gt.
Use an aware datetime object (with timezone info).
# E.g. with UTC timezone :
import pytz
import datetime
today = datetime.datetime.today()
past = today + timedelta(days=-200)
pytc.utc.localize(past)
results = mongo.stuff.find({"date_added": {"gt": past}}, {"id":1})
To use a different timezone to localize, try something like pytz.timezone('US/Mountain')
P.S. you'll need pip install pytz

Issue about Python imaplib library on method append

I'm trying to write an imapsync software that connects on host 1 to account1#host1.com and copy messages and folder to account2#host2.com host2.
Supposing I've already fetched the selected message with his UID with:
msg = connection.fetch(idOne, '(RFC822)'))
and msg is a good message, below you have the code I've tried to append the message:
date = connection.fetch(idOne, '(INTERNALDATE)')[1][0]
date = date.split("\"")[1]
authconnection1.append(folder, "", date, msg)
Error is:
ValueError: date_time not of a known type
I've tried many other possible solutions (with dateutil to convert date string to datetime object, using imaplib.Time2Internaldate I got the same error above ValueError: date_time not of a known type), but no one seems to work. I've searched around the network but nobody seems to have this issue.
Any idea? I'm getting very frustrated of it...
Thank you very much
Update:
I've resolved the date_time issue, because the "append" method of imaplib wants that date_time is an integer of seconds, so to retrieve the date I've written this code:
# Fetch message from host1
msg = connection.fetch(idOne, '(RFC822)')
# retrieve this message internal date
date = connection.fetch(idOne, '(INTERNALDATE)')[1][0].split("\"")[1]
# Cast str date to datetime object
date = parser.parse(date)
# Removes tzinfo
date = date.replace(tzinfo=None)
# Calculates total seconds between today and the message internal date
date = (datetime.datetime.now()-date).total_seconds()
# Makes the append of the message
authconnection1.append(folder, "", date, msg)
But now this fails with error:
TypeError: expected string or buffer
So the issue is only changed...
Any ideas?
Update (RESOLVED):
imaplib is not working fine, so I've made a workaround for append messages with right date/time. This is my code, I hope it will help everybody:
Function to convert date in right format:
def convertDate(date):
from time import struct_time
import datetime
from dateutil import parser
date = parser.parse(date)
date = date.timetuple()
return date
Main code:
#Get message
msg = authconnection.fetch(idOne, '(RFC822)')
#Get message date
date = authconnection.fetch(idOne, '(INTERNALDATE)')[1][0].split("\"")[1]
#Apply my function I've written above
date = convertDate(date)
#Append message with right date
authconnection1.append(folder, flags, date, msg[1][0][1])

How do I get the current date and current time only respectively in Django?

I came across an interesting situation when using this class:
class Company(models.Model):
date = models.DateField()
time = models.TimeField()
c = Company(date=datetime.datetime.now(), time=datetime.datetime.now())
Django decides to use DATETIME_INPUT_FORMATS defined within the formats.py file.
Which makes sense, because I am passing in a datetime.now() to both fields.
I think I could make Django to use DATE_INPUT_FORMATS and TIME_INPUT_FORMATS respectively, if I passed in only the current date and current time in.
Something like this:
c = Company(date=datetime.date.now(), time=datetime.time.now())
But this obviously throws an exception as now doesn't exist like that. Is there a different way to achieve this?
For the date, you can use datetime.date.today() or datetime.datetime.now().date().
For the time, you can use datetime.datetime.now().time().
However, why have separate fields for these in the first place? Why not use a single DateTimeField?
You can always define helper functions on the model that return the .date() or .time() later if you only want one or the other.
import datetime
datetime.datetime.now().strftime ("%Y%m%d")
20151015
For the time
from time import gmtime, strftime
showtime = strftime("%Y-%m-%d %H:%M:%S", gmtime())
print showtime
2015-10-15 07:49:18
import datetime
datetime.date.today() # Returns 2018-01-15
datetime.datetime.now() # Returns 2018-01-15 09:00
import datetime
Current Date and time
print(datetime.datetime.now())
#2019-09-08 09:12:12.473393
Current date only
print(datetime.date.today())
#2019-09-08
Current year only
print(datetime.date.today().year)
#2019
Current month only
print(datetime.date.today().month)
#9
Current day only
print(datetime.date.today().day)
#8
A related info, to the question...
In django, use timezone.now() for the datetime field, as django supports timezone, it just returns datetime based on the USE TZ settings, or simply timezone 'aware' datetime objects
For a reference, I've got TIME_ZONE = 'Asia/Kolkata' and USE_TZ = True,
from django.utils import timezone
import datetime
print(timezone.now()) # The UTC time
print(timezone.localtime()) # timezone specified time,
print(datetime.datetime.now()) # default local time
# output
2020-12-11 09:13:32.430605+00:00
2020-12-11 14:43:32.430605+05:30 # IST is UTC+5:30
2020-12-11 14:43:32.510659
refer timezone settings and Internationalization and localization in django docs for more details.
Another way to get datetime UTC with milliseconds.
from datetime import datetime
datetime.utcnow().isoformat(sep='T', timespec='milliseconds') + 'Z'
2020-10-29T14:46:37.655Z

Categories

Resources