Created
June 8, 2017 22:28
-
-
Save jourdanrodrigues/94feb437701b5eaad0a9f44ed5304b3a to your computer and use it in GitHub Desktop.
Python parser: date string -> date object.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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