【问题标题】:Converting list of strings to datetime将字符串列表转换为日期时间
【发布时间】:2019-01-27 01:46:48
【问题描述】:

我正在尝试将字符串列表转换为日期时间。

这是我正在处理的数据示例:
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

非常感谢任何帮助或指导!

【问题讨论】:

  • 是否保证一旦从 %M:%S:%f 转换到 %H:%M:%S 就不会回到以前的格式?
  • 您的数据不明确。 @ChrisHunt 对如何消除歧义有一个好主意。但需要回答他的问题。
  • 您可以使用timedelta 对象并使用total_seconds() 方法计算秒数、分钟数和小时数。
  • @ChrisHunt 数据不会回到以前的格式

标签: python datetime python-datetime timedelta


【解决方案1】:

datetime.datetime 对象必须采用一定范围内的参数,即分钟必须介于 059 之间。但是,您可以创建一个类来处理这种所需的行为。该类可以将输入转换为所需的时间戳格式,存储原始字符串,并提供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]

【讨论】:

    【解决方案2】:

    也许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
    

    【讨论】:

      【解决方案3】:

      您的列表包含持续时间,而不是时间。 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']
      

      【讨论】:

        【解决方案4】:
        >>> 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'
        

        【讨论】:

          【解决方案5】:

          在保证数据不会回到以前的格式的情况下,我们可以对其进行规范化。为了保持干净,最好将其包装在生成器中,这样它就不会弄乱您的主要应用程序逻辑。例如:

          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
          

          现在在循环中你可以做任何你想做的事情。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-25
            • 2015-09-17
            • 1970-01-01
            • 2022-08-18
            • 2017-08-31
            相关资源
            最近更新 更多