Как найти дату в строке python

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:

  1. “12 May 1999” is parsed to 1999-05-12 00:00:00
  2. “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

Рыжий Лис

Просто Лис

Эксперт Python

4944 / 3252 / 1008

Регистрация: 17.05.2012

Сообщений: 9,522

Записей в блоге: 9

26.03.2018, 05:48

2

Python
1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
import re
 
t = '''
Встреча состоится 13.03.2037 или может быть
19.05.2017. Или нет.
'''
 
print(re.findall(r'd{2}.d{2}.d{4}', t))



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.»
пишете регулярки для каждого поддерживаемого в вашем контексте формата даты, потом re_expr.find*()



0



Рыжий Лис

Просто Лис

Эксперт Python

4944 / 3252 / 1008

Регистрация: 17.05.2012

Сообщений: 9,522

Записей в блоге: 9

26.03.2018, 12:41

5

Python
1
2
3
4
5
6
7
8
#!/usr/bin/env python3
import re
 
t = '''
Встреча состоится 7 ноября 1917 или может быть
'''
 
print(re.findall(r'(d{1,2})s+(января|февраля|ноября)s+(d{4})', t))



1



151 / 102 / 33

Регистрация: 11.08.2016

Сообщений: 574

26.03.2018, 12:47

6

99 января 0000

Добавлено через 3 минуты
Навряд ли имеются в виду все форматы, упомянутые в ISO или просто имеющие распространение. Поэтому ТС надо сначала определиться с тем, что такое дата в данном контексте.



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:
если Вы намекаете на то, что датой считается и 01 Январь 1970 и 31 января 2018, то
январ(?:ь|я) итд… ах да, август(?:|а)
(?:…) – это non-capturing group.

Добавлено через 1 минуту
re.I не забывайте добавлять, чтобы матчинг был нечувствительным к регистру



1



Рыжий Лис

Просто Лис

Эксперт Python

4944 / 3252 / 1008

Регистрация: 17.05.2012

Сообщений: 9,522

Записей в блоге: 9

26.03.2018, 13:18

9

Цитата
Сообщение от koly121121
Посмотреть сообщение

d

Это одна цифра. Чтобы выбиралось от одной до двух: d{1,2}

Добавлено через 2 минуты
Для августа можно так:

Python
1
print(re.findall(r'август(?:а)?', t))



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

Python
1
2
3
4
5
6
7
In [20]: a = 'они встречались с 01 января 1970 года по 31 февраля 1990 года, дата смерти: 14 ноябрь 2000'
In [21]: re_date = re.compile(r'(d{1,2})s+(?:январ(?:ь|я)|феврал(?:ь|я)|ноябр(?:ь|я))s+(d{4})', re.I)
In [22]: list(re_date.finditer(a))
Out[22]: 
[<_sre.SRE_Match object; span=(18, 32), match='01 января 1970'>,
 <_sre.SRE_Match object; span=(41, 56), match='31 февраля 1990'>,
 <_sre.SRE_Match object; span=(76, 90), match='14 ноябрь 2000'>]

Добавлено через 3 минуты
re.findall() or re.findall() – здесь это не нужно, да и вообще так не делают



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)

Python
1
2
3
4
5
6
7
8
In [31]: re_x = re.compile(r'b(d{4}|w{3})b')
In [32]: a= 'sdf 2344 swedfasdf 22 1999 555555 ttt ssssss'
In [33]: list(re_x.finditer(a))
Out[33]: 
[<_sre.SRE_Match object; span=(0, 3), match='sdf'>,
 <_sre.SRE_Match object; span=(4, 8), match='2344'>,
 <_sre.SRE_Match object; span=(22, 26), match='1999'>,
 <_sre.SRE_Match object; span=(34, 37), match='ttt'>]

в данном примере мы ищем слова из 3х букв или 4х цифр



1



Рыжий Лис

Просто Лис

Эксперт Python

4944 / 3252 / 1008

Регистрация: 17.05.2012

Сообщений: 9,522

Записей в блоге: 9

26.03.2018, 14:47

14

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python3
import re
 
t = '''
они встречались с 01 января 1970 года по 31 февраля 1990 года,
дата смерти: 14 ноябрь 2000
Встреча состоится 13.03.2037 или может быть
19.05.2017. Или нет.
'''
 
re_dates = [
    re.compile(r'(d{1,2})s+((?:январ(?:ь|я)|феврал(?:ь|я)|ноябр(?:ь|я)))s+(d{4})', re.I),
    re.compile(r'(d{2}).(d{2}).(d{4})'),
]
 
ls = []
for r in re_dates:
    ls.extend(r.findall(t))
print(ls)

Добавлено через 6 минут
В первой регулярке что-то намудрили. (d{1,2})s+(январ(?:ь|я)|феврал(?:ь|я)|ноябр(?:ь|я))s+(d{4})



1



151 / 102 / 33

Регистрация: 11.08.2016

Сообщений: 574

26.03.2018, 14:50

15

в регулярках-то и без ошибок? 🙂
– d{2}).(d{2}).(d{4})
+ d{2}).(d{2}).(d{4})



0



Просто Лис

Эксперт Python

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

а вообще, конечно, на практике может быть эффективнее не итерировать по регуляркам, а делать одну:
(<re_for_datefmt1>|<re_for_datefmt2>|…)

Добавлено через 1 минуту
хороший пример из жизни про парсинг дат разных форматов на питоне – fail2ban.



0



Рыжий Лис

Просто Лис

Эксперт Python

4944 / 3252 / 1008

Регистрация: 17.05.2012

Сообщений: 9,522

Записей в блоге: 9

26.03.2018, 15:00

18

Если у вас есть проблема, и вы собираетесь решать ее с использованием регулярных выражений, то у вас есть две проблемы.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python3
import re
 
t = '''
они встречались с 01 января 1970 года по 31 февраля 1990 года,
дата смерти: 14 ноябрь 2000
Встреча состоится 13.03.2037 или может быть
19.05.2017. Или нет.
'''
 
re_date = re.compile(r'''
    (?:
        (d{1,2})s+(январ(?:ь|я)|феврал(?:ь|я)|ноябр(?:ь|я))s+(d{4})
        |
        ((d{2}).(d{2}).(d{4}))
    )
    ''', re.I | re.X)
 
print(re_date.findall(t))



0



151 / 102 / 33

Регистрация: 11.08.2016

Сообщений: 574

26.03.2018, 15:04

19

Цитата
Сообщение от Рыжий Лис
Посмотреть сообщение

есть две проблемы

для ТС: перед тем, как втыкать регулярку в код, regexbuddy в помощь.



0



Garry Galler

Эксперт Python

5407 / 3831 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

26.03.2018, 20:11

20

Не по теме сабжа (к тому ж ТС не обозначил понятие что есть дата в его (кон)тексте).

После выделения токенов дат (регулярками или, к примеру, нейронной сетью) может возникнуть задача преобразования полученных сущностей в объекты python. Есть такой превосходный модуль как dateparser, который умеет преобразовывать множество токенов типа “дата” (самого широкого диапазона) в объект datetime. Поддерживает кучу языков (человеческих).

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import dateparser
 
dates = ['сегодня','завтра', 'вчера',
        'послезавтра',
        'позавчера',
        '1 час назад','2 часа назад',
        'через 3 часа',
        '20 минут назад',
        'сейчас',
        'через 3 секунды',
        '13 января 2018 г. в 13:34',
        '13 января',
        'январь 2017',
        'январь',
        '1 день назад',
        '02-03-2018', # parsing ambiguous date: uses MDY date order - можно задать другой порядок разбора
        '02/03/2018',
        '2018-02-03'
        ]
 
for date in dates:
    print('{:30}{}'.format(date,dateparser.parse(date)))

Код

сегодня                       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



Добавить комментарий