Does django mess up with python's datetime? - python

I have a file that I check it's creation time using ctime. Here is the snippet of code (not complete, just the important part):
import time
import pytz
import os
from datetime import datetime
myfile = SOMEWHERE
myfile_ctime = os.path.getctime(myfile)
d = datetime.strptime(time.ctime(myfile_ctime), '%a %b %d %H:%M:%S %Y')
# d here is Tue Mar 25 00:33:40 2014 for example
ny = pytz.timezone("America/New_York")
d_ny = ny.localize(d)
mytz = pytz.timezone(MY_TZ_WHATEVER)
myd = d_ny.astimezone(mytz)
final_date = myd.strftime('%Y-%m-%d %H:%M:%S')
print(final_date + "some string")
# is now 2014-03-25 01:33:40some string, correctly with the timezone.
When this is run as a simple python script, everything is ok. But when I run the same code inside a function in a templatetags/myfile.py that renders to a template in a Django App, when trying to get the date from time.ctime(myfile_ctime), then I get Tue Mar 25 04:33:40 instead of Tue Mar 25 00:33:40 from the snippet above (the code is the same in the standalone script and in Django - and I concatenate the date with another string).
My question is: I'm using just Python standard libraries, same snippet of code in both places, reading the same file in the same environment. Why the difference? Do settings in settings.py mangles up something in the standard libraries? Just being in a Django environment it changes how standard libraries should work? Why when calling standalone everything works as it should?
(I'm behind apache, don't know if this is relevant)

Make sure of the Time Zone settings in settings.py, for more info about Django Time Zone Settings, check this page: https://docs.djangoproject.com/en/1.6/ref/settings/#time-zone

In ./django/conf/__init__.py:126:, TZ environment variable is set based on settings.py.
os.environ['TZ'] = self.TIME_ZONE
My TIME_ZONE is UTC.
That's why a standalone script result is different from a snippet inside Django: when running standalone, this environment variable TZisn't set.
Now, when creating a datetime object from a myfile_ctime, I just need to add tzinfo from my server (/etc/sysconfig/clock). My code now looks like this:
import time
import pytz
import os
from datetime import datetime
myfile = SOMEWHERE
myfile_ctime = os.path.getctime(myfile)
ny = pytz.timezone("America/New_York")
d = datetime.fromtimestamp(myfile_ctime, tz=ny)
mytz = pytz.timezone(MY_TZ_WHATEVER)
myd = d.astimezone(mytz)
final_date = myd.strftime('%Y-%m-%d %H:%M:%S')
I hope this is useful to someone. As always, read the source. :)

Related

How do I get website to display local time?

If I run this in VS Code, it gives me the correct local time:
from time import strftime
time = strftime("%H:%M %p")
print(time)
But if I use the same code in a Django project, my website displays a time which is 8 hours behind local time.
from time import strftime,localtime
def time_display(request):
context = {
"date":strftime("%b %d, %Y",localtime()), #DOESN'T DISPLAY LOCAL TIME
"time1": strftime("%H:%M %p",localtime()), #DOESN'T DISPLAY LOCAL TIME
"time3": strftime("%H:%M %p"), #DOESN'T DISPLAY LOCAL TIME
}
return render(request,'time_display.html',context)
How do I fix it to display correct local time where the webpage is being viewed?
Not an expert but you can change setting.py file like:
TIME_ZONE = 'Europe/London'
note: change Europe/London to your time zone.
You can find a list of timezone names here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Convert UTC time into local time using python

i want to convert UTC time into user's browser time.
i have tried a loat but its display me system time only.
working with django application. can anybudy help me out.
import pytz
from tzlocal import get_localzone
def utc_to_local(utc_dt):#utc_dt that is UTC time
local_tz = get_localzone()
print local_tz #that is display system timezone inplace of USER's timezone
I have tried with below code.
import time
from datetime import datetime
from dateutil import tz
utc = datetime.strptime(str(utc_dt)[:19], '%Y-%m-%d %H:%M:%S')
return time.mktime(utc_dt.timetuple()) * 1000
convert utc time into second and then using javascript need to make it localtime. but conversion value not accurate and its display me wrong date.
Javascript code.
//1449206930000 #Seconds when above code run
//1449226703.79 #that is correct >> time.time() in python = 1449226703.79
#below code give perfact output
var date = new Date(parseInt(1449226703.79, 10) * 1000);
console.log(date);
#below code not working
var date = new Date(parseInt(1449206930000, 10) * 1000);
console.log(date);
Regards
You need to find the users timezone first, to convert time in there local timezone.
There are two ways to do it.
1) Pass simply UNIX-timestamp then use a Javascript to convert it in human readable time on the browser momentjs can help you with that.
function human_time(unixtime, tz) {
var t=moment.unix(unixtime);
return t.tz(tz).format('DD/MM/YY HH:mm:ss');
}
2) Use IP address or HTTP headers to detect the user location and then use pytz to convert your time in users system timezone instead of your own django/server timezone.
def get_user_timezone(request):
return request.visitor.location.timezone
def human_time(dt, tz="Asia/Kolkata"):
try:
tz = pytz.timezone(tz)
except:
tz = pytz.timezone("Asia/Kolkata")
dt = dt.astimezone(tz)
return dt.strftime(r'%d/%m/%Y %H:%M:%S %Z')
def view_get_local_time(request):
tz = get_user_timezone(request) #detect user timezone, base on IP
text = human_time(timezone.now(), tz) #convert server-time to detected timezone
return HttpResponse(text)
Note: First method is the most preferable method.
import time, calendar
import datetime
utc = datetime.datetime.strptime(str(timezone_rt)[:19], '%Y-%m-%d %H:%M:%S')
return time.mktime(time.localtime(calendar.timegm(utc.timetuple()))) #convert utc time into second that correct output like function time.time()
Thanks for help.

How do I strftime a date object in a different locale? [duplicate]

This question already has answers here:
Locale date formatting in Python
(6 answers)
Closed 2 years ago.
I have a date object in python and I need to generate a time stamp in the C locale for a legacy system, using the %a (weekday) and %b (month) codes. However I do not wish to change the application's locale, since other parts need to respect the user's current locale. Is there a way to call strftime() with a certain locale?
The example given by Rob is great, but isn't threadsafe. Here's a version that works with threads:
import locale
import threading
from datetime import datetime
from contextlib import contextmanager
LOCALE_LOCK = threading.Lock()
#contextmanager
def setlocale(name):
with LOCALE_LOCK:
saved = locale.setlocale(locale.LC_ALL)
try:
yield locale.setlocale(locale.LC_ALL, name)
finally:
locale.setlocale(locale.LC_ALL, saved)
# Let's set a non-US locale
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
# Example to write a formatted English date
with setlocale('C'):
print(datetime.now().strftime('%a, %b')) # e.g. => "Thu, Jun"
# Example to read a formatted English date
with setlocale('C'):
mydate = datetime.strptime('Thu, Jun', '%a, %b')
It creates a threadsafe context manager using a global lock and allows you to have multiple threads running locale-dependent code by using the LOCALE_LOCK. It also handles exceptions from the yield statement to ensure the original locale is always restored.
No, there is no way to call strftime() with a specific locale.
Assuming that your app is not multi-threaded, save and restore the existing locale, and set your locale to 'C' when you invoke strftime.
#! /usr/bin/python3
import time
import locale
def get_c_locale_abbrev():
lc = locale.setlocale(locale.LC_TIME)
try:
locale.setlocale(locale.LC_TIME, "C")
return time.strftime("%a-%b")
finally:
locale.setlocale(locale.LC_TIME, lc)
# Let's suppose that we're french
locale.setlocale(locale.LC_ALL, 'fr_FR.utf8')
# Should print french, english, then french
print(time.strftime('%a-%b'))
print(get_c_locale_abbrev())
print(time.strftime('%a-%b'))
If you prefer with: to try:-finally:, you could whip up a context manager:
#! /usr/bin/python3
import time
import locale
import contextlib
#contextlib.contextmanager
def setlocale(*args, **kw):
saved = locale.setlocale(locale.LC_ALL)
yield locale.setlocale(*args, **kw)
locale.setlocale(locale.LC_ALL, saved)
def get_c_locale_abbrev():
with setlocale(locale.LC_TIME, "C"):
return time.strftime("%a-%b")
# Let's suppose that we're french
locale.setlocale(locale.LC_ALL, 'fr_FR.utf8')
# Should print french, english, then french
print(time.strftime('%a-%b'))
print(get_c_locale_abbrev())
print(time.strftime('%a-%b'))
take a look to the pytz package
you can use like this
import pytz
UTC = pytz.timezone('UTC') # utc
fr = pytz.timezone('Europe/Paris') #your local
from datetime import datetime
date = datetime.now(fr)
dateUTC = date.astimezone(UTC)
strftime will render in the timezone specified
for have month name in the locale use calendar for example :
import calendar
print calendar.month_name[dateUTC.month] #will print in the locale
inspect more deeply calendar for having more information

Using python-twitter library, how to set timezone?

I'm trying to list out tweets with their time-stamps. I have this...
#!/usr/bin/python
import twitter
api = twitter.Api()
statuses = api.GetUserTimeline('ttytter')
for s in statuses:
print s.created_at + " " + s.text
Which prints out...
Sat Oct 20 04:56:47 +0000 2012 #uriel1998 W/r/t DMs, they appear just fine in 2.0.4 and 2.1 beta here, near as I can tell.
Which is pretty much what I'm after, but for the time, which seems to be in the wrong timezone. https://twitter.com/ttytter/status/259518502069760000
Is there a way I can change this within the python-twitter library? I was looking at GetTimeZone() and SetTimeZone(), but I haven't been able to figure out how they work.
Also looking at how to shift a datetime object by 12 hours in python but not sure if I need to go there.
Thanks for any help!
python-twitter returns the status timestamps as a string and as the number of seconds since the epoch. The latter is the simplest to convert to a timezone-aware datetime instance (see this answer).
Unfortunately the user's time_zone attribute is not in the standard tz database format used by pytz, so it is necessary to use the utc_offset user attribute instead (we still use the time_zone attribute to name the tzinfo created with with the UTC offset). The python-dateutil package provides a convenience type tzoffset that allows the creation of tzinfo instances from UTC offsets, which we can then use to convert the datetime from UTC to the local time zone:
import pytz
import twitter
from datetime import datetime
from dateutil.tz import tzoffset
USERNAME = 'ttytter'
api = twitter.Api()
# get a 'tzinfo' instance with the UTC offset for the user's local time
user = api.GetUser(USERNAME)
localtime_tz = tzoffset(user.time_zone, user.utc_offset)
statuses = api.GetUserTimeline(USERNAME)
for s in statuses[:1]:
# get UTC timestamp from seconds since epoch
utc_dt = datetime.utcfromtimestamp(s.created_at_in_seconds).replace(tzinfo=pytz.utc)
print('utc: {}'.format(utc_dt))
# convert to local time in the user's timezone
localtime_dt = utc_dt.astimezone(localtime_tz)
print('localtime [{}]: {}'.format(localtime_dt.tzname(), localtime_dt))
which gives the output for the first status:
utc: 2012-10-20 04:56:47+00:00
localtime [Pacific Time (US & Canada)]: 2012-10-19 20:56:47-08:00
Combining suggestions from Pedro Romano and J.F. Sebastian, I have this...
import pytz
import twitter
from datetime import datetime
USERNAME = 'ttytter'
api = twitter.Api()
user = api.GetUser(USERNAME)
pst_tz = pytz.timezone('America/Los_Angeles')
statuses = api.GetUserTimeline(USERNAME)
for s in statuses[:1]:
# get UTC timestamp from seconds since epoch
utc_dt = datetime.utcfromtimestamp(s.created_at_in_seconds).replace(tzinfo=pytz.utc)
# convert to given timezone
pst_dt = pst_tz.normalize(utc_dt.astimezone(st_tz))
print(pst_dt.strftime('%Y-%m-%d %H:%M:%S ')) + s.text
Output: 2012-10-19 21:56:47 #uriel1998 W/r/t DMs, they appear just fine in 2.0.4 and 2.1 beta here, near as I can tell. which is the correct time zone and also accounts for DST.
Thank you!

How do you add datetime to a logfile name?

When I create my logfile, I want the name to contain the datetime.
In Python you can get the current datetime as:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2012, 2, 3, 21, 35, 9, 559000)
The str version is
>>> str(datetime.now())
'2012-02-03 21:35:22.247000'
Not a very nice str to append to the logfile name! I would like my logfile to be something like:
mylogfile_21_35_03_02_2012.log
Is there something Python can do to make this easy? I am creating the log file as:
fh = logging.FileHandler("mylogfile" + datetimecomp + ".log")
You need datetime.strftime(), this allows you to format the timestamp using all of the directives of C's strftime(). In your specific case:
>>> datetime.now().strftime('mylogfile_%H_%M_%d_%m_%Y.log')
'mylogfile_08_48_04_02_2012.log'
You could also use a TimedRotatingFileHandler that will handle the date and the rollover every day (or whenever you want) for you.
from logging.handlers import TimedRotatingFileHandler
fh = TimedRotatingFileHandler('mylogfile', when='midnight')
By default the format will be depending on the rollover interval:
The system will save old log files by appending extensions to the filename. The extensions are date-and-time based, using the strftime format %Y-%m-%d_%H-%M-%S or a leading portion thereof, depending on the rollover interval.
But you can modify that as showed here, by doing something like:
from logging.handlers import TimedRotatingFileHandler
fh = TimedRotatingFileHandler('mylogfile', when='midnight')
fh.suffix = '%Y_%m_%d.log'
Yes. Have a look at the datetime API, in particular strftime.
from datetime import datetime
print datetime.now().strftime("%d_%m_%Y")
Another Solution using format():
#generates a date for a generic filename
import datetime
date_raw = datetime.datetime.now()
date_processed = "{}-{}-{}_{}-{}-{}".format(date_raw.year, date_raw.month,
date_raw.day, date_raw.hour, date_raw.minute, date_raw.second)
#example value: date_processed = 2020-1-7_17-17-48
I used this in my own project
edit: as I found out about f(ormatted)-strings, this would be another solution:
date_processed = f"{date_raw.year}-{date_raw.month}-{date_raw.day}_{date_raw.hour}-{date_raw.minute}-{date_raw.second}"
We can use datetime.now() to get current timestamp. Here is my code that I am using to create log file with timestamp -
import logging
from datetime import datetime
LOG_FILENAME = datetime.now().strftime('D:/log/logfile_%H_%M_%S_%d_%m_%Y.log')
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
logging.info('Forecastiong Job Started...')
logging.debug('abc method started...')
from time import strftime
fh = logging.FileHandler(strftime("mylogfile_%H_%M_%m_%d_%Y.log"))
To print hour, minutes, day, month and year, use the following statement
from datetime import datetime
print datetime.now().strftime("%H_%M_%d_%m_%Y")

Categories