Checking if dictionary contains the date and plan - python

So I am trying to create a function that checks whether or not the contents of a function is true:
def command_add(date, event, calendar):
'''
Add event_details to the list at calendar[date]
Create date if it was not there
:param date: A string as "YYYY-MM-DD"
:param event: A string describing the event
:param calendar: The calendars database
:return: a string indicating any errors, "" for no errors
'''
>>> calendar == {'2015-10-20': ['Python']}
True
>>> command_add("2015-11-01", "Computer Science class", calendar)
''
How would I write such a function? The problem I'm having is how to make the string or how to see if the string for the date is in the format 'YYYY-MM-DD'.

The following code uses strptime to parse the date, if the parsing fails it is not a proper date string. Then it checks if the date is already in the calendar dict or not to see whether to append or add the first entry.
from datetime import datetime
def command_add(date, event, calendar):
'''
Add event_details to the list at calendar[date]
Create date if it was not there
:param date: A string as "YYYY-MM-DD"
:param event: A string describing the event
:param calendar: The calendars database
:return: a string indicating any errors, "" for no errors
'''
try:
datetime.strptime('%Y-%m-%d', date):
except ValueError:
return 'Error parsing date'
else:
if date in calendar:
calendar[date].append(event)
else:
calendar[date] = [event]
return ''

Look at: https://docs.python.org/2/library/time.html#time.strptime
Give strptime the wanted format and if string is not formatted as you wanted you will get an exception

from datetime import datetime
def command_add(date, event, calendar):
# Your Code
calendar = {'2015-10-20': ['Python']}
try:
Date = "2015-11-01"
date_object = datetime.strptime(Date, '%Y-%m-%d')
command_add(Date, "Computer Science class", calendar)
except:
print "Date Format is not correct"

Related

How to query dates in MongoDB using $gte and $lte with flask-mongoengine?

When I try to return documents based on the date created, I get an empty list when I know for a fact that there are documents in the database that meet the criteria. I used postman to send the request which would be a string input from the user eg. "Tue Apr 28 2020". This string input would then be converted to a datetime object like so:
def get(self):
try:
body = request.get_json()
search_field = datetime.datetime.strptime(body, '%a %b %d %Y') #format string to datetime object
next_day = search_field
next_day += relativedelta(days=1) #Set the end of the range to the next day
search_field = search_field.replace(tzinfo=datetime.timezone.utc).isoformat()
next_day = next_day.replace(tzinfo=datetime.timezone.utc).isoformat()
print(search_field) #Verify the fields are correct : 2020-04-28T00:00:00+00:00
print(next_day) #2020-04-29T00:00:00+00:00
date_search = Reports.objects.filter(__raw__={'creation_timestamp' : {'$gte' : search_field, '$lte' : next_day}}).to_json() #This is where the documents should be filtered for return
print(date_search)
return Response(date_search, mimetype="application/json", status=200) #The document/s should be returned here as a JSON array.
except Exception as e:
print(e)
return make_response(jsonify(message='Something went wrong :('), 401)
Here is the partial database model:
class Reports(db.Document):
creation_timestamp = db.DateTimeField(default=datetime.utcnow, required=True)
When the document is created, it is stored in the database and the time is stored as isoformat(). The user can only input the search field in the format stated above with a date picker so I format the date to fit the format Mongodb would understand.
Using the above code, I get an empty list and the 200 status code. Checking the database shows I have documents that would fit the criteria, can anyone help figure out what is wrong? Thanks.
If you can have your search_field and nextday in datetime format then you can write the query. I also suggest using Q for pymongo queries in mongoengine.
Your query :
import Q from mongoengine
search_time=datetime.datetime(2017, 11, 8)
nextday=datetime.datetime(2017, 11, 9)
date_search=Report.objects(Q(creation_timestamp__gte=search_field) & Q(timestamp__lte=nextday)).to_json()

insert conditional for hours

Good evening, could you help me in how I can put a condition so that a message comes out saying that you can not take an hour because it is already busy ?, I currently have this:
class reserva (models.Model):
_name='gimnasio.reserva'
tipo_reserva=fields.Selection([('clase','Clase'),('evaluacion','Evaluacion')])
fecha_reserva=fields.Date()
start_time=fields.Float()
end_time=fields.Float()
def fecha(self):
if self.star_time==self.star_time:
raise validationError('the hour is busy')
I have another question for you. you know how to configure Datetime only for hour and minutes because I only need hour and minutes but not the date.
To configure Datetime only for hour and minutes.
time = fields.Datetime("time")
custom_time = fields.Char('my_custome_time')
#api.onchange('time')
def _get_time(self):
if self.time:
for rec in self:
# datetime value is a string like 'YYYY-mm-dd HH:MM:SS'
# so just extract string from position 11 to 16
_time = self.time[11:16]
self.custom_time = _time
rec.custom_time = self.custom_time
I think you can use strptime method from datetime module.
from datetime import datetime as dt
start_time = fields.Float()
end_time = fields.Float()
#api.onchange('start_time','end_time')
def _check(self):
records = self.env["gimnasio.reserva"].search([("day", '=', the day you want to check eg. "2019-06-13")])
for rec in records:
ref_start = dt.strptime(str(rec.start_time), "%H:%M")
curr_start = dt.strptime(str(self.start_time), "%H:%M")
if ref_start == curr_start:
raise validationError('the hour is busy')
I didn't debug yet, you can try it.
how to eliminate the default date that you added ("2019-06-13") and that any date should not have the same busy schedule?
In this case you don't need datetime module just
#api.constrains("start_time")
def _check(self):
# search db for any record have same start time.
records = self.env["gimnasio.reserva"].search([('start_time ','=', self.start_time)])
if len(records) > 0:
raise validationError('the hour is busy')

How to validate that a string is a valid date in Python

I have a model in Django that has two DateFields, but sometimes they receive wrong dates from the front-end, like '20196-10-23'. Even when it might actually be a valid date (crazy, but legit), python doesn't allow to compare both dates due to this error: TypeError: '>=' not supported between instances of 'datetime.date' and 'str', so I want to use clean() method to verify that both dates are valid ones, but I always get dates wrong, even when they are correct.
This is the code for clean() method:
def clean(self, *args, **kwargs):
try:
Reservation.objects.get(booking=self.booking)
except:
pass
else:
raise CustomValidation(_('Booking already exists.'), 'booking', status_code=status.HTTP_400_BAD_REQUEST)
print("{}/{}".format(self.arrival_date, self.departure_date))
try:
datetime.strptime(self.arrival_date, "%Y-%m-%d")
except:
raise CustomValidation(_('Arrival date must be a valid date.'), 'arrival_date', status_code=status.HTTP_400_BAD_REQUEST)
if self.arrival_date >= self.departure_date:
raise CustomValidation(_('Departure date must be later than Arrival date.'), 'departure_date', status_code=status.HTTP_400_BAD_REQUEST)
elif self.arrival_date <= timezone.datetime.now().date():
if self.id == None:
raise CustomValidation(_('Arrival date must be later than today.'), 'arrival_date', status_code=status.HTTP_400_BAD_REQUEST)
if self.status == 'CONFIRMED' and self.confirmation is None:
raise CustomValidation(_('Must provide a confirmation number.'), 'confirmation', status_code=status.HTTP_400_BAD_REQUEST)
I always get an exception, even when the date is correct.
While 20196 is conceptually a valid year, Python won't allow it. I tried this...
import datetime
from datetime import date
def clean(arrival_date):
return date(*map(int, arrival_date.split("-")))
print(clean("20196-10-23"))
# ValueError: year is out of range
...and found out there's actually a hard-coded maximum year value of 9999 for Python dates.
So while you could technically validate the format in various ways, you won't be able to handle dates like this with the built-in datetime module.
I usually first set both dates as datetime.strptime():
try:
#get the dates
my_date_time_1 = self.cleaned_data['date_1']
my_date_time_2 = self.cleaned_data['date_2']
#set the datetime
my_date_time_1 = datetime.strptime(my_date_time_1, '%Y-%m-%d %H:%M:%S')
my_date_time_2 = datetime.strptime(my_date_time_2, '%Y-%m-%d %H:%M:%S')
except:
raise forms.ValidationError(u'Wrong Date Format')
#and then compare dates
if my_date_time_1 >= my_date_time_2:
raise forms.ValidationError(u'Please check the dates')

How to convert date before 1970 in python

I wrote a method to handle mongodb result, where date is coming as datetime.datetime() i used dumps method, which converts the date is not milliseconds, here if the date is before 1970 then date is converted to negative value and i am unable to handle this to change back to date and time after wards.
My sample code is as below:
import datetime
from bson.json_util import dumps
from bson.objectid import ObjectId
import string
def get_json_key_value(mongoResult, key):
# converts mongoResult which is not into proper json format to proper json format
result = dumps(dict(eval(mongoResult)))
# convert unicode format to string format
data = __convert(dict(eval(result)))
# code to get the json value.
value="data"
jsonlist = key.split('.')
for eachKey in jsonlist:
if (eachKey.isdigit()):
value = value + "["+eachKey+ "]"
else:
value = value + "['"+eachKey + "']"
returnValue = eval(value)
#processing the date value, if key has $date
if((string.find(key,"$date"))>=0):
returnValue = datetime.datetime.fromtimestamp(returnValue/1000.0)
returnValue = datetime.datetime.strftime(returnValue , format="%Y-%m-%dT%H:%M:%S")
returnValue = datetime.datetime.strptime(str(returnValue), "%Y-%m-%dT%H:%M:%S")
returnValue = returnValue - datetime.timedelta(minutes=330)
returnValue = datetime.datetime.strftime(returnValue , format="%Y-%m-%dT%H:%M:%S")
return returnValue
sample input data can be as
MongoResult: {'profileDetails': {'basicDetails': {'dateOfBirth': {'$date': -414892800000L}, 'customerCode': 'C017145'}, 'xDirLevel': {'masterCode': 1}, 'createdDate': {'$date': 1467392480962L}}, '_id': {'$oid': '58872e98321a0c863329199d'}}
Key: profileDetails.basicDetails.dateOfBirth.$date
I am getting error ValueError: timestamp out of range for platform localtime()/gmtime() function if the date is before 1970, how to handle this
I got the solution for date convertion before 1970 as below:
need to replace the code in if((string.find(key,"$date"))>=0): block as
ndate = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=(returnValue)/1000)
returnValue = str(ndate).replace(' ','T')
I got the solution from the another question in stackoverflow Timestamp out of range for platform localtime()/gmtime() function

Guessing the date format python

I am writing a method in a Python module which tries to make live easier to the users. This method implements the creation of events in that calendar.
def update_event(start_datetime=None, end_datetime=None, description=None):
'''
Args:
start_date: string datetime in the format YYYY-MM-DD or in RFC 3339
end_date: string datetime in the format YYYY-MM-DD or in RFC 3339
description: string with description (\n are transforrmed into new lines)
'''
If the user specifies the start_date or the end_date a check up should be made in order to determine if the date is in YYYY-MM-DD format or in the datetime RFC 3339 format.
if (start_date is not None):
# Check whether we have an date or datetime value
# Whole day events are represented as YYYY-MM-DD
# Other events are represented as 2014-04-25T10:47:00.000-07:00
whole_day_event = False
try:
new_start_time = datetime.datetime.strptime(start_date,'YYYY-MM-DD')
# Here the event date is updated
try:
new_start_time = datetime.datetime.strptime(start_date,'%Y-%m-%dT%H:%M:%S%z')
#Here the event date is updated
except ValueError:
return (ErrorCodeWhatever)
except ValueError:
return (ErrorCodeWhatever)
Is this a good way of doing this? Can I check what kind of date I am receiving in a nicer way?
Thanks!
dateutil.parser.parse can be used to attempt to parse strings into datetime objects for you.
from dateutil.parser import parse
def update_event(start_datetime=None, end_datetime=None, description=None):
if start_datetime is not None:
new_start_time = parse(start_datetime)
return new_start_time
d = ['23/04/2014', '24-04-2013', '25th April 2014']
new = [update_event(i) for i in d]
for date in new:
print(date)
# 2014-04-23 00:00:00
# 2013-04-24 00:00:00
# 2014-04-25 00:00:00
Extending #Ffisegydd answer you can also specify your target datetime format that you want like this :-
from dateutil.parser import parse
def update_event(start_datetime=None, end_datetime=None, description=None):
if start_datetime is not None:
new_start_time = parse(start_datetime)
return new_start_time
d = ['06/07/2021 06:40:23.277000','06/07/2021 06:40','06/07/2021']
new = [update_event(i) for i in d]
for date in new:
print(date.strftime('%Y/%m/%d %H:%M:%S.%f'))

Categories