This is the representation desired for dates:
>>> tz = pytz.timezone('US/Central')
>>> datefmt = '%Y-%m-%d %H:%M:%S.%f%z(%Z)'
>>> datetime.now(tz).strftime(datefmt)
'2017-04-27 15:09:59.606921-0500(CDT)'
This is how it's logged (Python 3.6.0 on Linux):
>>> logrecord_format = '%(asctime)s %(levelname)s %(message)s'
>>> logging.basicConfig(format=logrecord_format, datefmt=datefmt)
>>> logging.error('ruh-roh!')
2017-04-27 15:10:35.%f-0500(CDT) ERROR ruh-roh!
It's not filling the microseconds properly. I've tried changing the logrecord_format to a few other things, but I could not figure it out - how to configure the logger to show microseconds and timezone in the correct way to match the strftime output exactly?
Edit: I could settle for milliseconds with offset, i.e. 2017-04-27 15:09:59,606-0500(CDT). Is that possible? logging provides %(msecs)03d directive, but I can't seem to get the timezone offset to appear after the milliseconds.
Personally, instead of integrating the timezone into the date format, I add it directly to the logged message format. Usually, the timezone should not change during the program execution.
import logging
import time
tz = time.strftime('%z')
fmt = '%(asctime)s' + tz + ' %(levelname)s %(message)s'
logging.basicConfig(format=fmt)
logging.error("This is an error message.")
# 2017-07-28 19:34:53,336+0200 ERROR This is an error message.
Related
I am trying to convert a datetime from an API that stores datetime values as UTC. I need to convert the datetime to my local time 'Pacific/Auckland'
The API I am using is Sunrise-Sunset https://sunrise-sunset.org/api
The specific location I am requesting is Christchurch, New Zealand https://sunrise-sunset.org/search?location=christchurch
import requests
api_url = 'https://api.sunrise-sunset.org/json?lat=-43.525650&lng=172.639847&formatted=0'
response = requests.get(api_url)
if response.status_code == 200:
sunset_today = response.json()['results']['sunset']
print(sunset_today) # outputs '2021-09-26T06:31:41+00:00'
I have searched StackOverflow and Google extensively, but cannot seem to find a solution that fits my needs.
The question I am asking is
How can I convert the UTC value to my local datetime ('Pacific/Auckland')?
FYI, I don't want to add bloat to the application, but from previous (unsuccessful) attempts at solving this problem I have already installed the tzlocal and pytz packages.
I am writing my application in Django 3.2.7 and have adjusted my settings.py TIME_ZONE = 'Pacific/Auckland'
Edit
When trying to convert the string to a datetime I get the following error.
time data '2021-09-26T06:31:41+00:00' does not match format '%Y-%m-%dT%H:%M:%S %Z'
sunset_today = response.json()['results']['sunset']
format = '%Y-%m-%dT%H:%M:%S %Z'
parsed_date = datetime.strptime(sunset_today, format)
print(parsed_date)
# ERROR: time data '2021-09-26T06:31:41+00:00' does not match format '%Y-%m-%dT%H:%M:%S %Z'*
To convert timezone aware string to python datetime easier to use fromisoformat, since you are getting ISO formatted string from API anyway:
import datetime
sunset_today = response.json()['results']['sunset']
parsed_date = datetime.datetime.fromisoformat(sunset_today)
# 2021-09-26 06:31:41+00:00
I solved the problem using the dateutil and pytz library
import requests
import pytz
from dateutil import parser
api_url = 'https://api.sunrise-sunset.org/json?lat=-43.525650&lng=172.639847&formatted=0'
response = requests.get(api_url)
nz_zone = pytz.timezone('Pacific/Auckland')
if response.status_code == 200:
sunset_today = response.json()['results']['sunset']
converted_date = parser.parse(sunset_today).astimezone(nz_zone)
print(converted_date) # outputs 2021-09-26 19:31:41+13:00
After a user logs in, I am setting a session variable to the time with utc.. but the timezone is getting stripped.
import datetime
from pytz import timezone
utc = timezone('utc')
session['login_time'] = datetime.datetime.now(utc)
When I print after the assignment the timezone is there 2021-06-11 23:56:00.161971+00:00. And a decorator function gets called. When I print session['login_time'] the timezone is removed. 2021-06-11 23:56:00
For me, I will use .strftime to help format the datetime and %Z is to show the timezone.
You can see the strftime document to help you format the time. I will use this code to replace your original one:
session['login_time'] = datetime.datetime.now(utc).strftime('"%Y-%m-%d %H:%M:%S%Z"')
login_time = datetime.datetime.strptime(session['login_time'],"%Y-%m-%d %H:%M:%S%Z" )
utct = utc.localize(login_time)
print(utct)
print(type(utct))
And here is the output:
2021-06-12 01:00:23+00:00
<class 'datetime.datetime'>
I had to re-add the timezone('utc') when i needed to use the time in another function.
def diff_min(t):
utc = timezone('utc')
t = utc.localize(t)
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.
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!
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")