Know which parts a day contains - python

The dateparser library set missing parts of a date to today's values.
Example:
>>> import dateparser
>>> dateparser.parse("2015")
datetime.datetime(2015, 2, 14, 0, 0)
How to know which parts a date really contains?
(and thus which parts were set to today's values by the library)?
This is what I've come up with.
Is there a more efficient way?
date_str = input('Type a date: ')
settings = {"REQUIRE_PARTS": ["year"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Invalid Date")
return
settings = {"REQUIRE_PARTS": ["year", "month"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year only")
return
settings = {"REQUIRE_PARTS": ["year", "month", "day"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year and month")
return
print("Date has year, month and day")

Related

How to replace the day in a date with another date?

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

Strftime error Python

I'm calling a function to get the calculation for driver revenue but, I keep getting this error:
"line 396, in driver_get_revenue
monthly[month.strftime("%m")] = orders.count() * settings.DRIVER_DELIVERY_PRICE
AttributeError: 'int' object has no attribute 'strftime'"
The function is this:
def driver_get_revenue(request):
driver = JWTAuthentication().authenticate(request)[0].driver
#Returns the difference between date and time.
from datetime import timedelta
revenue = {}
monthly = {}
yearly = {}
today = timezone.now()
month = today.month
year = today.year
#Created a range to calculate the current weekday.
current_weekdays = [today + timedelta(days = i) for i in range(0 - today.weekday(), 7 - today.weekday())]
for day in current_weekdays:
orders = Order.objects.filter(
driver = driver,
status = Order.DELIVERED,
created_at__year = day.year,
created_at__month = day.month,
created_at__day = day.day
)
revenue[day.strftime("%A")] = orders.count() * settings.DRIVER_DELIVERY_PRICE
for day in range(0, 30):
orders = Order.objects.filter(
driver = driver,
status = Order.DELIVERED,
created_at__month = month,
created_at__day = day
)
(Line 396) monthly[month.strftime("%m")] = orders.count() * settings.DRIVER_DELIVERY_PRICE
for month in range(0, 12):
orders = Order.objects.filter(
driver = driver,
status = Order.DELIVERED,
created_at__year = year,
created_at__month = month
)
yearly[year.strftime("%y")] = orders.count() * settings.DRIVER_DELIVERY_PRICE
return JsonResponse({"revenue": revenue,
"month": monthly,
"yearly": yearly})
I'm not exactly sure where I went wrong. I marked line 396 so that you see where the error is. Any help will be greatly appreciated.
Thanks.
When you do this: month = today.month, month becomes an integer. The strftime function works with datetime objects, not with integers.
Therefore, month.strftime("%m") doesn't work.
Try day.strftime("%m") instead, or perhaps just month, depending on your requirements.
If instead you're looking for the month's name, you could do it like this:
today = timezone.now()
month = today.month
month_name = today.strftime("%B") # e.g. December
...
...and use the month_name variable in your code.

How to get only date from "Date" field in python

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.

Match and change multiple date formats into one with Python Regex

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 :-)

change (eg) 8 to 08...python

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.

Categories