emencia.django.newsletter datetime problems with django 1.4 - python

I am using emencia.django.newsletter. When I run `python manage.py send_newsletter' I get this error
if self.newsletter.sending_date <= datetime.now() and \
TypeError: can't compare offset-naive and offset-aware datetimes
This is where the error comes from:
def can_send(self):
"""Check if the newsletter can be sent"""
if self.test:
return True
if self.newsletter.sending_date <= datetime.now() and\
(self.newsletter.status == Newsletter.WAITING or\
self.newsletter.status == Newsletter.SENDING):
return True
return False
I use Django 1.4
Any ideas?

Your sending_date value is timezone aware, but datetime.now() is timezone naive. As the error message says, you cannot compare them.
The answer is to convert now into a timezone aware datetime before doing the comparison.
import datetime
from django.utils.timezone import utc
now = datetime.datetime.utcnow().replace(tzinfo=utc)
if self.newsletter.sending_date <= now and \
...
For more information see the Django docs on naive and aware datetime objects.

Related

How do I create a datetime object from day and time and handle the required timezone?

I created a form with a DateField and a TimeField. When printing these from the routes.py I get these example values:
TimeField: 17:30:00
DateField: 2021-07-12
How can I turn those values into a datetime object, which I can submit to my Postgres Database? The required object format is DateTime. The Postgres Table is set up as TIMESTAMPTZ. I tried replace() to add the time to the DateField Data. But that does not work. I am new to datetimes and such, so please excuse my ignorance. How do the Timezones work? because I probably need to add the timezone somehow for the TIMESTAMPTZ, right?
Below is the minimal code for the functioning
forms.py
class CreateEvent(Form):
dt = DateField('DateTimePicker')
start_time = TimeField('Start')
submit = SubmitField("Submit")
models.py
class Events(db.Model):
__tablename__='events'
eid = db.Column(db.Integer, primary_key = True)
event_day = db.Column(db.DateTime, nullable=False)
start_time = db.Column(db.DateTime, nullable=False)
def __init__(self, event_day, start_time):
self.event_day = event_day
self.start_time = start_time
routes.py
if request.method == 'POST':
if form.validate() == False:
return render_template('create.html', form=form)
else:
event_day = form.dt.data
start_time = form.start_time.data
print(start_time)
print(event_day)
start_time = event_day.replace(time=start_time)
newevent = Events(event_day, start_time)
db.session.add(newevent)
db.session.commit()
return "Success"
Just in case, here is the Postgres Create Statement for the table:
CREATE TABLE events (
eid serial PRIMARY KEY NOT NULL,
event_day TIMESTAMPTZ NOT NULL,
start_time TIMESTAMPTZ NOT NULL,
);
pip install dateutil:
https://dateutil.readthedocs.io/en/stable/
then:
from dateutil.parser import parse
TimeField = "17:30:00"
DateField = "2021-07-12"
parse(DateField + ' ' + TimeField)
datetime.datetime(2021, 7, 12, 17, 30)
You probably don't need to add a timezone, Postgres will use the timezone setting for the server. Postgres does not actually store the timezone in a timestamptz field. It just uses the timezone setting to rotate the value to a UTC time for storage.
Not tested but as an example, and you may have to install pytz from PIP (if not already present on your system). Python knows so-called naive datetime objects (that have no timezone context), and time zone-aware datetime objects.
So the goal is to build a string with the date and the time, then parse it into a datetime object. Next, we add the desired time zone (in this example it is assumed US/Pacific so change as appropriate).
import datetime
import pytz
TimeField = "17:30:00"
DateField = "2021-07-12"
current_tz = pytz.timezone('US/Pacific')
# parse string into naive datetime object
dt_naive = datetime.datetime.strptime(f"{DateField} {TimeField}", "%Y-%m-%d %H:%M:%S")
# convert to time zone-aware datetime
dt_aware = current_tz.localize(dt_naive)

Adapt translation method from django to my function

I am working on a django project. I have created a function that will display the current date in french or english.
We have to install
sudo locale-gen fr_FR.utf8
and then
from datetime import datetime
import locale
def set_locale(locale_):
locale.setlocale(category=locale.LC_ALL, locale=locale_)
def date_customerprofile(language):
now_ = datetime.today()
if language == 'English':
set_locale('en_US.utf8')
date_ = now_.strftime("%A %B %d %Y")
else:
set_locale('fr_FR.utf8')
date_ = now_.strftime("%A %B %d %Y")
I know it works well, but I would like to use the django translation method. There are good informations here : https://docs.djangoproject.com/fr/1.10/topics/i18n/translation/ and in particular here : https://www.technomancy.org/python/django-i18n-manually-turn-on-a-language/.
Could anyone be able to adapt the last website method to my function?
I tried something but that doesn't work :
from django.utils import translation
def date_customerprofile(language):
now_ = datetime.today()
old_lang = 'en'
if language == 'English':
import ipdb; ipdb.set_trace()
translation.activate('en')
date_ = now_.strftime("%A, %B %d %Y")
else :
translation.activate('fr')
date_ = now_.strftime("%A, %d %B %Y")
translation.activate(old_lang)
return date_
In fact, my main purpose is to create a function which will display the current date of the form Mercredi, 29 mars 2017 when I select 'French' and the form 'Wednesday, March 29, 2017'. Could anyone have an idea how to do that with a django method?
Thanks!
P.S. Please let me know if the question is unclear.
datetime.strftime() is a method from the Python standard library and doesn't know anything about your Django language. You can use the builtin date template filter which does respect the Django language.
from datetime import datetime
from django.template.defaultfilters import date as datefilter
from django.utils import translation
def date_customerprofile(language):
now_ = datetime.today()
if language == 'English':
translation.activate('en')
return datefilter(now_, 'l, F j, Y')
else:
translation.activate('fr')
return datefilter(now_, 'l, j F Y')
Seems to give the results you want:
>>> date_customerprofile('English')
u'Thursday, March 30, 2017'
>>> date_customerprofile('French')
u'jeudi, 30 mars 2017'
Some notes:
If this is used in the context of one user who has one language, it would be better to set the language on the user's sessions rather than switch it around just within this function.
If you were really serious about localization you would put your custom date formats in format files but it may be overkill for your use case.

In flask how to get current time in GMT?

I want to get current time in GMT, like 2015-08-21 05:13:13+00:00 Here you can see that correction is made like 00:00 for GMT, In django they are using from django.utils import timezone and date_to = timezone.now() to calculate the current time. How I will get the same functionality in flask, Formate of time should be like 2015-08-21 05:13:13+00:00 not like 2015-03-30 07:19:06.746037+02. I got this link but they are using 2015-03-30 07:19:06+02. I don't want. Just GTM time
Following code is in Django, I want same in Flask, Here they are using from django.utils import timezone. In Flask what is equivalent of it, which gives current time in this format 2015-08-21 05:13:13+00:00
import datetime
import pytz
from django.utils import timezone
def calc_date_args(date_from, date_to, date_options):
try:
date_to = timezone.now()
print 'calc_date_args, date_to', date_to #calc_date_args, date_to 2015-08-21 05:13:13.615541+00:00
date_from = date_to - datetime.timedelta(days=float(date_options))
except Exception:
raise ValueError(_("The time delta must be a number representing "
"the time span in days"))
return date_from, date_to
Not sure if you mean UTC time instead of GMT, as most machines consume UTC and most timestamps are in UTC.
In Python 3 to get UTC timezone-aware timestamp:
import datetime
def now():
"""Get timezone-aware UTC timestamp."""
return datetime.datetime.now(datetime.timezone.utc)

Timezone conversion shows an offset of an hour more in OpenShift

I've implemented a REST webservice using flask. It stores and provides events information.
While storing information, I do the following steps:
Take the date, time and timezone.
Localize into the provided timezone
Then convert it into utc timezone
Finally get the utc timestamp and store it in the db.
def __get_timestamp(_datetime):
"""Returns the timestamp from datetime
"""
return time.mktime(_datetime.timetuple())
def __strptime(formatted_dt, tzinfo):
"""Returns the utc timestamp after conversion from entered timezone to utc
"""
tzinfo_dt = tzinfo.localize(datetime.datetime(formatted_dt['year'], formatted_dt['month'], formatted_dt['day'], formatted_dt['hour'], formatted_dt['minute']), is_dst=True)
utc = get_tzinfo()
utc_tz = utc.normalize(tzinfo_dt.astimezone(utc))
return __get_timestamp(utc_tz)
def get_tzinfo(user_timezone="UTC"):
"""Return pytz timezone
"""
return pytz.timezone(user_timezone)
While retrieving information
Retrieve the utc timestamp
Localize it into the utc
Convert it into the required timezone
Return with the required format
def get_tzinfo(user_timezone="UTC"):
"""Return pytz timezone
"""
return pytz.timezone(user_timezone)
def __strftime(ts, tzinfo, format='%Y-%m-%d %I:%M %p'):
"""Return the formatted datetime after converting utc timestamp to required timezone
"""
utc = get_tzinfo()
utc_dt = utc.localize(datetime.datetime.fromtimestamp(ts), is_dst=True)
tzinfo_dt = tzinfo.normalize(utc_dt.astimezone(tzinfo))
formatted_dt = tzinfo_dt.strftime(format)
return formatted_dt
The sequence goes like this
Entered datetime = 2014-03-21 14:00
TimeZone = "Asia/Kathmandu" --> (GMT+05:45) Kathmandu
Resulting timestamp = 1395407700
Final Formatted Output = "2014-03-21 03:00 PM"
The problem seems to be with daylight saving because the same code gives the correct result when tested locally.
Currently the webservice is being run on Openshift
whose server has "EDT" timezone,
while my local settings has "NPT".
How can this be resolved?

Exception was: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'

I am new with python and I am making a system that deals with request.GET method...
when i pass a date to the system, if it is exist then it will look for the database and show data according to that date and other dates, else it will display a date with other date...
here is my code :
from django.utils.xmlutils import SimplerXMLGenerator
from piston.handler import BaseHandler
from booking.models import *
from django.db.models import *
from piston.utils import rc, require_mime, require_extended, validate
import datetime
class BookingHandler(BaseHandler):
allowed_method = ('GET', 'POST', 'PUT', 'DELETE')
fields = ('id', 'date_select', 'product_name', 'quantity', 'price','totalcost', 'first_name', 'last_name', 'contact', 'product')
model = Booking
#for product availability
def read(self, request, id, date_select):
if not self.has_model():
return rc.NOT_IMPLEMENTED
try:
prod = Product.objects.get(id=id)
merge = []
checkDateExist = Booking.objects.filter(date_select=date_select)
if checkDateExist.exists():
entered_date = Booking.objects.values('date_select').distinct('date_select').filter(date_select=date_select)[0]['date_select']
else:
enteredTemp_date = datetime.datetime.strptime(date_select, '%Y-%m-%d')
entered_date = datetime.datetime.strftime(enteredTemp_date,'%Y-%m-%d')
delta = datetime.timedelta(days=3)
target_date = entered_date - delta
day = 1
for x in range(0,5):
delta = datetime.timedelta(days=x+day)
new_date = target_date + delta
maximumProdQuantity = prod.quantity
quantityReserve = Booking.objects.filter(date_select=new_date, product=prod).aggregate(Sum('quantity'))['quantity__sum']
if quantityReserve == None:
quantityReserve = 0
data1 = {'maximum_guest': maximumProdQuantity, 'avialable': quantityReserve, 'date': new_date}
merge.append(data1)
return merge
except self.model.DoesNotExist:
return rc.NOT_HERE
and i got this error :
Piston/0.3dev (Django 1.3.1) crash report:
Method signature does not match.
Signature should be: id, date_select
Exception was: unsupported operand type(s) for -: 'str' and 'datetime.timedelta'
i think in my else statement the entered_date become a string, i do this line entered_date = datetime.datetime.strftime(enteredTemp_date,'%Y-%m-%d') so that the date format will be not 2011-12-01 00:00:00 i just only need 2011-12-01. my question is how can i get 2011-12-01 that is datetime format not a string?
can anyone can give a hint or an idea about my case?
thanks
strftime returns a formatted string. If you want to discard time portion of datetime object, use datetime.date:
entered_date = datetime.datetime.strptime(date_select, '%Y-%m-%d')
entered_date = entered_date.date()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''hi, your need to transfor the stirng to the date formation.
use this :
'''
import datetime
import time
from datetime import timedelta
today = datetime.date.today()
print(today)
# 0r
from datetime import date
today1 = date.today()
print(today1)
tomorrow = today - datetime.timedelta(days=7)
print(str(tomorrow))
# it is ok, because the today is date formation
#but the following it is not ok
event_day= "2021-05-18"
tomorrow = event_day - datetime.timedelta(days=7)
# you should do this:
text='2021-5-10'
x=datetime.datetime.strptime(text, '%Y-%m-%d').date()
print(x) # it's ok
# hope this help you!

Categories