Skip to content

Instantly share code, notes, and snippets.

@jourdanrodrigues
Created June 8, 2017 22:28
Show Gist options
  • Save jourdanrodrigues/94feb437701b5eaad0a9f44ed5304b3a to your computer and use it in GitHub Desktop.
Save jourdanrodrigues/94feb437701b5eaad0a9f44ed5304b3a to your computer and use it in GitHub Desktop.
Python parser: date string -> date object.
import datetime
from re import match
date_separator = r'(/|-|.)'
time_separator = r'(:|-|.)'
date_formats = '"D/M/YYYY" | "D-M-YYYY" | "D.M.YYYY"'
datetime_formats = '"D/M/YYYY H:M:S" | "D-M-YYYY H-M-S" | "D.M.YYYY H.M.S"'
def datetime_input(regex_verbose=date_formats, input_time=True, timezone=False, initial=True, date=None, required=True,
message='Specify a date', regex=r'(?P<day>[0-9]+)' + date_separator +
r'(?P<month>[0-9]+)' + date_separator +
r'(?P<year>[0-9]{4})'):
"""
:param date: String date to return date object (optional)
:param required: Ends only with a valid date (ignored if "date" is sent) (defaults to True)
:param message: Message to be shown as message for input (ignored if "date" is sent)
:param regex: Regex to match the string date
:param regex_verbose: Date format to be shown to the user
:param initial: Specifies the beginning or the end of the specified date (ignored if time is sent with the date)
:param timezone: Specifies if timezone will be included in the "datetime" object
:param input_time: Defines if the time will be sent
:return: "DateTime" object ("False" if no input is provided and not required)
"""
if input_time:
regex += (r'\s((?P<hour>[0-9]+)' + time_separator +
r'(?P<minute>[0-9]+)' + time_separator +
r'(?P<second>[0-9]+))?')
regex_verbose = datetime_formats
if date:
date = match(regex, date)
if not date:
raise ValidationError('Sent an invalid date format. Format: ' + regex_verbose)
else:
executed_once = date = False
input_message = '{message} {required}({regex_verbose}): '.format(
message=message,
required='' if required else '(leave empty to continue)',
regex_verbose=regex_verbose
)
while not date:
if executed_once:
print('Provide a valid value.')
date = raw_input(input_message)
# User must leave empty if doesn't want to specify it
if not date and not required:
return False
date = match(regex, date)
executed_once = True
date = date.groupdict()
# The values are string (parse them to integer)
for key, value in date.items():
if value is None:
del date[key]
else:
date[key] = int(value)
if timezone:
from django.utils import timezone
date_object = timezone.now().replace(**date)
else:
date_object = datetime.datetime(**date)
if not ('hour' in date and 'minute' in date and 'second' in date):
# Set the time
time = date_object.time().min if initial else date_object.time().max
date_object = datetime.datetime.combine(date_object, time)
return date_object
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment