python: logging:: get the current time in a custom timezone - python

I am trying the following code to log using the timezone 'America/New_York'
the time is shown correct, but the %z and %Z are not showing the right time Zone
from datetime import datetime
from pytz import timezone
import logging
def timetz(*args):
tz = timezone('America/New_York')
print(tz)
dt = datetime.now(tz)
print(dt)
return dt.timetuple()
logger = logging.getLogger()
formatter = logging.Formatter(fmt='%(asctime)s::%(levelname)-8s\n%(message)s',datefmt='%Y-%m-%d %H:%M:%S %p %Z %z')
formatter.converter = timetz
formatter.default_msec_format = '%s.%03d'
handler= logging.StreamHandler()
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)
logger.addHandler(handler)
logger.error('test')
I get
2021-03-05 14:53:04 PM UTC +0000::ERROR
test
But i should get
2021-03-05 14:53:04 PM EST -0500::ERROR
test
The %z and %Z are not working

Related

Convert hour string containing pm to datetime

I want to convert a string that contains PM notation to a datetime type. Thanks!
datetime.strptime('8/18/2020 11:08:54 PM', '%m/%d%Y %I:%M:%S %p' )
I am getting this error
ValueError: time data '8/18/2020 11:08:54 PM' does not match format '%m/%d%Y %I:%M:%S %p'
You can use this code. It's very simple.
r = datetime.strptime('8/18/2020 11:08:54 PM', '%m/%d/%Y %I:%M:%S %p')
Or
import dateparser
r = dateparser.parse('8/18/2020 11:08:54 PM')
print(r)
Here is an answer using the builtin datetime module:
from datetime import datetime
date_str = '8/18/2020 11:08:54 PM'
fmt = '%m/%d/%Y %I:%M:%S %p'
parsed_date = datetime.strptime(date_str, fmt)

How to get current GMT time in this very format "Sun, 22 Sep 2019 09:18:13 GMT" in python

Even tho it's not used anymore in favor of UTC, the endpoint i am trying to query requires an hmac signature with a date header in this format : "Sun, 22 Sep 2019 09:18:13 GMT"
This deprecated method new Date().toGMTString(); makes the js sdk works, i need an equivalent in python.
time.strftime("%a, %d %b %Y %I:%M:%S %Z", time.gmtime()) returns the full name (i.e. CENTRAL EUROPE TIME) while time.strftime("%a, %d %b %Y %I:%M:%S %z", time.gmtime()) returns "Sun, 22 Sep 2019 09:18:13 +0100".
The closest i got istime.strftime("%a, %d %b %Y %I:%M:%S GMT", time.gmtime()) which in theory print the right string, but i keep getting this error anyway: "{\"message\":\"HMAC signature cannot be verified, a valid date or x-date header is required for HMAC Authentication\"}"
import datetime
print(datetime.datetime.now(datetime.timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT'))
This works for me :)
Source of the formattings
Have a look here: https://www.programiz.com/python-programming/datetime/strftime
Be sure that you use %Z and not %z.
from datetime import datetime
import time
now = datetime.now() # current date and time
date_time = time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.gmtime())
# output: date and time: Sun, 22 Sep 2019 10:01:53 GMT
print("date and time in GMT:",date_time)
# output: Local: Sun, 22 Sep 2019 10:01:53 AM UTC
print("Local: " + time.strftime("%a, %d %b %Y %I:%M:%S %p %Z\n"))

Python CSV Finding average time taken

I am trying to find the average time taken. The value 'x' will allow me to get the time taken for every row there is, but how am I able to find the average time taken for all the rows. I will think it is something like x divided by count, but I am not able to find a solution to this... any pros out there can help me??
import datetime,time,csv
from itertools import islice
from Tkinter import Tk #python GUI programming
from tkFileDialog import askopenfilename
from collections import Counter
from datetime import datetime
import pandas
Tk().withdraw()
category_list=[]
description_list=[]
reported_date=[]
acknowledged_date=[]
count = 0
# hard code all possible date formats
date_formats = ['%m/%d/%Y %H:%M', '%-d-%b-%y', '%d/%m/%Y %h:%M %p', '%d/%m/%Y %H:%M', '%A, %d %B %Y %H:%M','%A, %d %B %Y %H:%M','%A %d %B %Y %H%M',"%d/%m/%Y %H:%M %p"," %d/%m/%Y %H:%M %p", '%d-%b-%y' ,
'%d.%m.%Y', '%d %b %Y %H%M hrs', '%d %b %Y %H%M', '%d-%m-%y', '%d-%b-%y', '%b-%d-%y', '%d-%a-%y','%e-%a-%y','%b %d %Y %H%M hrs','%d/%b/%Y %m:%M %p','%A, %e %B %Y %H:%M',' %d/%m/%Y %h:%M','%d-%b-%y','%m/%d/%Y %H:%M:%S %p']
#file = askopenfilename() #ask user which file to open
#f = open(file,'r')
with open('Feedback and Complaints_Sample Dataset.csv', 'rb') as f:
reader = csv.reader(f)
header = next(reader) #read 2nd line onwards
data= [] #make a list called data
for row in reader: #assign data in every column and name them respectively
for format in date_formats:
try:
reported_on = datetime.strptime(row[0], format) #try and get the dates
acknowledged_on = datetime.strptime(row[12], format) #try and get the dates
x= acknowledged_on-reported_on #time taken to acknowledge
#acknowledged_date.append(acknowledged_on)
#reported_date.append(reported_on)
count += 1
break # if correct format, dont test any other formats
except ValueError:
pass # if incorrect format, try other formats`enter code here`
Subtracting two datetime objects creates a timedelta object. You need to keep a total time, so create a timedelta object, and for each x add it to your total.
At the end, you can then divide your total_time by your count:
import csv
from itertools import islice
from datetime import datetime, timedelta
count = 0
total_time = timedelta()
# hard code all possible date formats
date_formats = ['%m/%d/%Y %H:%M', '%-d-%b-%y', '%d/%m/%Y %h:%M %p', '%d/%m/%Y %H:%M', '%A, %d %B %Y %H:%M','%A, %d %B %Y %H:%M','%A %d %B %Y %H%M',"%d/%m/%Y %H:%M %p"," %d/%m/%Y %H:%M %p", '%d-%b-%y' ,
'%d.%m.%Y', '%d %b %Y %H%M hrs', '%d %b %Y %H%M', '%d-%m-%y', '%d-%b-%y', '%b-%d-%y', '%d-%a-%y','%e-%a-%y','%b %d %Y %H%M hrs','%d/%b/%Y %m:%M %p','%A, %e %B %Y %H:%M',' %d/%m/%Y %h:%M','%d-%b-%y','%m/%d/%Y %H:%M:%S %p']
with open('Feedback and Complaints_Sample Dataset.csv', 'rb') as f:
reader = csv.reader(f)
header = next(reader) #read 2nd line onwards
for row in reader:
for format in date_formats:
try:
reported_on = datetime.strptime(row[0], format) #try and get the dates
acknowledged_on = datetime.strptime(row[12], format) #try and get the dates
x = acknowledged_on - reported_on #time taken to acknowledge
total_time += x
count += 1
break # if correct format, don't test any other formats
except ValueError:
pass # if incorrect format, try other formats`enter code here`
print "Total time taken:", total_time
print "Average time taken:", total_time / count
Note: your logic for the date_formats implies that both dates in a single row will always share the same date format.

Python: timezone.localize() not working

I am having some issues getting timezone.localize() to work correctly. My goal is to grab today's date and convert it from CST to EST. Then finally format the datetime before spitting it out. I am able to format the date correctly, but the datetime is not changing from CST to EST. Additionally when I format the date I don't see the text representation of the timezone included.
Below I have listed out a simple program I created to test this out:
#! /usr/bin/python
#Test script
import threading
import datetime
import pexpect
import pxssh
import threading
from pytz import timezone
import pytz
est = timezone('US/Eastern')
curtime = est.localize(datetime.datetime.now().strftime("%a %b %d %H:%M:%S %Z %Y"))
#test time change
#curtime = datetime.datetime.now().strftime("%a %b %d %H:%M:%S %Z %Y")
class ThreadClass(threading.Thread):
def run(self):
#now = (datetime.datetime.now() + datetime.timedelta(0, 3600))
now = (datetime.datetime.now())
print "%s says Hello World at time: %s" % (self.getName(), curtime)
for i in range(3):
t = ThreadClass()
t.start()
.localize() takes a naive datetime object and interprets it as if it is in that timezone. It does not move the time to another timezone. A naive datetime object has no timezone information to be able to make that move possible.
You want to interpret now() in your local timezone instead, then use .astimezone() to interpret the datetime in another timezone:
est = timezone('US/Eastern')
cst = timezone('US/Central')
curtime = cst.localize(datetime.datetime.now())
est_curtime = curtime.astimezone(est).strftime("%a %b %d %H:%M:%S %Z %Y")
def run(self):
print("%s says Hello World at time: %s" % (self.getName(), est_curtime))
Use cst.localize to make a naive datetime into a timezone-aware datetime.
Then use astimezone to convert a timezone-aware datetime to another timezone.
import pytz
import datetime
est = pytz.timezone('US/Eastern')
cst = pytz.timezone('US/Central')
curtime = cst.localize(datetime.datetime.now())
curtime = curtime.astimezone(est)

How to Customize the time format for Python logging?

I am new to Python's logging package and plan to use it for my project. I would like to customize the time format to my taste. Here is a short code I copied from a tutorial:
import logging
# create logger
logger = logging.getLogger("logging_tryout2")
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(message)s")
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
# "application" code
logger.debug("debug message")
logger.info("info message")
logger.warn("warn message")
logger.error("error message")
logger.critical("critical message")
And here is the output:
2010-07-10 10:46:28,811;DEBUG;debug message
2010-07-10 10:46:28,812;INFO;info message
2010-07-10 10:46:28,812;WARNING;warn message
2010-07-10 10:46:28,812;ERROR;error message
2010-07-10 10:46:28,813;CRITICAL;critical message
I would like to shorten the time format to just: '2010-07-10 10:46:28', dropping the mili-second suffix. I looked at the Formatter.formatTime, but I am confused.
From the official documentation regarding the Formatter class:
The constructor takes two optional arguments: a message format string and a date format string.
So change
# create formatter
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(message)s")
to
# create formatter
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(message)s",
"%Y-%m-%d %H:%M:%S")
Using logging.basicConfig, the following example works for me:
logging.basicConfig(
filename='HISTORYlistener.log',
level=logging.DEBUG,
format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
This allows you to format & config all in one line. A resulting log record looks as follows:
2014-05-26 12:22:52.376 CRITICAL historylistener - main: History log failed to start
To add to the other answers, here are the variable list from Python Documentation.
Directive Meaning Notes
%a Locale’s abbreviated weekday name.
%A Locale’s full weekday name.
%b Locale’s abbreviated month name.
%B Locale’s full month name.
%c Locale’s appropriate date and time representation.
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%I Hour (12-hour clock) as a decimal number [01,12].
%j Day of the year as a decimal number [001,366].
%m Month as a decimal number [01,12].
%M Minute as a decimal number [00,59].
%p Locale’s equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locale’s appropriate date representation.
%X Locale’s appropriate time representation.
%y Year without century as a decimal number [00,99].
%Y Year with century as a decimal number.
%z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].
%Z Time zone name (no characters if no time zone exists).
%% A literal '%' character.
if using logging.config.fileConfig with a configuration file use something like:
[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S
Try These Formats:
Format 1:
'formatters': {
'standard': {
'format' : '%(asctime)s |:| LEVEL: %(levelname)s |:| FILE PATH: %(pathname)s |:| FUNCTION/METHOD: %(funcName)s %(message)s |:| LINE NO.: %(lineno)d |:| PROCESS ID: %(process)d |:| THREAD ID: %(thread)d',
'datefmt' : "%y/%b/%Y %H:%M:%S"
},
}
Output of Format 1:
Format 2:
'formatters': {
'standard': {
'format' : '%(asctime)s |:| LEVEL: %(levelname)s |:| FILE PATH: %(pathname)s |:| FUNCTION/METHOD: %(funcName)s %(message)s |:| LINE NO.: %(lineno)d |:| PROCESS ID: %(process)d |:| THREAD ID: %(thread)d',
'datefmt' : "%Y-%m-%d %H:%M:%S"
},
}
Output of Format 2:
In order to customize time format while logging we can create a logger object and and a fileHandler to it.
import logging
from datetime import datetime
logger = logging.getLogger("OSA")
logger.setLevel(logging.DEBUG)
filename = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ".log"
fileHandler = logging.FileHandler(filename, mode="a")#'a' for append you can use 'w' for write
formatter = logging.Formatter(
"%(asctime)s : %(levelname)s : [%(filename)s:%(lineno)s - %(funcName)s()] : %(message)s",
"%Y-%m-%d %H:%M:%S")
fileHandler.setFormatter(formatter)
logger.addHandler(fileHandler)

Categories

Resources