I am reading data from a csv file, and there are date elements in it, but there is an inconsistency in the dates.
For example: sometimes the date element is like 1/1/2011 and sometimes it is like 01/01/2011
Since I am plotting this data later.. this causes a great deal of noise in my plots. The following is my date class. Can you help me out in where and how to modify the code in order to get the date in the form 01/01/2011
import re
class Date:
def __init__(self, input_date):
self._input_date = input_date
self._date = None
self._month = None
self._year = None
self._hour = None
self._min = None
def setDate(self):
date = self._input_date
#date = re.findall('w+',date)
date = self.__mySplit()
#print"len ",len(date)
assert (len(date) >= 3) #has atleast dd/mm/yy
#dateLength = len(date[0])
self._month = int(date[0])
self._date = int(date[1])
self._year = int(date[2])
if (len(date) ==5):
self._hour = int(date[3])
self._min = int(date[4])
def __mySplit(self): #splitting the date by delimiters..
res = [self._input_date]
#print res
seps = [' ','/',':']
for sep in seps:
s,res = res,[]
for seq in s:
res += seq.split(sep)
#print res
return res
Thanks
You definitely want to be using datetime. Here's some code that will get a datetime from either string type:
from datetime import datetime
def strToDatetime(dateStr):
return datetime.strptime(dateStr, "%d/%m/%Y")
Then, you can print a datetime out in the format you want with:
strToDatetime("1/3/2011").strftime("%d/%m/%Y)
>'01/03/2011'
You should never need to roll your own date/time/datetime structure in python.
Related
Is there a way to convert to date format will use the Printer and QTextDocument the result always show in the date and time like in the image?
this is my code
def handlePaintRequest(self, printer):
model_hjd = QSqlTableModel()
model_hjd.setTable('transactions')
date = str(self.dateEdit_10.text())
date_2 = str(self.dateEdit_14.text())
self.tableView_22.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
model_hjd.setSort(6, Qt.DescendingOrder)
self.tableView_22.setModel(model_hjd)
model_hjd.select()
filter_ft = "date_d BETWEEN '%s' AND '%s'" % (date, date_2)
model_hjd.setFilter(filter_ft)
self.tableView_22.setModel(model_hjd)
document = QTextDocument()
cursor = QTextCursor(document)
tableFormat = QTextTableFormat()
table = cursor.insertTable(model_hjd.rowCount() + 1, model_hjd.columnCount(), tableFormat)
myheaders = []
for i in range(0, model_hjd.columnCount()):
myheader = model_hjd.headerData(i, Qt.Horizontal)
cursor.insertText(myheader)
cursor.movePosition(QTextCursor.NextCell)
for row in range(0, model_hjd.rowCount()):
for col in range(0, model_hjd.columnCount()):
index = model_hjd.index( row, col )
cursor.insertText(str(index.data()))
cursor.movePosition(QTextCursor.NextCell)
document.print_(printer)
but the result in date and time are like this
You could use a custom function to format the different types of data in your table, e.g.
#staticmethod
def to_string(entry):
if isinstance(entry, (QtCore.QDate, QtCore.QTime, QtCore.QDateTime)):
return entry.toString(Qt.SystemLocaleShortDate)
else:
return str(entry)
def handlePaintRequest(self, printer):
....
cursor.insertText(self.to_string(index.data()))
....
I'm trying to replace the day in my if statement for my date but I keep getting this output for my year.
05/15/5 besides 05/15/2020 . Code is below:
today_date = datetime.datetime.now()
date = today_date.date()
formatted_date = datetime.date.strftime(date, "%m/%d/%Y")
mmonth = date.month
myear = date.year
mdate = date.day
if mdate < 7:
m0weekend = formatted_date.replace(str(myear),str(mmonth),1)
else:
m0weekend = formatted_date.replace(str(myear),str(mmonth),15)
it's easier to replace the day before converting to a string:
date = date.replace(day=1)
or, in your case:
if mdate < 7:
m0weekend = date.replace(day=1)
else:
m0weekend = date.replace(day=15)
formatted_date is actually a string.
You are using the str.replace() method not the datetime.date.replace() method.
import datetime
today_date = datetime.datetime.now()
pre_formatted_date = today_date.date()
mmonth = pre_formatted_date.month
myear = pre_formatted_date.year
mdate = pre_formatted_date.day
if mdate < 7:
pre_formatted_date = pre_formatted_date.replace(day=1)
else:
pre_formatted_date = pre_formatted_date.replace(day=15)
print(pre_formatted_date)
formatted_date = pre_formatted_date.strftime("%m/%d/%Y")
print(formatted_date)
Which has the following output:
2020-05-15
05/15/2020
You might get today datetime.date directly from datetime rather than creating datetime.datetime and converting to date. After you have today you might create needed datetime.date and turn it into str, i.e.:
import datetime
today = datetime.date.today()
date = datetime.date(today.year, today.month, 1 if today.day < 7 else 15)
formatted_date = datetime.date.strftime(date, "%m/%d/%Y")
print(formatted_date) # 05/15/2020
def generate_leave(self, cr, uid,ids, fields, context=None):
if context is None:
context = {}
month_split = self.browse( cr, uid,ids)
print "\n\n\n\n\n\n DATEE",month_split.name
dt = datetime.strptime(month_split.name, "%Y-%m-%d")
# date= dt.strftime(month_split.name[],'%Y-%m-%d')
# print "\n\n\n\n\n DAT",date
year = dt.year
print "\n\n\n\n YER",year
month = dt.month
print "\n\n\n MNTH",month
currentMonth = datetime.now().month
print "\n\n\n\n\n CURR MNTH",currentMonth
date = dt.date
print "\n\n\n\n\n\n DATTE",date
date = datetime.now().day
print "\n\n\n\n\n\n DATEE",date
This is my code. I am able to get current date separately. But in my scenario user will input a date and I want to take only the "Date" from that input, I don't want month and year.
I need to implement a function in Python which is able to retrieve multiple date formats from input string, change them into one specific format and return the date only:
Format Example Input String
MMDDYYYY foo.bar.02242015.txt
MMDDYY foo.bar.022415.txt
MONCCYY foo.bar.FEB2015.txt
YYYY-MM-DD foo_bar_2015-02-01_2015-02-28.txt
YYYYMMDD foo_bar_20150224.txt
MM_YY foo_bar_02_15.txt
YYYYMMDD foo_bar_20150224.txt
Output: just a fixed 8 digits date format (no foo, bar or txt):
YYYYMMDD (e.g. 20120524)
Example:
Input Output
foo.bar.02242015.txt -> 20150224
Some requirements:
if date is missing, add the last day of the month:
foo_02_15.txt -> 20150228
if year is 2 digits, change it to 4:
foo_02_24_16.txt -> 20160224
valid year is current or previous year, for now: 2016 or 2015
if month is not number, e.g. FEB, change it to 2 digit number:
foo.FEB2015.txt -> 20150228
Format 'YYYY-MM-DD' always contains two dates, fetch the second one:
foo_2015-02-01_2015-02-28.txt -> 20150228
Anyone know how to do it with Regex in Python? Or what is the best practice to do it?
Try this:
import re
import time
import datetime
import calendar
p = re.compile(ur'(?<=\.|_)([A-Z\d+_-]*?([A-Z\d+_-]{0,10}))(?=\.)')
test_str = u"Format Example Input String \n\nMMDDYYYY foo.bar.02242015.txt\nMMDDYY foo.bar.022415.txt\nMONCCYY foo.bar.FEB2015.txt\nYYYY-MM-DD foo_bar_2015-02-01_2015-02-28.txt\nYYYYMMDD foo_bar_20150224.txt\nMM_YY foo_bar_02_15.txt\nYYYYMMDD foo_bar_20150224.txt"
def changedate(date):
try:
t = time.strptime(date,'%m%d%Y')
except:
pass
try:
t = time.strptime(date,'%m%d%y')
except:
pass
try:
t = time.strptime(date,'%b%Y')
lastday = calendar.monthrange(int(t.tm_year), int(t.tm_mon))[1]
t = time.strptime(date + str(lastday),'%b%Y%d')
except:
pass
try:
t = time.strptime(date,'%m_%y')
lastday = calendar.monthrange(int(t.tm_year), int(t.tm_mon))[1]
t = time.strptime(date + str(lastday),'%m_%y%d')
except:
pass
try:
t = time.strptime(date,'%Y-%m-%d')
except:
pass
try:
r = time.strftime("%Y%m%d",t)
return r
except:
pass
return date
test_str = re.sub(p,lambda m: changedate(m.group(2)), test_str)
print test_str
Regex Demo
Input
Format Example Input String
MMDDYYYY foo.bar.02242015.txt
MMDDYY foo.bar.022415.txt
MONCCYY foo.bar.FEB2015.txt
YYYY-MM-DD foo_bar_2015-02-01_2015-02-28.txt
YYYYMMDD foo_bar_20150224.txt
MM_YY foo_bar_02_15.txt
YYYYMMDD foo_bar_20150224.txt
Output:
Format Example Input String
MMDDYYYY foo.bar.20150224.txt
MMDDYY foo.bar.20150224.txt
MONCCYY foo.bar.20150228.txt
YYYY-MM-DD foo_bar_20150228.txt
YYYYMMDD foo_bar_20150224.txt
MM_YY foo_bar_20150228.txt
YYYYMMDD foo_bar_20150224.txt
Explanation:
E.g.
Input
foo_bar_2015-02-01_2015-02-28.txt
So
(?<=\.|_)([A-Z\d+_-]*?([A-Z\d+_-]{0,10}))(?=\.)
Regex to capture date string in to group m
1. [182-203] `2015-02-01_2015-02-28`
2. [193-203] `2015-02-28`
m.group(0) = 2015-02-01_2015-02-28
m.group(1) = 2015-02-01_2015-02-28
m.group(2) = 2015-02-28
Then
lambda m: changedate(m.group(2)) to re-format datetime
So
2015-02-28 can not pass others as
try:
t = time.strptime(date,'%m%d%Y')
except:
pass
But pass only this block
try:
r = time.strftime("%Y-%m-%d",t)
return r
except:
pass
Then format it
try:
r = time.strftime("%Y%m%d",t)
return r
except:
pass
UPDATE2 Please try the following approach (python 2.7):
import re
import calendar
INPUT = ['foo.bar.02242015.txt',
'foo.bar.022415.txt',
'foo.bar.FEB2015.txt',
'foo_bar_2015-02-01_2015-02-28.txt',
'foo_bar_20150224.txt',
'foo_bar_02_15.txt',
'foo_bar_20150224.txt' ]
P1 = r'(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])((?:19|20)?\d{2})'
P2 = r'[A-Z]{3}[12]\d{3}|[12]\d{3}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])_?|(?:0[1-9]|1[0-2])_[12]\d'
MONTHS = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']
def StrFormat(date_string):
m2 = re.findall(P2, date_string)
if m2:
for m in m2:
if len(m) == 5:
month, year = m.split('_')[0], '20' + m.split('_')[1]
last_day = calendar.monthrange(int(year), int(month))[1]
date_string = re.sub(P2, year+month+ str(last_day), date_string, 1)
elif len(m) == 7:
month, year = str(MONTHS.index(m[0:3]) + 1).zfill(2), m[3:]
last_day = calendar.monthrange(int(year), int(month))[1]
date_string = re.sub(P2, year+month+ str(last_day), date_string, 1)
elif len(m) == 10:
date_string = re.sub(P2, m.replace('-', ''), date_string, 1)
elif len(m) > 5:
date_string = re.sub(P2, '', date_string, 1)
m1 = re.findall(P1, date_string)
if m1:
for m in m1:
if len(m[2]) == 2:
date_string = re.sub(P1, r'20\3\1\2', date_string, 1)
elif len(m[2]) == 4:
date_string = re.sub(P1, r'\3\1\2', date_string, 1)
elif len(m) > 2:
date_string = re.sub(P1, '', date_string, 1)
return date_string
for i in INPUT:
print i.ljust(35), '->', StrFormat(i).rjust(20)
Output:
foo.bar.02242015.txt -> foo.bar.20150224.txt
foo.bar.022415.txt -> foo.bar.20150224.txt
foo.bar.FEB2015.txt -> foo.bar.20150228.txt
foo_bar_2015-02-01_2015-02-28.txt -> foo_bar_20150228.txt
foo_bar_20150224.txt -> foo_bar_20150224.txt
foo_bar_02_15.txt -> foo_bar_20150228.txt
foo_bar_20150224.txt -> foo_bar_20150224.txt
Btw: It is indeed 10% Regex + 90% programming as suggested by noob :-)
After solving a naive datetime problem I am facing a new problem on a view to generate graphs. Now I get mktime argument out of range.
I have no idea how to solve it. I didn't write the code, I am using it from a colleague of mine and I can't seem o understand why it fails. I think it has to do with a function that runs overtime and the error pops out.
#login_required(login_url='/accounts/login/')
def loggedin(request):
data = []
data2 = []
data3 = []
dicdata2 = {}
dicdata3 = {}
datainterior = []
today = timezone.localtime(timezone.now()+timedelta(hours=1)).date()
tomorrow = today + timedelta(1)
semana= today - timedelta(7)
today = today - timedelta(1)
semana_start = datetime.combine(today, time())
semana_start = timezone.make_aware(semana_start, timezone.utc)
today_start = datetime.combine(today, time())
today_start = timezone.make_aware(today_start, timezone.utc)
today_end = datetime.combine(tomorrow, time())
today_end = timezone.make_aware(today_end, timezone.utc)
for modulo in Repository.objects.values("des_especialidade").distinct():
dic = {}
mod = str(modulo['des_especialidade'])
dic["label"] = str(mod)
dic["value"] = Repository.objects.filter(des_especialidade__iexact=mod).count()
data.append(dic)
for modulo in Repository.objects.values("modulo").distinct():
dic = {}
mod = str(modulo['modulo'])
dic["label"] = str(mod)
dic["value"] = Repository.objects.filter(modulo__iexact=mod, dt_diag__gte=semana_start).count()
datainterior.append(dic)
# print mod, Repository.objects.filter(modulo__iexact=mod).count()
# data[mod] = Repository.objects.filter(modulo__iexact=mod).count()
dicdata2['values'] = datainterior
dicdata2['key'] = "Cumulative Return"
dicdata3['values'] = data
dicdata3['color'] = "#d67777"
dicdata3['key'] = "Diagnosticos Identificados"
data3.append(dicdata3)
data2.append(dicdata2)
#-------sunburst
databurst = []
dictburst = {}
dictburst['name'] = "CHP"
childrenmodulo = []
for modulo in Repository.objects.values("modulo").distinct():
childrenmodulodic = {}
mod = str(modulo['modulo'])
childrenmodulodic['name'] = mod
childrenesp = []
for especialidade in Repository.objects.filter(modulo__iexact=mod).values("des_especialidade").distinct():
childrenespdic = {}
esp = str(especialidade['des_especialidade'])
childrenespdic['name'] = esp
childrencode = []
for code in Repository.objects.filter(modulo__iexact=mod,des_especialidade__iexact=esp).values("cod_diagnosis").distinct():
childrencodedic = {}
codee= str(code['cod_diagnosis'])
childrencodedic['name'] = 'ICD9 - '+codee
childrencodedic['size'] = Repository.objects.filter(modulo__iexact=mod,des_especialidade__iexact=esp,cod_diagnosis__iexact=codee).count()
childrencode.append(childrencodedic)
childrenespdic['children'] = childrencode
#childrenespdic['size'] = Repository.objects.filter(des_especialidade__iexact=esp).count()
childrenesp.append(childrenespdic)
childrenmodulodic['children'] = childrenesp
childrenmodulo.append(childrenmodulodic)
dictburst['children'] = childrenmodulo
databurst.append(dictburst)
# print databurst
# --------stacked area chart
datastack = []
for modulo in Repository.objects.values("modulo").distinct():
datastackdic = {}
mod = str(modulo['modulo'])
datastackdic['key'] = mod
monthsarray = []
year = timezone.localtime(timezone.now()+timedelta(hours=1)).year
month = timezone.localtime(timezone.now()+timedelta(hours=1)).month
last = timezone.localtime(timezone.now()+timedelta(hours=1)) - relativedelta(years=1)
lastyear = int(last.year)
lastmonth = int(last.month)
#i = 1
while lastmonth <= int(month) or lastyear<int(year):
date = str(lastmonth) + '/' + str(lastyear)
if (lastmonth < 12):
datef = str(lastmonth + 1) + '/' + str(lastyear)
else:
lastmonth = 01
lastyear = int(lastyear)+1
datef = str(lastmonth)+'/'+ str(lastyear)
lastmonth = 0
datainicial = datetime.strptime(date, '%m/%Y')
datainicial = timezone.make_aware(datainicial, timezone.utc)
datafinal = datetime.strptime(datef, '%m/%Y')
datafinal = timezone.make_aware(datafinal, timezone.utc)
#print "lastmonth",lastmonth,"lastyear", lastyear
#print "datainicial:",datainicial,"datafinal: ",datafinal
filtro = Repository.objects.filter(modulo__iexact=mod)
count = filtro.filter(dt_diag__gte=datainicial, dt_diag__lt=datafinal).count()
conv = datetime.strptime(date, '%m/%Y')
ms = datetime_to_ms_str(conv)
monthsarray.append([ms, count])
#i += 1
lastmonth += 1
datastackdic['values'] = monthsarray
datastack.append(datastackdic)
#print datastack
if request.user.last_login is not None:
#print(request.user.last_login)
contador_novas = Repository.objects.filter(dt_diag__lte=today_end, dt_diag__gte=today_start).count()
return render_to_response('loggedin.html',
{'user': request.user.username, 'contador': contador_novas, 'data': data, 'data2': data2,
'data3': data3,
'databurst': databurst, 'datastack':datastack})
def datetime_to_ms_str(dt):
return str(1000 * mktime(dt.timetuple()))
I think the problem is with this condition.
while lastmonth <= int(month) or lastyear<int(year):
During December, month=12, so lastmonth <= int(month) will always be True. So the loop whill always return True, even once lastyear is more that the current year.
You want to loop if the loop is in the previous year, or if the loop is in the current year and the month is not in the future. Therefore, I think you want to change it to the following:
while lastyear < year or (lastyear == year and lastmonth <= month):
To be sure that the code is working and to understand it, you need to add lots of print statements to the loops, see how lastmonth and lastyear change, and check that the loop exits when you expect it to. You also need to test it for other values of year and month so that it doesn't break next month. Ideally you want to extract this bit of the code into a separate function. It would be easier to understand the loop if it only returned a list of (month, year) integers, instead of doing lots of date formatting at the same time. Then it would be easier to add unit tests.