Корректность дат

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
как добиться корректности для всех предложенных в массиве?, то есть была ли дата вообще?
Код:
from datetime import datetime as dt
 
dtdt = ['28.02.2012', '28/02/2012', '28 02 2012', '28 02 2012 г.', '28 02 2012 года', '28 февраля 2012 г.']
 
for val in dtdt:
    try:
        dt.strptime(val, '%d.%m.%Y')
        print(val, '- дата корректная')
    except ValueError:
        print(val, '- дата НЕ корректная')
пока корректная только 1-я, спс
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
нужны шаблоны для всех видов дат, которые у вас есть в массиве
например для даты 28/02/2012 шаблон такой '%d/%m/%Y'
 

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
спс за ответ, а формат
Код:
dt.strptime(val, '%d%m%Y')
бывает?, вроде в представленном коде в этом проблема, и посмотрите пжл 12 строк относительно замен текстового представления месяцев можно упростить, там имелось ввиду, чтобы менять в разных падежах мая-мая-мае, ещё нужно некоторые написать с ошибками, например синтябрь, спс
Код:
from datetime import datetime as dt

dtdt = ['28.02.2012', '28/02/2012', '28\02\2012', '28 02 2012', '28 02 2012 г.', '28 02 2012 года',
        '28 февраля 2012 г.']

for val, ind in enumerate(dtdt):
    val = str(val).lower()
    val = val.replace('январ', '01')
    val = val.replace('феврал', '02')
    val = val.replace('март', '03')
    val = val.replace('апрел', '04')
    val = val.replace('ма', '05')
    val = val.replace('июн', '06')
    val = val.replace('июл', '07')
    val = val.replace('август', '08')
    val = val.replace('сентябр', '09')
    val = val.replace('октябр', '10')
    val = val.replace('ноябр', '11')
    val = val.replace('декабр', '12')
    import re

    val = re.sub('^d', '', val)  # в строке удалить все знаки кроме цифр
    try:
        dt.strptime(val, '%d%m%Y')
        print(f'{dtdt[ind]} - дата корректная, день={val[:2]}, месяц={val[2:-4]}, год={val[-4:]}')
    except ValueError:
        print(f'{dtdt[ind]} - дата корректная, день={val[:2]}, месяц={val[2:-4]}, год={val[-4:]}')
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
спс за ответ, а формат бывает?
бывает вот пример
Python:
from datetime import datetime as dt

s = '23022021'
print(dt.strptime(s, '%d%m%Y'))

по поводу замены, можно все эти значения объединить в словарь, где ключ это числовое представление месяца, а значение - это все текстовые виды написания месяца, в том числе и с ошибками...
но принцип будет такой же, вам нужно будет пробегать все элементы и сравнивать/заменять значения...
если много элементов, это может занять продолжительное время, в таком случае можно использовать асинхронные методы обработки...
 

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
спс, управился
 
Последнее редактирование:

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
может занять продолжительное время, в таком случае можно использовать асинхронные методы обработки
так?
Код:
from datetime import datetime as dt

dtdt = ['28февраля2012 г.', '28.02.2012', '28/02/2012', '28\\02\\2012', '28 02 2012', '28 02 2012 г.',
        '28 02 2012 года', '28 02 2012года', '28 02 2012г.', '30 февраля 2012 г.']
for ind, val in enumerate(dtdt):
    val = str(val).lower()
    mm = {'01': ['январь', 'января'],
          '02': ['февраль', 'февраля', 'фивраль', 'фивраля'],
          '03': ['март', 'марта'],
          '04': ['апрель', 'апреля', 'априль', 'априля'],
          '05': ['май', 'мая'],
          '06': ['июнь', 'июня'],
          '07': ['июль', 'июля'],
          '08': ['август', 'августа'],
          '09': ['сентябрь', 'сентября', 'синтябрь', 'синтября'],
          '10': ['октябрь', 'октября'],
          '11': ['ноябрь', 'ноября'],
          '12': ['декабрь', 'декабря', 'дикабрь', 'дикабря']}
    for key_mm, val_mm in mm.items():
        for i in val_mm:
            if i in val:
                val = val.replace(i, key_mm)
                break
    # print(val)
    import re

    val = re.sub('\D', '', val)  # в строке удалить все знаки кроме цифр, '\D' - соответствует нецифровым знакам: [^\d]
    try:
        dt.strptime(val, '%d%m%Y')
        # [:2] - 2-а первых знака, [2:-4] - без первых 2-х и последних 4-х знаков, [-4:] - 4-е последних знаков
        print(f'{dtdt[ind]} - дата корректная, день={val[:2]}, месяц={val[2:-4]}, год={val[-4:]}')
    except ValueError:
        print(f'{dtdt[ind]} - дата НЕ корректная, день={val[:2]}, месяц={val[2:-4]}, год={val[-4:]}')
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
нет это не асинхронная обработка, для этого есть специальный модуль asyncio
 

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
спс за ответ, погуглил
Код:
import asyncio
async def hello_world():
    print("Hello World!")
asyncio.run(hello_world())
# В целом модуль стал работать быстрее и эффективнее
не дошло, можете на моём примере показать? спс
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 580
457
83
спс за ответ, погуглил
Код:
import asyncio
async def hello_world():
    print("Hello World!")
asyncio.run(hello_world())
# В целом модуль стал работать быстрее и эффективнее
не дошло, можете на моём примере показать? спс
в вашем примере элементов немного, использование асинхронной обработки большого прироста вам не принесет...
много элементов - это тысяч 5...
 

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
в вашем примере элементов немного, использование асинхронной обработки большого прироста вам не принесет...
много элементов - это тысяч 5...
это понятно, тем не менее можете выложить? буду использовать на других примерах........ спасибо
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
это понятно, тем не менее можете выложить? буду использовать на других примерах........ спасибо
Чтобы код работал асинхронно можно обернуть его в функцию, которая будет проверять одну дату, а потом запустить эту функцию асинхронно для всех дат в списке. Чтобы получать результаты по мере выполнения можно использовать метод asyncio.as_completed(), а если нужно чтобы результаты получались после проверки всех дат - то asyncio.gather().
Вот пример:
Python:
import asyncio
import re
from datetime import datetime as dt


async def check_date(test_date):
    td = test_date.lower()

    mm = {'01': ['январь', 'января'],
          '02': ['февраль', 'февраля', 'фивраль', 'фивраля'],
          '03': ['март', 'марта'],
          '04': ['апрель', 'апреля', 'априль', 'априля'],
          '05': ['май', 'мая'],
          '06': ['июнь', 'июня'],
          '07': ['июль', 'июля'],
          '08': ['август', 'августа'],
          '09': ['сентябрь', 'сентября', 'синтябрь', 'синтября'],
          '10': ['октябрь', 'октября'],
          '11': ['ноябрь', 'ноября'],
          '12': ['декабрь', 'декабря', 'дикабрь', 'дикабря']}
    flag = False
    for month_number, months_names in mm.items():
        for month in months_names:
            if month in td:
                td = td.replace(month, month_number)
                flag = True
                break
        if flag:
            break

    td = re.sub('\D', '', td)
    correct = ''
    try:
        dt.strptime(td, '%d%m%Y')
    except ValueError:
        correct = ' НЕ'
    finally:
        return (f'{test_date} - дата{correct} корректная, день={td[:2]},'
                f'месяц={td[2:-4]}, год={td[-4:]}')


async def main(dates):
    for task in asyncio.as_completed([check_date(date) for date in dates]):
        print(await task)


dtdt = ['28февраля2012 г.', '28.02.2012', '28/02/2012', '28\\02\\2012', '28 02 2012', '28 02 2012 г.',
        '28 02 2012 года', '28 02 2012года', '28 02 2012г.', '30 февраля 2012 г.']
asyncio.run(main(dtdt))
 

Ципихович Эндрю

Активный пользователь
Пользователь
Мар 27, 2021
490
25
28
спасибо большое
 

Форум IT Специалистов