Преобразование списка строк в дату и время - PullRequest
0 голосов
/ 27 января 2019

Я пытаюсь преобразовать список строк в дату и время.

Вот пример данных, с которыми я имею дело:
x = ['59:55:00', '59:55:00', '59:58:00', '1:00:02', '1:00:05', '1:01:26']

Например, список должен отражать от 59 минут, 58 секунд до 1 часа, 0 минут и 5 секунд.

Я понимаю, что это дурацкий формат, но я играю с рукой, с которой мне раздали. Я не уверен, как обрабатывать данные, когда я получаю значения, превышающие 59 минут.

Я пытался использовать:

from datetime import datetime
for i in x:
    datetime_object = datetime.strptime(i, '%M:%S:%f')
    print(datetime_object)

Мои результаты:

1900-01-01 00:59:55
1900-01-01 00:59:55
1900-01-01 00:59:58
1900-01-01 00:01:00.020000
1900-01-01 00:01:00.050000
1900-01-01 00:01:01.260000

Я хотел бы сохранить вывод в минутах и ​​секундах. Например, 1:01:26 будет 00:61:26

Итак, мой желаемый результат будет выглядеть примерно так:

1900-01-01 00:59:55
1900-01-01 00:59:55
1900-01-01 00:59:58
1900-01-01 00:60:02
1900-01-01 00:60:02
1900-01-01 00:61:26

Любая помощь или руководство с благодарностью!

Ответы [ 5 ]

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

Ваш список содержит длительностей , а не раз. datetime.timedelta разработан для этой цели, но не необходим , если вы хотите очень специфический формат строки для вывода.

Проблема с вашими входными данными - несоответствие форматирования. Если вы хотите жестко закодировать ограничивающее значение для первой части, вы можете применить переключатель с помощью троичных операторов:

from datetime import timedelta

x = ['59:55:00', '59:55:00', '59:58:00', '1:00:02', '1:00:05', '1:01:26']

def converter(value, limit=59):
    var1, var2, var3 = map(int, value.split(':'))
    switch = var1 < limit
    mins = var1 * 60 + var2 if switch else var1
    secs = var3 if switch else var2
    return f'00:{mins:02}:{secs:02}'

res = list(map(converter, x))

print(res)
# ['00:59:55', '00:59:55', '00:59:58', '00:60:02', '00:60:05', '00:61:26']
0 голосов
/ 27 января 2019

datetime.datetime объекты должны принимать параметры, которые находятся в определенном диапазоне, т. Е. Минуты должны быть между 0 и 59. Однако вы можете создать класс для обработки этого желаемого поведения. Класс может преобразовать входные данные в желаемый формат отметки времени, сохранить исходную строку и предоставить свойство to_date для извлечения действительной отметки времени в виде объекта datetime.datetime:

import datetime

class Minutes:
  d = datetime.datetime.now()
  def __init__(self, _str, _year = None):
    self._val = _str
    d = datetime.datetime.now()
    self.year = _year if _year is not None else '-'.join(str(getattr(d, i)) for i in ['year', 'month', 'day'])
  @property
  def to_date(self):
    return datetime.datetime(*map(int, self.year.split('-')), *map(int, str(self).split(':')))
  def __str__(self):
    _h, _m, _s = map(int, self._val.split(':'))
    h, m, s = 0 if _h else _h, _m+(_h*60) if _h else _m, _s
    return f'{self.year} '+':'.join(str(i).zfill(2) for i in [h, m, s])
  def __repr__(self):
    return str(self)

x = ['59:55:00', '59:55:00', '59:58:00', '1:00:02', '1:00:05', '1:01:26']
new_x = [Minutes(i, '1900-01-01') for i in x]    

Выход:

[1900-01-01 00:3595:00, 
 1900-01-01 00:3595:00, 
 1900-01-01 00:3598:00, 
 1900-01-01 00:60:02, 
 1900-01-01 00:60:05, 
 1900-01-01 00:61:26]
0 голосов
/ 27 января 2019
>>> time = datetime.datetime.now()
>>> halfformatted = time.strftime('00:{minutes}:%S.%f')
>>> minutes_total = time.hour * 60 + time.minute
>>> halfformatted.format(minutes=minutes_total)
'00:358:33.339341'
0 голосов
/ 27 января 2019

Учитывая гарантию того, что данные не вернутся к предыдущему формату, мы можем его нормализовать.Чтобы сохранить вещи в чистоте, это, вероятно, лучше обернуть в генератор, чтобы не загромождать логику вашего основного приложения.Например:

def normalized(times):
    hms = False
    last_minute = 0
    for t in x:
        h, m, s = [int(i) for i in t.split(':')]
        if not hms:
            if h < last_minute:
                hms = True
            else:
                h, m, s = 0, h, m
                last_minute = m
        yield f'{h:02}:{m:02}:{s:02}'


x = ['59:55:00', '59:55:00', '59:58:00', '1:00:02', '1:00:05', '1:01:26']


for v in normalized(x):
    print(v)

приводит к

00:59:55
00:59:55
00:59:58
01:00:02
01:00:05
01:01:26

Теперь в цикле вы можете делать все, что захотите.

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

Может быть, strptime здесь не тот инструмент (некоторые проверки ошибок для краткости опущены):

def convert(s):
    parts = [int(i) for i in s.split(":")]

    if parts[0] < 3:  # 3 is arbitrary value, may need adaption
        # Assuming format hour:min:sec
        h, m, s = parts
        millis = 0
    else:
        # Assuming format min:sec:millisec
        m, s, millis = parts
        h = 0

    return "1900-01-01 00:{:02}:{:02}".format(h * 60 + m, s)


x = ['59:55:00', '59:55:00', '59:58:00', '1:00:02', '1:00:05', '1:01:26']

print(*(convert(i) for i in x), sep="\n")

Выход:

1900-01-01 00:59:55
1900-01-01 00:59:55
1900-01-01 00:59:58
1900-01-01 00:60:02
1900-01-01 00:60:05
1900-01-01 00:61:26
...