Как изменить формат строки даты (20 октября 2052 -> 2052-10-20) - PullRequest
0 голосов
/ 22 января 2019

Blockquote

У меня есть строка даты в формате День Месяц Год, например, 1 марта 1984 г., 4 апреля 1973 г., 22 мая 2006 г., где:

День в наборе {"1-й", "2-й", "3-й", ..., "30-й", "31-й"}

Месяц в наборе {"январь", "февраль", "март", ..., "декабрь"}

Год находится в диапазоне [1900,2100]

Мне нужно преобразовать строку даты в формат ГГГГ-ММ-ДД, например: 1 марта 1984 -> 1984-03-01 4 апреля 1973 г. -> 1973-04-04

(Функция reformatDate имеет следующие параметры: даты [даты [0], ..., даты [n-1]] - массив строк даты в формате день месяц год)

Пример ввода 4 20 октября 2052 г. 6 июня 1933 г. 26 мая 1960 г. 20 сентября 1958 г.

Пример вывода 2052-10-20 1933-06-06 1960-05-26 1958-09-20

enter code here
    def reformatDate(dates):
    # write your code here
    if __name__ == '__main__':
        fptr = open(os.environ['OUTPUT_PATH'], 'w')
        dates_count = int(input().strip())
        dates = []
        for _ in range(dates_count):
            dates.item = input()
            dates.append(dates_item)       
        result = reformatDate(dates)
        fptr.write('\n'.join(result))
        fptr.write('\n')
        fptr.close

Ответы [ 5 ]

0 голосов
/ 22 января 2019

Вы писали:

Я бы предпочел не использовать внешние модули, если это возможно

в комментарии, но datetime и calendar являются частями стандартной библиотеки, а не являются внешними модулями! То есть: эти модули являются частью языка Python как целые числа, циклы, функции и классы. (Ну ... почти: см. Является ли стандартная библиотека Python действительно стандартной? и Какие части стандартной библиотеки Python гарантированно будут доступны? .). Запомните это:

У Python есть философия «батареи включены». ( Гвидо ван Россум , https://docs.python.org/3/tutorial/stdlib.html#batteries-included)

Вы не должны пытаться избегать использования стандартной библиотеки, а скорее узнаете, как ее использовать.

Если вы все еще хотите попробовать сделать это самостоятельно, вы можете играть с обычным однострочником:

>>> date_strings = ["20th Oct 2052", "6th Jun 1933", "26th May 1960", "20th Sep 1958"]
>>> month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
>>> ["{:0>4}-{:0>2}-{:0>2}".format(y, month_names.index(m)+1, d.rstrip("stnrdh")) for d,m,y in map(str.split, date_strings)]
['2052-10-20', '1933-06-06', '1960-05-26', '1958-09-20']

Пояснение:

  • Формат {:0>4} означает: ширина должна быть 4, выровнена по правому краю (>) для чисел и строк и заполнена 0 с (см .: https://docs.python.org/3.7/library/string.html#formatspec).
  • month_names.index(m)+1 - номер месяца (сбой, если месяц неизвестен)
  • d.rstrip("stnrdh") просто очищает суффикс номера дня ("st", "nd", "rd", "th")
  • map(str.split, date_strings) разбивает даты на три части (день, месяц, год).

Обратите внимание, что этот код не будет работать, если введенные данные неверны. Другими словами, я бы не стал полагаться на этот код, если входные данные не проверены.

0 голосов
/ 22 января 2019

Поскольку во всех предыдущих ответах использовались модули вывода (re, datetime или calendar находятся в стандартной библиотеке Python, но, тем не менее, их необходимо импортировать как таковые), я написал решение со встроенным Python функции. Не стесняйтесь предлагать улучшения:

#your input
d = ["20th Oct 2052", "6th Jun 1933", "26th May 1960", "20th Sep 1958"]
#first split the data
ds=[l.strip().split(" ") for l in d]
#then create a dictionary for month
month_dict={'Jan':'01', 'Feb':'02', 'Mar':'03', 'Apr':'04', 'May':'05', 'Jun':'06', 'Jul':'07', 'Aug':'08', 'Sep':'09', 'Oct':'10', 'Nov':'11', 'Dec':'12'}

#function to filter digits from a string.
#a strong advantage of filtering digits is that it doesn't matter whether or not days are written with st, nd or rd
def digit_from_string(x):
    s = ''.join(filter(str.isdigit, x))
    #in case only one digit was extracted (e.g., 2), add a 0 in front (e.g., 02)
    if len(s) == 1:
        s='0'+s
    return s

#iterates on the splitted data; v[0] corresponds to the day, v[1] the month and v[2] the year
ds=[{'day': digit_from_string(v[0]),
    'month': digit_from_string(month_dict[v[1]]),
    'year': digit_from_string(v[2])}
   for v in ds]

#format the output
output=['{0}-{1}-{2}'.format(x['year'],x['month'],x['day']) for x in ds]

Выход:

['2052-10-20', '1933-06-06', '1960-05-26', '1958-09-20']
0 голосов
/ 22 января 2019

Это один подход с использованием модуля datetime.

Ex:

import datetime
import re    

lst = ["20th Oct 2052", "6th Jun 1933", "26th May 1960", "20th Sep 1958"]
for i in lst:
    print(datetime.datetime.strptime(re.sub(r"(st|th|rd)", "", i), "%d %b %Y").strftime("%Y-%m-%d"))

Выход:

2052-10-20
1933-06-06
1960-05-26
1958-09-20

Примечание: re.sub(r"(st|th|rd)", "", i) для удаления st, th, rd из даты.

0 голосов
/ 22 января 2019

Вы можете использовать lambda с пониманием списка:

import re
lst = ["20th Oct 2052", "6th Jun 1933", "26th May 1960", "20th Sep 1958"]
m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
new_data = [(lambda x:f'{x[-1]}-{m.index(x[1])+1}-{x[0]}')(re.findall('\d+|\w{3,}', c)) for c in lst]

Вывод:

['2052-10-20', '1933-6-6', '1960-5-26', '1958-9-20']
0 голосов
/ 22 января 2019

Это своего рода специальное решение для вашего случая. Вы можете избежать использования пакета календаря, передавая свое собственное название месяца для сопоставления номеров. Хотя, возможно, есть более общие и питонические решения.

import calendar 

def reformatDate(dates):
    output_dates = []
    for date in output_dates:
        fields = date.split()
        day = fields[0][:-2]
        month = str(list(calendar.month_abbr).index(fields[1]))
        year = fields[2]
        output_date = year + "-" + month + "-" + day
        output_dates.append(output_date)
    return output_dates
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...