Instead of using regex, it is generally better to parse the string as a datetime.datetime
object:
In [140]: datetime.datetime.strptime("11/12/98","%m/%d/%y")
Out[140]: datetime.datetime(1998, 11, 12, 0, 0)
In [141]: datetime.datetime.strptime("11/12/98","%d/%m/%y")
Out[141]: datetime.datetime(1998, 12, 11, 0, 0)
You could then access the day, month, and year (and hour, minutes, and seconds) as attributes of the datetime.datetime
object:
In [143]: date.year
Out[143]: 1998
In [144]: date.month
Out[144]: 11
In [145]: date.day
Out[145]: 12
To test if a sequence of digits separated by forward-slashes represents a valid date, you could use a try..except
block. Invalid dates will raise a ValueError
:
In [159]: try:
.....: datetime.datetime.strptime("99/99/99","%m/%d/%y")
.....: except ValueError as err:
.....: print(err)
.....:
.....:
time data '99/99/99' does not match format '%m/%d/%y'
If you need to search a longer string for a date,
you could use regex to search for digits separated by forward-slashes:
In [146]: import re
In [152]: match = re.search(r'(d+/d+/d+)','The date is 11/12/98')
In [153]: match.group(1)
Out[153]: '11/12/98'
Of course, invalid dates will also match:
In [154]: match = re.search(r'(d+/d+/d+)','The date is 99/99/99')
In [155]: match.group(1)
Out[155]: '99/99/99'
To check that match.group(1)
returns a valid date string, you could then parsing it using datetime.datetime.strptime
as shown above.
You can run a date parser on all subtexts of your text and pick the first date. Of course, such solution would either catch things that are not dates or would not catch things that are, or most likely both.
Let me provide an example that uses dateutil.parser
to catch anything that looks like a date:
import dateutil.parser
from itertools import chain
import re
# Add more strings that confuse the parser in the list
UNINTERESTING = set(chain(dateutil.parser.parserinfo.JUMP,
dateutil.parser.parserinfo.PERTAIN,
['a']))
def _get_date(tokens):
for end in xrange(len(tokens), 0, -1):
region = tokens[:end]
if all(token.isspace() or token in UNINTERESTING
for token in region):
continue
text = ''.join(region)
try:
date = dateutil.parser.parse(text)
return end, date
except ValueError:
pass
def find_dates(text, max_tokens=50, allow_overlapping=False):
tokens = filter(None, re.split(r'(S+|W+)', text))
skip_dates_ending_before = 0
for start in xrange(len(tokens)):
region = tokens[start:start + max_tokens]
result = _get_date(region)
if result is not None:
end, date = result
if allow_overlapping or end > skip_dates_ending_before:
skip_dates_ending_before = end
yield date
test = """Adelaide was born in Finchley, North London on 12 May 1999. She was a
child during the Daleks' abduction and invasion of Earth in 2009.
On 1st July 2058, Bowie Base One became the first Human colony on Mars. It
was commanded by Captain Adelaide Brooke, and initially seemed to prove that
it was possible for Humans to live long term on Mars."""
print "With no overlapping:"
for date in find_dates(test, allow_overlapping=False):
print date
print "With overlapping:"
for date in find_dates(test, allow_overlapping=True):
print date
The result from the code is, quite unsurprisingly, rubbish whether you allow overlapping or not. If overlapping is allowed, you get a lot of dates that are nowhere to be seen, and if if it is not allowed, you miss the important date in the text.
With no overlapping:
1999-05-12 00:00:00
2009-07-01 20:58:00
With overlapping:
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-12 00:00:00
1999-05-03 00:00:00
1999-05-03 00:00:00
1999-07-03 00:00:00
1999-07-03 00:00:00
2009-07-01 20:58:00
2009-07-01 20:58:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-01 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00
2058-07-03 00:00:00
Essentially, if overlapping is allowed:
- “12 May 1999” is parsed to 1999-05-12 00:00:00
- “May 1999” is parsed to 1999-05-03 00:00:00 (because today is the 3rd day of the month)
If, however, overlapping is not allowed, “2009. On 1st July 2058” is parsed as 2009-07-01 20:58:00 and no attempt is made to parse the date after the period.
You are here: Home / Python / Check if String is Date in Python
To check if a string is a date, you can use the Python strptime() function from the datetime module. strptime() takes a string and a date format.
from datetime import datetime
string = "06/02/2022"
format_ddmmyyyy = "%d/%m/%Y"
format_yyyymmdd = "%Y-%m-%d"
try:
date = datetime.strptime(string, format_ddmmyyyy)
print("The string is a date with format " + format_ddmmyyyy)
except ValueError:
print("The string is not a date with format " + format_ddmmyyyy)
try:
date = datetime.strptime(string, format_yyyymmdd)
print("The string is a date with format " + format_yyyymmdd)
except ValueError:
print("The string is not a date with format " + format_yyyymmdd)
#Output:
The string is a date with format %d/%m/%Y
The string is not a date with format %Y-%m-%
When working with strings in Python, the ability to check if a string is a date can be very useful.
You can check if a string is a date using the Python strptime() function from the datetime module.
strptime() takes a string and a date format, and tries to create a datetime object. If the string matches the given string format, then the datetime object is created. If not, a ValueError occurs.
You can use a try-except block to try to create a datetime object with strptime() and if it succeeds, then you know the string is a date.
Below is a simple example showing you how to check if a string is a date in your Python code.
from datetime import datetime
string = "06/02/2022"
format_ddmmyyyy = "%d/%m/%Y"
format_yyyymmdd = "%Y-%m-%d"
try:
date = datetime.strptime(string, format_ddmmyyyy)
print("The string is a date with format " + format_ddmmyyyy)
except ValueError:
print("The string is not a date with format " + format_ddmmyyyy)
try:
date = datetime.strptime(string, format_yyyymmdd)
print("The string is a date with format " + format_yyyymmdd)
except ValueError:
print("The string is not a date with format " + format_yyyymmdd)
#Output:
The string is a date with format %d/%m/%Y
The string is not a date with format %Y-%m-%
How to Check if String has Specific Date Format in Python
If you want to check if a string is a date, you need to pass strptime() the correct date format.
There are a number of format codes which allow you to create different date and time formats.
You can check if a string is a specific date format by building a date format with the format codes linked above and then use strptime().
For example, if you want to check that a string is a date with format YYYYMMDD, you can use the format “%Y-%m-%d”.
string = "2022-06-02"
format_YYYYMMDD = "%Y-%m-%d"
try:
date = datetime.strptime(string, format_YYYYMMDD)
print("The string is a date with format " + format_YYYYMMDD)
except ValueError:
print("The string is not a date with format " + format_YYYYMMDD)
#Output:
The string is a date with format %Y-%m-%d
Hopefully this article has been useful for you to learn how to use strptime() to check if a string is a date in Python.
Other Articles You’ll Also Like:
- 1. Convert List to Set with Python
- 2. Python cube root – Find Cube Root of Number With math.pow() Function
- 3. PROC PHREG Equivalent in Python
- 4. Drop Duplicates pandas – Remove Duplicate Rows in DataFrame
- 5. How to Check if Set is Empty in Python
- 6. How to Check if Variable Exists in Python
- 7. Write Integer to File Using Python
- 8. pandas groupby size – Get Number of Elements after Grouping DataFrame
- 9. Using Lambda Expression with min() in Python
- 10. Check if Variable is None in Python
About The Programming Expert
The Programming Expert is a compilation of a programmer’s findings in the world of software development, website creation, and automation of processes.
Programming allows us to create amazing applications which make our work more efficient, repeatable and accurate.
At the end of the day, we want to be able to just push a button and let the code do it’s magic.
You can read more about us on our about page.
Reader Interactions
Given a date format and a string date, the task is to write a python program to check if the date is valid and matches the format.
Examples:
Input : test_str = ’04-01-1997′, format = “%d-%m-%Y”
Output : True
Explanation : Formats match with date.
Input : test_str = ’04-14-1997′, format = “%d-%m-%Y”
Output : False
Explanation : Month cannot be 14.
Method #1 : Using strptime()
In this, the function, strptime usually used for conversion of string date to datetime object, is used as when it doesn’t match the format or date, raises the ValueError, and hence can be used to compute for validity.
Python3
from
datetime
import
datetime
test_str
=
'04-01-1997'
print
(
"The original string is : "
+
str
(test_str))
format
=
"%d-%m-%Y"
res
=
True
try
:
res
=
bool
(datetime.strptime(test_str,
format
))
except
ValueError:
res
=
False
print
(
"Does date match format? : "
+
str
(res))
Output:
The original string is : 04-01-1997 Does date match format? : True
Method #2 : Using dateutil.parser.parse()
In this, we check for validated format using different inbuilt function, dateutil.parser. This doesn’t need the format to detect for a date.
Python3
from
dateutil
import
parser
test_str
=
'04-01-1997'
print
(
"The original string is : "
+
str
(test_str))
format
=
"%d-%m-%Y"
res
=
True
try
:
res
=
bool
(parser.parse(test_str))
except
ValueError:
res
=
False
print
(
"Does date match format? : "
+
str
(res))
Output:
The original string is : 04-01-1997 Does date match format? : True
Method#3: Using regular expression
Approach
validate a string date format is by using regular expressions. We can define a regular expression pattern that matches the expected format, and then use the re module to check if the string matches the pattern.
Algorithm
1. Import the re module
2. Define the input test string and the regular expression pattern string
3. Use the re.match() method to match the pattern against the test string
4. If the pattern matches the test string:
a. Print “True”
5. Otherwise:
a. Print “False”
Python3
import
re
test_str
=
'04-01-1997'
pattern_str
=
r
'^d{2}-d{2}-d{4}$'
if
re.match(pattern_str, test_str):
print
(
"True"
)
else
:
print
(
"False"
)
Time complexity of this approach is O(n), where n is the length of the input string.
Auxiliary Space is also O(n), since we need to store the regular expression pattern in memory.
Last Updated :
14 Mar, 2023
Like Article
Save Article
0 / 0 / 0 Регистрация: 14.10.2017 Сообщений: 14 |
|
1 |
|
Выбрать из текста (из списка) все даты25.03.2018, 21:19. Показов 4421. Ответов 19
выбрать из текста (из списка) все даты
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
25.03.2018, 21:19 |
19 |
Рыжий Лис Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
||||
26.03.2018, 05:48 |
2 |
|||
1 |
0 / 0 / 0 Регистрация: 14.10.2017 Сообщений: 14 |
|
26.03.2018, 11:10 [ТС] |
3 |
Рыжий Лис, а если вот такая дата 7 ноября 1917?
0 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 12:28 |
4 |
«позавчера» тоже можно считать датой. как и «500 A.D.»
0 |
Рыжий Лис Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
||||
26.03.2018, 12:41 |
5 |
|||
1 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 12:47 |
6 |
99 января 0000 Добавлено через 3 минуты
0 |
0 / 0 / 0 Регистрация: 14.10.2017 Сообщений: 14 |
|
26.03.2018, 12:57 [ТС] |
7 |
blz, а как учесть окончание месяца? re.findall(r’dsянварь|февраль|март|апрель|май|и юнь|июль|август|сентябрь|октябрь|ноябрь|декабрьs d{4}’,str)
0 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 13:09 |
8 |
koly121121: Добавлено через 1 минуту
1 |
Рыжий Лис Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
||||
26.03.2018, 13:18 |
9 |
|||
d Это одна цифра. Чтобы выбиралось от одной до двух: Добавлено через 2 минуты
1 |
0 / 0 / 0 Регистрация: 14.10.2017 Сообщений: 14 |
|
26.03.2018, 13:30 [ТС] |
10 |
blz, если проверять сразу несколько условий, то так можно написать m[i].append(re.findall(r'(d{1,2})s+(января|февраля|м арта|апреля|мая|июня|июля|августа|сентября|октября |ноября|декабря)s+(d{4})’,str)or(re.findall(r’d d.dd.d{4}’, str)”)) ?
0 |
blz 151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
||||
26.03.2018, 13:44 |
11 |
|||
Добавлено через 3 минуты
0 |
0 / 0 / 0 Регистрация: 14.10.2017 Сообщений: 14 |
|
26.03.2018, 13:49 [ТС] |
12 |
blz, как использовать несколько регулярных выражений?
0 |
blz 151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
||||
26.03.2018, 14:05 |
13 |
|||
(expr1|expr2|…exprN)
в данном примере мы ищем слова из 3х букв или 4х цифр
1 |
Рыжий Лис Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
||||
26.03.2018, 14:47 |
14 |
|||
Добавлено через 6 минут
1 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 14:50 |
15 |
в регулярках-то и без ошибок? 🙂
0 |
Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
|
26.03.2018, 14:52 |
16 |
Да, ещё и точки заэкранировать, а то будет строку “1201201994” принимать за дату.
0 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 14:54 |
17 |
а вообще, конечно, на практике может быть эффективнее не итерировать по регуляркам, а делать одну: Добавлено через 1 минуту
0 |
Рыжий Лис Просто Лис 4944 / 3252 / 1008 Регистрация: 17.05.2012 Сообщений: 9,522 Записей в блоге: 9 |
||||
26.03.2018, 15:00 |
18 |
|||
Если у вас есть проблема, и вы собираетесь решать ее с использованием регулярных выражений, то у вас есть две проблемы.
0 |
151 / 102 / 33 Регистрация: 11.08.2016 Сообщений: 574 |
|
26.03.2018, 15:04 |
19 |
есть две проблемы для ТС: перед тем, как втыкать регулярку в код, regexbuddy в помощь.
0 |
Garry Galler 5407 / 3831 / 1214 Регистрация: 28.10.2013 Сообщений: 9,554 Записей в блоге: 1 |
||||
26.03.2018, 20:11 |
20 |
|||
Не по теме сабжа (к тому ж ТС не обозначил понятие что есть дата в его (кон)тексте). После выделения токенов дат (регулярками или, к примеру, нейронной сетью) может возникнуть задача преобразования полученных сущностей в объекты python. Есть такой превосходный модуль как dateparser, который умеет преобразовывать множество токенов типа “дата” (самого широкого диапазона) в объект datetime. Поддерживает кучу языков (человеческих).
Код сегодня 2018-03-26 20:00:15.350677 завтра 2018-03-27 20:00:15.354677 вчера 2018-03-25 20:00:15.356677 послезавтра 2018-03-28 20:00:15.359677 позавчера 2018-03-24 20:00:15.361677 1 час назад 2018-03-26 19:00:15.364677 2 часа назад 2018-03-26 18:00:15.366678 через 3 часа 2018-03-26 23:00:15.369678 20 минут назад 2018-03-26 19:40:15.372678 сейчас 2018-03-26 20:00:15.375678 через 3 секунды 2018-03-26 20:00:18.377678 13 января 2018 г. в 13:34 2018-01-13 13:34:00 13 января 2018-01-13 00:00:00 январь 2017 2017-01-26 00:00:00 январь 2018-01-26 00:00:00 1 день назад 2018-03-25 20:00:15.400680 02-03-2018 2018-03-02 00:00:00 02/03/2018 2018-03-02 00:00:00
0 |