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.
Related
I use Enum classes to explicitly show possible values of argument. It is nice and concise.
However, when I am accessing one Enum from another it stars to look unpythonic: Functions[day.value].value. The fact that I need to pass and retrieve the value attribute of Enum adds complexity.
How can this (fictional) code be rewritten to use only one Enum, and not need to access the value attribute?
from datetime import datetime, timedelta
from enum import Enum
class Day(Enum):
YESTERDAY = 'YESTERDAY'
TODAY = 'TODAY'
TOMORROW = 'TOMORROW'
def get_date(day: Day):
class Functions(Enum):
YESTERDAY = datetime.now() + timedelta(days=-1)
TODAY = datetime.now()
TOMORROW = datetime.now() + timedelta(days=1)
return Functions[day.value].value.date()
today = get_date(Day.TODAY)
yesterday = get_date(Day.YESTERDAY)
tomorrow = get_date(Day.TOMORROW)
It seems to me that you are trying to implement a switch statement that python does not have. The most common way I have seen being used to do such a thing is via a dict:
def get_date(day: Day):
return {
Day.YESTERDAY: datetime.now() + timedelta(days=-1),
Day.TODAY: datetime.now(),
Day.TOMORROW: datetime.now() + timedelta(days=1),
}[day].date()
Note that I am accessing [day] directly which might raise KeyError. If you want to avoid this, you can use get(day, default=datetime.now()) which essentially attempts to access the key and if does not exist it returns datetime.now().
It is possible for an Enum to have other attributes besides name and value -- for example, date:
from datetime import date, timedelta
from enum import Enum
class Day(Enum):
YESTERDAY = 'YESTERDAY'
TODAY = 'TODAY'
TOMORROW = 'TOMORROW'
#
#property
def date(self):
today = date.today()
return {
'YESTERDAY': today + timedelta(days=-1),
'TODAY': today,
'TOMORROW': today + timedelta(days=1),
}[self.value]
and in use:
>>> Day.YESTERDAY
<Day.YESTERDAY: 'YESTERDAY'>
>>> Day.YESTERDAY.date
datetime.date(2020, 11, 9)
>>> Day.TODAY
<Day.TODAY: 'TODAY'>
>>> Day.TODAY.date
datetime.date(2020, 11, 10)
>>> Day.TOMORROW
<Day.TOMORROW: 'TOMORROW'>
>>> Day.TOMORROW.date
datetime.date(2020, 11, 11)
Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.
Currently the date format on our Odoo CRM looks like 11/20/2017 13:03:41 but I want to display the format to July 3rd 3:00PM and on another place show as 3 Jul 3:00PM
We show this field in the form
<field name="pickup_time"/>
I have searched a lot to find how to change the format, but It's mainly to change in the local settings and it's permanently one setting for everywhere. Which would not solve of what we want, like having two different format for different places.
Along Odoo the default constant date format used is DEFAULT_SERVER_DATETIME_FORMAT. This is defined in the file misc.py
DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d"
DEFAULT_SERVER_TIME_FORMAT = "%H:%M:%S"
DEFAULT_SERVER_DATETIME_FORMAT = "%s %s" % (
DEFAULT_SERVER_DATE_FORMAT,
DEFAULT_SERVER_TIME_FORMAT)
So if you declare the field like the following code then that constant is going to be used:
pickup_time = fields.Datetime(
string="Pickup time",
)
So if you want to use another format you can create a computed field with that custom format. You need to use some date functions: strftime (object to string) and strptime (string to object). The formats codes are explained almost at the bottom of this python documentation page
from datetime import datetime
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
[...]
pickup_time_formated = fields.Char( # it is going to be a readonly field
string='Pickup time formated',
compute='_compute_pickup_time_formated'
)
#api.multi
#api.depends('pickup_time')
def _compute_pickup_time_formated(self):
for record in self:
date = record.pickup_time
date_obj = datetime.strptime(date, DEFAULT_SERVER_DATETIME_FORMAT) # to convert it in a date object
v = date_obj.day % 10 # to get the remainder of the operation
if v == 1:
ordinal_suffix = 'st'
elif v == 2:
ordinal_suffix = 'nd'
elif v == 3:
ordinal_suffix = 'rd'
else:
ordinal_suffix = 'th'
# format 'July 3rd 3:00PM'
record.pickup_time_formated = datetime.strftime(date_obj, '%B %d' + ordinal_suffix + ' %I:%M %p')
# format '3 Jul 3:00PM'
# record.pickup_time_formated = datetime.strftime(date_obj, '%d %b %I:%M %p'),
And then you can show the new fields in the xml form:
<field name="pickup_time_formated"/>
I want to format a date in the future based on a time delta:
from django import template
from datetime import datetime, timedelta, time
register = template.Library()
#register.simple_tag
def tomorrow(format):
tommorow = datetime.now() + timedelta(days=1)
return tommorow.strftime(format)
def dayfuture(dday, format):
dayfuture = datetime.now() + timedelta(days=dday)
return dayfuture.strftime(format)
This works:
{% tomorrow "%A, %d %b, %Y" %}
But I've had no luck with dayfuture.
Also, is it possible to have multiple custom template tags in the same file. I've had no luck registering a second one.
I'm using django 1.11 pythone 3.4
This does not work because you did not register it. It is possible to have multiple template tags inside a single file.
def dayfuture(dday, format):
dayfuture = datetime.now() + timedelta(days=dday)
return dayfuture.strftime(format)
You have to put the decorator on it to register it
#register.simple_tag
def dayfuture(dday, format):
dayfuture = datetime.now() + timedelta(days=dday)
return dayfuture.strftime(format)
I am trying to create a number of constraints for some other code based on twitter handle sets.
I am having issues with the following code because:
TypeError: can't compare datetime.datetime to str
It seems that even though I have changed Last_Post to a datetime object initially, when i compare it to datetime.datetime.today() it is converting to string. Yes, I have checked the to ensure that Last_post is converting properly. Im not really sure what is going on. Help?
for handle in handles:
try:
user = api.get_user(handle)
#print json.dumps(user, indent = 4)
verified = user["verified"]
name = user['name']
language = user['lang']
follower_count = user['followers_count']
try:
last_post = user['status']['created_at']
last_post = datetime.strptime(last_post, '%a %b %d %H:%M:%S +0000 %Y')
except:
last_post = "User has not posted ever"
location = user['location']
location_ch = location_check(location)
if location_ch is not "United States":
location_output.append(False)
else:
location_output.append(True)
new_sum.append(follower_count)
if language is not "en":
lang_output.append(False)
else:
lang_output.append(True)
if datetime.datetime.today() - datetime.timedelta(days=30) > last_post:
recency.append(False)
else:
recency.append(True)
I think you need to convert the twitter date to a timestamp:
import time
ts = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(tweet['created_at'],'%a %b %d %H:%M:%S +0000 %Y'))
How does one set the date on the CalendarDatePicker. i.e. it defaults to current date and I want to display it with another date which I will set from my controller.
I am displaying the CalendarDatePicker widget in a TableForm from tw.form. I have looked at this for a few hours and can't work out how to do this so any pointers greatly appreciated.
import tw.forms as twf
form = twf.TableForm('dateSel', action='changeDate', children=[
twf.CalendarDatePicker('StartDate', date_format = "%d/%m/%Y"),
twf.CalendarDatePicker('EndDate', date_format = "%d/%m/%Y" )
])
I don't have a copy of twforms laying around, but based on their sample code, it looks like you might want to do something like:
from datetime import datetime
start = twf.CalendarDatePicker('StartDate', date_format = "%d/%m/%Y")
start.default = datetime.now() # or any valid datetime object
end = twf.CalendarDatePicker('EndDate', date_format = "%d/%m/%Y" )
start.default = datetime.now() # or any valid datetime object
form = twf.TableForm('dateSel', action='changeDate', children=[start, end])