Guessing the date format python - 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'))

Related

How filter by date and convert datetime

I am sending some dates from the front made in vue. I am receiving these dates in my viewSet in django, I want to filter data from these received dates.
I have two questions:
How do I convert dates into Python Datetime?
How do I filter the dates equal or greater or equal or less. => <=
In other words: bring records whose date is equal to or greater than another date.
date format in the front: 2021-08-03 10:12:14
date format in the back:
# print(type(fechas['desde']))
fecha <class 'str'>
# print(fechas['desde'])
fecha 2021-08-03 10:12:14
VIEWSET:
class TecnicosViewSet(
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.RetrieveModelMixin,
mixins.ListModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
queryset = Tecnico.objects.all()
serializer_class = Tecnicoserializer
def list(self, request):
dataQ = request.GET
newQ = json.dumps(dict(dataQ))
newQ1= json.loads(newQ)
tecnicos = ''
fechas= json.loads(newQ1['fechas'][0])
for item in newQ1['tecnicos']:
itemN = json.loads(item)
tecnicos = itemN['tecnicos']
print('fechas', fechas['desde'], fechas['hasta'])
# fecha = datetime.strptime(fechas['desde'], '%Y-%m-%d %H:%M')
print('fecha', type(fechas['desde']))
print('fecha', fechas['desde'])
for id in tecnicos:
ordenes = Servicio_realizados_orden_trabajo.objects.filter(date_range = [fechas['desde'], fechas['hasta']]).filter(state = 1).filter(tecnico = id)
ordenS = ServicioRealizadosserializer(ordenes, many=True)
return Response({'OK'})
As I fixed before: I want to convert that date into understandable python format and then use that transformed date to filter data by that date.
The for loop seen in the viewsewt is where I am trying to do the query.
I think you are pretty close based off your code...
You basically use strptime to convert a string to date in a desired format and then once you have created python datetime objects you can compare them.
Here's an example:
from datetime import datetime
date = datetime.strptime("2021-08-03 10:12:14", "%Y-%m-%d %H:%M:%S")
if date >= datetime.strptime("2021", "%Y"):
print('After or in 2021')
if date >= datetime.strptime("2021-09", "%Y-%m"):
print('After or in September 2021')

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

Checking if dictionary contains the date and plan

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"

Timezone conversion shows an offset of an hour more in OpenShift

I've implemented a REST webservice using flask. It stores and provides events information.
While storing information, I do the following steps:
Take the date, time and timezone.
Localize into the provided timezone
Then convert it into utc timezone
Finally get the utc timestamp and store it in the db.
def __get_timestamp(_datetime):
"""Returns the timestamp from datetime
"""
return time.mktime(_datetime.timetuple())
def __strptime(formatted_dt, tzinfo):
"""Returns the utc timestamp after conversion from entered timezone to utc
"""
tzinfo_dt = tzinfo.localize(datetime.datetime(formatted_dt['year'], formatted_dt['month'], formatted_dt['day'], formatted_dt['hour'], formatted_dt['minute']), is_dst=True)
utc = get_tzinfo()
utc_tz = utc.normalize(tzinfo_dt.astimezone(utc))
return __get_timestamp(utc_tz)
def get_tzinfo(user_timezone="UTC"):
"""Return pytz timezone
"""
return pytz.timezone(user_timezone)
While retrieving information
Retrieve the utc timestamp
Localize it into the utc
Convert it into the required timezone
Return with the required format
def get_tzinfo(user_timezone="UTC"):
"""Return pytz timezone
"""
return pytz.timezone(user_timezone)
def __strftime(ts, tzinfo, format='%Y-%m-%d %I:%M %p'):
"""Return the formatted datetime after converting utc timestamp to required timezone
"""
utc = get_tzinfo()
utc_dt = utc.localize(datetime.datetime.fromtimestamp(ts), is_dst=True)
tzinfo_dt = tzinfo.normalize(utc_dt.astimezone(tzinfo))
formatted_dt = tzinfo_dt.strftime(format)
return formatted_dt
The sequence goes like this
Entered datetime = 2014-03-21 14:00
TimeZone = "Asia/Kathmandu" --> (GMT+05:45) Kathmandu
Resulting timestamp = 1395407700
Final Formatted Output = "2014-03-21 03:00 PM"
The problem seems to be with daylight saving because the same code gives the correct result when tested locally.
Currently the webservice is being run on Openshift
whose server has "EDT" timezone,
while my local settings has "NPT".
How can this be resolved?

converting from local to utc timezone

I'm attempting to craft a function that takes a time object and converts it to UTC time. The code below appears to be off by one hour. When i run noon through the converter, i get back 18:00:00. But when i run the same data through online converters, i get 17:00:00.
What am i doing wrong here? Any help would be greatly appreciated.
import pytz, datetime
def convert_to_utc(time, tz):
now_dt = datetime.datetime.utcnow()
#get a date object
date_dt = now_dt.date()
#combine the current date object with our given time object
dt = datetime.datetime.combine(date_dt, time)
#get an timezone object for the source timezone
src_tz = pytz.timezone(str(tz))
#stamp the source datetime object with the src timezone
src_dt = dt.replace(tzinfo=src_tz)
#get the offset from utc to given timezone
offset = str(int(src_dt.strftime("%z"))).rstrip('0')
#convert the source datetime object to
utc_dt = src_dt.astimezone(pytz.utc)
#return the converted time and the offset in integer format
return (utc_dt.time(), int(offset))
time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")
**EDIT**
Here's the updated(and functional) code in case anyone else needs help converting to/from UTC.
Thanks everyone for your help!
import pytz, datetime
def convert_to_utc(time, tz): #this returns the offset in int form as well
now_dt = datetime.datetime.utcnow()
#get a date object
date_dt = now_dt.date()
#combine the current date object with our given time object
dt = datetime.datetime.combine(date_dt, time)
#get an timezone object for the source timezone
src_tz = pytz.timezone(str(tz))
#stamp the source datetime object with the src timezone
src_dt = src_tz.localize(dt)
#get the offset from utc to given timezone
offset = str(int(src_dt.strftime("%z"))).rstrip('0')
#convert the source datetime object to
utc_dt = src_dt.astimezone(pytz.utc)
#return the converted time and the offset in integer format
return (utc_dt.time(), int(offset))
def convert_from_utc(time, tz):
now_dt = datetime.datetime.now()
date = now_dt.date()
dt = datetime.datetime.combine(date, time)
dest = pytz.timezone(str(tz))
dt = dt.replace(tzinfo=pytz.utc)
dest_dt = dt.astimezone(dest)
return dest_dt.time()
time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")
utc_time = datetime.datetime.strptime('17:00:00', "%H:%M:%S").time()
TIME = convert_from_utc(utc_time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")
Change
src_dt = dt.replace(tzinfo=src_tz)
to
src_dt = src_tz.localize(dt)
Using localize adjusts for Daylight Savings Time, while replace does not.
See the section entitled "Localized times and date arithmetic" in the docs.
To convert time in given timezone to UTC time:
from datetime import datetime
import pytz
def convert_to_utc(time, tzname, date=None, is_dst=None):
tz = pytz.timezone(tzname)
if date is None: # use date from current local time in tz
date = datetime.now(tz).date()
dt = tz.localize(datetime.combine(date, time), is_dst=is_dst)
return dt.astimezone(pytz.utc).time(), dt.utcoffset().total_seconds()
if is_dst is None it raises an exception for ambiguous local times.
To convert UTC time to local time in given timezone:
def convert_from_utc(time, tzname, date=None):
tz = pytz.timezone(tzname)
if date is None: # use date from current time in utc
date = datetime.utcnow().date()
dt = datetime.combine(date, time).replace(tzinfo=pytz.utc)
return tz.normalize(dt.astimezone(tz)).time()
Example:
time = datetime.strptime('12:00:00', "%H:%M:%S").time()
utc_time, offset = convert_to_utc(time, 'America/Chicago')
print utc_time.strftime("%H:%M:%S"), offset # -> 17:00:00 -18000.0
utc_time = datetime.strptime('17:00:00', "%H:%M:%S").time()
time = convert_from_utc(utc_time, 'America/Chicago')
print time.strftime("%H:%M:%S") # -> 12:00:00
In general it is preferable to work with full datetime objects to avoid ambiguity with what is the correct date i.e., pass and return datetime objects.
By using the replace method on the datetime, you're not allowing the time zone to be adjusted for daylight savings time. Try using one of the documented methods from the pytz documentation:
src_dt = src_tz.localize(dt)

Categories