I'm working on Google app engine with Python.
I have stored a datetime object in database and fetched it and applied timezone, and I saved it using template. The result is "2011-03-15 16:54:24.398503+09:00", but what I want is: "2011-03-16 01:54:24" (timezone applied string without millisecond - note that day is changed).
How can I do that?
Once you have the datetime object, use strftime, like so;
from datetime import datetime
datetime.now().strftime('%Y-%m-%d %H:%M:%S')
http://docs.python.org/release/2.6.6/library/datetime.html#strftime-and-strptime-behavior
using strftime is encouraged, but make sure that your localtime is correct. This should be a setting in your app/site assuming you're using django, or you may have to do this manually
Related
How do I convert custom datetime value ex. "15:22:03 13/11/2019"
to "13/11/2019 15:22:03" to add value as datetime in models?
Or how do i change default django datetime format?
thank you
You can use this to change the default:
date = models.DateField(blank=False, default=datetime.now().strftime(("%d.%m.%Y %H:%M:%S")))
You can get the % strings at the bottom of this page to make it fit the format you asked for in the column, i can update it for you if you can't get it to work, i'm pretty good with Django.
https://docs.python.org/2/library/datetime.html
You can convert your datetime string to datetime object and insert the date into your database.
from datetime import datetime
date_str = "15:22:03 13/11/2019"
temp_date = datetime.strptime(date_str, "%H:%M:%S %d/%m/%Y").date()
ModelClassName.objects.create(name='ABC', date_time=temp_date)
installed dateutil.parser
in view added
from dateutil.parser import parse as date_parse
and in csv import, in a needed row just added date_parse
reading_date=date_parse(READING_DATE),
I have a list of timestamps which look like so:
time_list=['2016-10-01T00:00:00+01:00','2016-10-01T23:00:00+00:00','2016-10-01T22:00:00+02:00',..]
I would like to apply a magic function to this list which gets them all in +00:00 timezone - this should result in (all timestamps should correctly adjusted to the +00:00 format):
ret_list=['2016-10-01T23:00:00+00:00','2016-10-01T23:00:00+00:00','2016-10-01T23:00:00+00:00',..]
You have to convert your isoformat strings to datetime objects first, change timezones to UTC and then stringify back.
If you are on python 3.7, according to this, you can use fromisoformat method of datetime, but if you don't, like me, I think the best option involves the use of dateutil module (you have to install it) and pytz:
import datetime as dt
from dateutil import parser
import pytz
time_list = ['2016-10-01T00:00:00+01:00','2016-10-01T23:00:00+00:00','2016-10-01T22:00:00+02:00']
utc_time_list = [parser.parse(x).astimezone(pytz.utc).isoformat() for x in time_list]
print(utc_time_list)
['2016-09-30T23:00:00+00:00', '2016-10-01T23:00:00+00:00', '2016-10-01T20:00:00+00:00']
I am trying to parse an RSS feed. Entries in the feed have date elements like:
<dc:date>2016-09-21T16:00:00+02:00</dc:date>
Using feedparser, I try to do:
published_time = datetime.fromtimestamp(mktime(entry.published_parsed))
But the problem is that I seem to be getting the wrong time stored in the database. In this particular case, the datetime is stored as:
2016-09-21 13:00:00
... when I would expect 14:00 - the correct UTC time.
I assume the problem is in our django settings, where we have:
TIME_ZONE = 'Europe/Berlin'
Because when I switch to:
TIME_ZONE = 'UTC'
... the datatime is stored as correct UTC time:
2016-09-21 14:00:00
Is there any way to keep the django settings as they are, but to parse and store this datetime correctly, without the django timezone setting affecting it?
EDIT:
Maybe it's more clear like this...
print entry.published_parsed
published_time = datetime.fromtimestamp(mktime(entry.published_parsed))
print published_time
localized_time = pytz.timezone(settings.TIME_ZONE).localize(published_time, is_dst=None)
print localized_time
time.struct_time(tm_year=2016, tm_mon=9, tm_mday=21, tm_hour=14, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=265, tm_isdst=0)
2016-09-21 15:00:00
2016-09-21 15:00:00+02:00
feedparser's entry.published_parsed is always a utc time tuple whatever the input time string is. To get timezone-aware datetime object:
from datetime import datetime
utc_time = datetime(*entry.published_parsed[:6], tzinfo=utc)
where utc is a tzinfo object such as datetime.timezone.utc, pytz.utc, or just your custom tzinfo (for older python versions).
You shouldn't pass utc time to mktime() that expects a local time. Same error: Have a correct datetime with correct timezone.
Make sure USE_TZ=True so that django uses aware datetime objects everywhere. Given a timezone-aware datetime object, django should save it to db correctly whatever your TIME_ZONE or timezone.get_current_timezone() are.
Have you tried using datetime.utcfromtimestamp() instead of datetime.fromtimestamp()?
As a secondary solution, you can get the unparsed data (I believe it's available as entry.published?) and just use python-dateutil to parse the string, then convert it to pytz.utc timezone like this.
>>> import pytz
>>> from dateutil import parser
>>> dt = parser.parse('2016-09-21T16:00:00+02:00')
>>> dt
datetime.datetime(2016, 9, 21, 16, 0, tzinfo=tzoffset(None, 7200))
>>> dt.astimezone(pytz.utc)
datetime.datetime(2016, 9, 21, 14, 0, tzinfo=<UTC>)
Use
published_time = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Feedparser can parse a large range of date formats, you can find them here.
As you can see in feedparser/feedparser/datetimes/__init__.py, the built-in function from Feedparser _parse_date does the following:
Parses a variety of date formats into a 9-tuple in GMT
This means that in parsed_entry.published_parsed you have a time.struct_time object in GMT timezone.
When you convert it to a datetime object using
published_time = datetime.fromtimestamp(mktime(parsed_entry.published_parsed))
the problem is that mktime assumes that the passed tuple is in local time, which is not, it's GMT/UTC! Other than that you don't properly localize the datetime object at the end of the conversion.
You need to replace that conversion with the following, remembering that Feedparser returns a GMT struct_time, and localize that with the timezone you like (UTC for the sake of simplicity).
You use calendar.timegm, which gives the number of seconds between epoch and the date passed as a parameter, assuming that the passed object is in UTC/GMT (we know from Feedparser it is)
You use utcfromtimestamp to obtain a naive datetime object (which we know represents a datetime in UTC, but Python does not at this moment)
With pytz.utc.localize you properly localize in UTC the datetime object.
Example:
import calendar
from datetime import datetime
import pytz
localized_dt = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
As long as you are consistent, it doesn't matter if you use fromtimestamp or utcfromtimestamp. If you use fromtimestamp you need to tell Python that the datetime object you created has the local timezone. Supposing you are in Europe/Berlin, this is also fine:
pytz.timezone('Europe/Berlin').localize(datetime.fromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Were parsed_entry.published_parsed also in local timezone, mktime must be used in place of calendar.timegm.
As an alternative you can parse yourself the data string you get from Feedparser parsed_entry['published']
from dateutil import parser
localized_dt = parser.parse(parsed_entry['published'])
You can check that the following returns True:
parser.parse(parsed_entry['published']) == pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
The Django TIME_ZONE setting doesn't actually matter, because it's used only for visualization purposes or to automatically convert naive datetimes.
When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
What is important is to always use properly localized datetimes, no matter which time zone is used. As long as they are not in naive format, they will be properly handled by Django.
I'm using the following to get utc datetime:
import datetime
import time
from pytz import timezone
now_utc = datetime.datetime.now(timezone('UTC'))
now = time.time()
print now_utc.time(), now
>> 04:51:39.337515 1332823899.34
I need to convert the format of now_utc.time() to look like the output of time.time().
How do I do that? Or, how to I get time.time() in utc?
time.mktime(now_utc.timetuple())
Updating the answer, since it was completely wrong, but mistake I made can be useful for others.
time.mktime does not retain the timezone, using the tuple as a local time, so this:
time.mktime(datetime.now().timetuple())
would rather work.
But, to make it short, time.time(), as explicitly stated in the spec, returns an UTC timestamp, so just use it.
(Also, you don't need pytz to get an UTC datetime, datetime.utcnow() does the same)
try:
now_utc.time().strftime(....)
from here
How to set default datetime format in python because i have multiple tuples to send via template on client side. This is not good approach to set each object's value to specified format. I want to set a datetime format on server side and these converted values will be shown to client. I tried
datetime.strftime("%Y-%m-%d %X")
but it is giving error.
strftime is a method of datetime objects - it doesn't set a default representation, which seems to be what you suggest. For example, you might call it like this:
>>> import datetime
>>> now = datetime.datetime.now()
>>> now.strftime("%Y-%m-%d %X")
'2011-03-17 10:14:12'
If you need to do this a lot, it would be worth creating a method that wraps this conversion of a datetime to a string. The documentation for the datetime module can be found here.
I'm not sure I understand your issue, but this might help
http://docs.djangoproject.com/en/dev/ref/settings/
there is a datetime format section, this sets datetime format globally.