如何将描述时间的字符串转换为秒?
How to convert a string describing time into seconds?
我正在尝试创建一个函数将时间字符串(来自用户)转换为秒数。
我想做的是让用户以字符串形式输入时间,例如:
"one hour and forty five minutes"
然后将其分解为秒。所以上面的输出将是
6300 seconds
这不是一件容易的事,没有特定的方法可以做到,或者我不知道。但我分享了一段代码,可以给你一个想法。
首先,您需要读取输入字符串并拆分它。拆分数据时,您应该搜索关键字符串,例如“小时”或“分钟”。在此之后,您需要获取此值并在您已经定义数字字符串版本的数据集中搜索。然后,你需要定义一些规则,例如(四十,五十,它们都以ty结尾,你可以在字符串中搜索这些东西。)
但是,用户可以输入的可能性是无限的,因此您应该定义限制。我刚刚分享了我对如何解决此类问题的看法,但我可能会漏掉一些要点。
def convertSeconds(n_hours,n_minutes):
return n_hours * 3600 + n_minutes *60
dataSet = {
"one": 1,
"two": 2,
"three": 3,
"four": 4,
"five": 5,
"six": 6,
"seven":7,
"eight":8,
"nine":9,
"hundred":100,
"hundreds":100,
"thousand" : 1000,
"millions" : 1000000
#etc...
}
time = input('Please Enter Date As String : ')
word_array = time.split()
idx = 0
idx_hour = 0
for word in word_array:
if word == "hour":
n_hours = word_array[0:idx]
idx_hour = idx
if word == "hours":
n_hours = word_array[0:idx]
idx_hour = idx
if word == "and":
idx_hour = idx_hour +1
if word == "minute":
n_minutes = word_array[idx_hour+1:idx]
if word == "minutes":
n_minutes = word_array[idx_hour+1:idx]
idx = idx + 1
total_hours = 0
total_minutes = 0
for counter in range(len(n_hours)):
value = dataSet[n_hours[counter]]
if n_hours[counter] == "hundreds" or n_hours[counter] == "hundred":
value = dataSet[n_hours[counter-1]] * 100
total_hours = total_hours - dataSet[n_hours[counter-1]]
total_hours = total_hours + value
for counter in range(len(n_minutes)):
value = dataSet[n_minutes[counter]]
total_minutes = total_minutes + value
print("Your Time in Seconds : ",convertSeconds(total_hours,total_minutes))
Please Enter Date As String : two hundred hours and five minutes
Your Time in Seconds : 720300
parsedatetime
库可以完成一些工作。
from parsedatetime import Calendar, Constants
c = Calendar(Constants(usePyICU=False))
c.parse("1 minute and 3 hours")
将 return 一个时间结构,不幸的是包含了整个日期。如果您输入超过 24 小时,将尝试重新计算日期。
并且,数字必须以数字而不是单词的形式呈现,但您可以使用 replace() 提前格式化您的字符串。
一旦你有了一个时间结构,你可以使用time.mktime()
将它转换成Unix以来的秒数,然后你可以减去当前时间的秒数,或者更安全,在[=13中输入开始日期=] 方法并减去它。
这是不完美的,但我使用 dateutil.parser.parser.parse()
和 parsedatetime.Calendar.parse()
的组合从用户那里获得 datetime.datetime()
。如果 dateutil
失败,那么我会尝试 parsedatetime
。用户了解如何输入日期和时间以正确识别它们。
你可以用很长的数字字典来做到这一点:
def parse_int(string):
numbers = {'zero': 0,
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'nine': 9,
'ten': 10,
'eleven': 11,
'twelve': 12,
'thirteen': 13,
'fourteen': 14,
'fifteen': 15,
'sixteen': 16,
'seventeen': 17,
'eighteen': 18,
'nineteen': 19,
'twenty': 20,
'twenty-one': 21,
'twenty-two': 22,
'twenty-three': 23,
'twenty-four': 24,
'twenty-five': 25,
'twenty-six': 26,
'twenty-seven': 27,
'twenty-eight': 28,
'twenty-nine': 29,
'thirty': 30,
'thirty-one': 31,
'thirty-two': 32,
'thirty-three': 33,
'thirty-four': 34,
'thirty-five': 35,
'thirty-six': 36,
'thirty-seven': 37,
'thirty-eight': 38,
'thirty-nine': 39,
'forty': 40,
'forty-one': 41,
'forty-two': 42,
'forty-three': 43,
'forty-four': 44,
'forty-five': 45,
'forty-six': 46,
'forty-seven': 47,
'forty-eight': 48,
'forty-nine': 49,
'fifty': 50,
'fifty-one': 51,
'fifty-two': 52,
'fifty-three': 53,
'fifty-four': 54,
'fifty-five': 55,
'fifty-six': 56,
'fifty-seven': 57,
'fifty-eight': 58,
'fifty-nine': 59,
'sixty': 60,
'sixty-one': 61,
'sixty-two': 62,
'sixty-three': 63,
'sixty-four': 64,
'sixty-five': 65,
'sixty-six': 66,
'sixty-seven': 67,
'sixty-eight': 68,
'sixty-nine': 69,
'seventy': 70,
'seventy-one': 71,
'seventy-two': 72,
'seventy-three': 73,
'seventy-four': 74,
'seventy-five': 75,
'seventy-six': 76,
'seventy-seven': 77,
'seventy-eight': 78,
'seventy-nine': 79,
'eighty': 80,
'eighty-one': 81,
'eighty-two': 82,
'eighty-three': 83,
'eighty-four': 84,
'eighty-five': 85,
'eighty-six': 86,
'eighty-seven': 87,
'eighty-eight': 88,
'eighty-nine': 89,
'ninety': 90,
'ninety-one': 91,
'ninety-two': 92,
'ninety-three': 93,
'ninety-four': 94,
'ninety-five': 95,
'ninety-six': 96,
'ninety-seven': 97,
'ninety-eight': 98,
'ninety-nine': 99}
powers = {'hundred': 10 ** 2,
'thousand': 10 ** 3,
'million': 10 ** 6,
'billion': 10 ** 9,
'quadrillion': 10 ** 15,
'quintillion': 10 ** 18,
'sextillion': 10 ** 21,
'septillion': 10 ** 24,
'octillion': 10 ** 27,
'nonillion': 10 ** 30,
'decillion': 10 ** 33,
'undecillion': 10 ** 36,
'duodecillion': 10 ** 39,
'tredecillion': 10 ** 42,
'quattuordecillion': 10 ** 45,
'quindecillion': 10 ** 48,
'sexdecillion': 10 ** 51,
'septemdecillion': 10 ** 54,
'octodecillion': 10 ** 57,
'novemdecillion': 10 ** 60,
'vigintillion': 10 ** 63,
'vigintunillion': 10 ** 66,
'unvigintillion': 10 ** 66,
'duovigintillion': 10 ** 69,
'vigintiduoillion': 10 ** 69,
'vigintitrillion': 10 ** 72,
'trevigintillion': 10 ** 72,
'vigintiquadrillion': 10 ** 75,
'quattuorvigintillion': 10 ** 75,
'quinvigintillion': 10 ** 78,
'vigintiquintrillion': 10 ** 78,
'vigintisextillion': 10 ** 81,
'sexvigintillion': 10 ** 81,
'vigintiseptillion': 10 ** 84,
'septvigintillion': 10 ** 84,
'octovigintillion': 10 ** 87,
'vigintoctillion': 10 ** 87,
'vigintinonillion': 10 ** 90,
'nonvigintillion': 10 ** 90,
'trigintillion': 10 ** 93,
'untrigintillion': 10 ** 96,
'duotrigintillion': 10 ** 99,
'googol': 10 ** 100,
'centillion': 10 ** 303}
result = 0
a = string.split(" ")
b = []
for c in a:
if c in numbers:
b.append(c)
elif c in powers:
b[-1] += " " + c
elif c == "and":
continue
else:
print("INVALID WORD:",c)
return
for d, e in enumerate(b):
if len(e.split(" ")) == 1:
b[d] = numbers[e]
else:
b[d] = e.split(" ")
b[d][0] = numbers[b[d][0]]
f = 1
while f < len(b[d]):
b[d][f] = powers[b[d][f]]
f += 1
if not(isinstance(b[0], int)):
while len(b[0]) > 2:
b[0][1] *= b[0][2]
b[0].pop(2)
while len(b):
if len(b) == 1:
if isinstance(b[0], int):
result += b[0]
b.pop(0)
else:
while len(b[0]) > 1:
b[0][0] *= b[0][1]
b[0].pop(1)
result += b[0][0]
b.pop(0)
else:
if isinstance(b[1], int):
b[1] += b[0][0] * b[0][1]
b.pop(0)
else:
while len(b[1]) > 2:
b[1][1] *= b[1][2]
b[1].pop(2)
if b[0][1] < b[1][1]:
b[1][0] += b[0][0] * b[0][1]
b.pop(0)
else:
result += b[0][0] * b[0][1]
b.pop(0)
return result
hours, minutes = input(">>> ").split(" and ")
seconds = parse_int(hours.rsplit(' ', 1)[0]) * 3600 + \
parse_int(minutes.rsplit(' ', 1)[0]) * 60
print(seconds)
测试运行:
>>> one billion hours and twelve minutes
输出:
3600000000720
如果您想从头开始,那么其他答案也不错。以下是您无需输入太多内容即可执行的操作:
您需要为该解决方案安装 word2number
。
from word2number import w2n
import re
def strTimeToSec(s):
s = s.replace(' and', '')
time = re.split(' hour| hours| minute| minutes| second| seconds', s)[:-1]
if not('hour' in s):
time = ['zero']+time
elif not('minute' in s):
time = [time[0]]+['zero']+[time[1]]
elif not('second' in s):
time = time+['zero']
time = [w2n.word_to_num(x) for x in time]
out = time[0]*3600+time[1]*60+time[2]
return str(out)+' seconds'
>>> print(strTimeToSec('one hour and forty five minute'))
6300 seconds
>>> print(strTimeToSec('one hour forty five minute and thirty three seconds'))
6333 seconds
我正在尝试创建一个函数将时间字符串(来自用户)转换为秒数。
我想做的是让用户以字符串形式输入时间,例如:
"one hour and forty five minutes"
然后将其分解为秒。所以上面的输出将是
6300 seconds
这不是一件容易的事,没有特定的方法可以做到,或者我不知道。但我分享了一段代码,可以给你一个想法。 首先,您需要读取输入字符串并拆分它。拆分数据时,您应该搜索关键字符串,例如“小时”或“分钟”。在此之后,您需要获取此值并在您已经定义数字字符串版本的数据集中搜索。然后,你需要定义一些规则,例如(四十,五十,它们都以ty结尾,你可以在字符串中搜索这些东西。)
但是,用户可以输入的可能性是无限的,因此您应该定义限制。我刚刚分享了我对如何解决此类问题的看法,但我可能会漏掉一些要点。
def convertSeconds(n_hours,n_minutes):
return n_hours * 3600 + n_minutes *60
dataSet = {
"one": 1,
"two": 2,
"three": 3,
"four": 4,
"five": 5,
"six": 6,
"seven":7,
"eight":8,
"nine":9,
"hundred":100,
"hundreds":100,
"thousand" : 1000,
"millions" : 1000000
#etc...
}
time = input('Please Enter Date As String : ')
word_array = time.split()
idx = 0
idx_hour = 0
for word in word_array:
if word == "hour":
n_hours = word_array[0:idx]
idx_hour = idx
if word == "hours":
n_hours = word_array[0:idx]
idx_hour = idx
if word == "and":
idx_hour = idx_hour +1
if word == "minute":
n_minutes = word_array[idx_hour+1:idx]
if word == "minutes":
n_minutes = word_array[idx_hour+1:idx]
idx = idx + 1
total_hours = 0
total_minutes = 0
for counter in range(len(n_hours)):
value = dataSet[n_hours[counter]]
if n_hours[counter] == "hundreds" or n_hours[counter] == "hundred":
value = dataSet[n_hours[counter-1]] * 100
total_hours = total_hours - dataSet[n_hours[counter-1]]
total_hours = total_hours + value
for counter in range(len(n_minutes)):
value = dataSet[n_minutes[counter]]
total_minutes = total_minutes + value
print("Your Time in Seconds : ",convertSeconds(total_hours,total_minutes))
Please Enter Date As String : two hundred hours and five minutes
Your Time in Seconds : 720300
parsedatetime
库可以完成一些工作。
from parsedatetime import Calendar, Constants
c = Calendar(Constants(usePyICU=False))
c.parse("1 minute and 3 hours")
将 return 一个时间结构,不幸的是包含了整个日期。如果您输入超过 24 小时,将尝试重新计算日期。 并且,数字必须以数字而不是单词的形式呈现,但您可以使用 replace() 提前格式化您的字符串。
一旦你有了一个时间结构,你可以使用time.mktime()
将它转换成Unix以来的秒数,然后你可以减去当前时间的秒数,或者更安全,在[=13中输入开始日期=] 方法并减去它。
这是不完美的,但我使用 dateutil.parser.parser.parse()
和 parsedatetime.Calendar.parse()
的组合从用户那里获得 datetime.datetime()
。如果 dateutil
失败,那么我会尝试 parsedatetime
。用户了解如何输入日期和时间以正确识别它们。
你可以用很长的数字字典来做到这一点:
def parse_int(string):
numbers = {'zero': 0,
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'nine': 9,
'ten': 10,
'eleven': 11,
'twelve': 12,
'thirteen': 13,
'fourteen': 14,
'fifteen': 15,
'sixteen': 16,
'seventeen': 17,
'eighteen': 18,
'nineteen': 19,
'twenty': 20,
'twenty-one': 21,
'twenty-two': 22,
'twenty-three': 23,
'twenty-four': 24,
'twenty-five': 25,
'twenty-six': 26,
'twenty-seven': 27,
'twenty-eight': 28,
'twenty-nine': 29,
'thirty': 30,
'thirty-one': 31,
'thirty-two': 32,
'thirty-three': 33,
'thirty-four': 34,
'thirty-five': 35,
'thirty-six': 36,
'thirty-seven': 37,
'thirty-eight': 38,
'thirty-nine': 39,
'forty': 40,
'forty-one': 41,
'forty-two': 42,
'forty-three': 43,
'forty-four': 44,
'forty-five': 45,
'forty-six': 46,
'forty-seven': 47,
'forty-eight': 48,
'forty-nine': 49,
'fifty': 50,
'fifty-one': 51,
'fifty-two': 52,
'fifty-three': 53,
'fifty-four': 54,
'fifty-five': 55,
'fifty-six': 56,
'fifty-seven': 57,
'fifty-eight': 58,
'fifty-nine': 59,
'sixty': 60,
'sixty-one': 61,
'sixty-two': 62,
'sixty-three': 63,
'sixty-four': 64,
'sixty-five': 65,
'sixty-six': 66,
'sixty-seven': 67,
'sixty-eight': 68,
'sixty-nine': 69,
'seventy': 70,
'seventy-one': 71,
'seventy-two': 72,
'seventy-three': 73,
'seventy-four': 74,
'seventy-five': 75,
'seventy-six': 76,
'seventy-seven': 77,
'seventy-eight': 78,
'seventy-nine': 79,
'eighty': 80,
'eighty-one': 81,
'eighty-two': 82,
'eighty-three': 83,
'eighty-four': 84,
'eighty-five': 85,
'eighty-six': 86,
'eighty-seven': 87,
'eighty-eight': 88,
'eighty-nine': 89,
'ninety': 90,
'ninety-one': 91,
'ninety-two': 92,
'ninety-three': 93,
'ninety-four': 94,
'ninety-five': 95,
'ninety-six': 96,
'ninety-seven': 97,
'ninety-eight': 98,
'ninety-nine': 99}
powers = {'hundred': 10 ** 2,
'thousand': 10 ** 3,
'million': 10 ** 6,
'billion': 10 ** 9,
'quadrillion': 10 ** 15,
'quintillion': 10 ** 18,
'sextillion': 10 ** 21,
'septillion': 10 ** 24,
'octillion': 10 ** 27,
'nonillion': 10 ** 30,
'decillion': 10 ** 33,
'undecillion': 10 ** 36,
'duodecillion': 10 ** 39,
'tredecillion': 10 ** 42,
'quattuordecillion': 10 ** 45,
'quindecillion': 10 ** 48,
'sexdecillion': 10 ** 51,
'septemdecillion': 10 ** 54,
'octodecillion': 10 ** 57,
'novemdecillion': 10 ** 60,
'vigintillion': 10 ** 63,
'vigintunillion': 10 ** 66,
'unvigintillion': 10 ** 66,
'duovigintillion': 10 ** 69,
'vigintiduoillion': 10 ** 69,
'vigintitrillion': 10 ** 72,
'trevigintillion': 10 ** 72,
'vigintiquadrillion': 10 ** 75,
'quattuorvigintillion': 10 ** 75,
'quinvigintillion': 10 ** 78,
'vigintiquintrillion': 10 ** 78,
'vigintisextillion': 10 ** 81,
'sexvigintillion': 10 ** 81,
'vigintiseptillion': 10 ** 84,
'septvigintillion': 10 ** 84,
'octovigintillion': 10 ** 87,
'vigintoctillion': 10 ** 87,
'vigintinonillion': 10 ** 90,
'nonvigintillion': 10 ** 90,
'trigintillion': 10 ** 93,
'untrigintillion': 10 ** 96,
'duotrigintillion': 10 ** 99,
'googol': 10 ** 100,
'centillion': 10 ** 303}
result = 0
a = string.split(" ")
b = []
for c in a:
if c in numbers:
b.append(c)
elif c in powers:
b[-1] += " " + c
elif c == "and":
continue
else:
print("INVALID WORD:",c)
return
for d, e in enumerate(b):
if len(e.split(" ")) == 1:
b[d] = numbers[e]
else:
b[d] = e.split(" ")
b[d][0] = numbers[b[d][0]]
f = 1
while f < len(b[d]):
b[d][f] = powers[b[d][f]]
f += 1
if not(isinstance(b[0], int)):
while len(b[0]) > 2:
b[0][1] *= b[0][2]
b[0].pop(2)
while len(b):
if len(b) == 1:
if isinstance(b[0], int):
result += b[0]
b.pop(0)
else:
while len(b[0]) > 1:
b[0][0] *= b[0][1]
b[0].pop(1)
result += b[0][0]
b.pop(0)
else:
if isinstance(b[1], int):
b[1] += b[0][0] * b[0][1]
b.pop(0)
else:
while len(b[1]) > 2:
b[1][1] *= b[1][2]
b[1].pop(2)
if b[0][1] < b[1][1]:
b[1][0] += b[0][0] * b[0][1]
b.pop(0)
else:
result += b[0][0] * b[0][1]
b.pop(0)
return result
hours, minutes = input(">>> ").split(" and ")
seconds = parse_int(hours.rsplit(' ', 1)[0]) * 3600 + \
parse_int(minutes.rsplit(' ', 1)[0]) * 60
print(seconds)
测试运行:
>>> one billion hours and twelve minutes
输出:
3600000000720
如果您想从头开始,那么其他答案也不错。以下是您无需输入太多内容即可执行的操作:
您需要为该解决方案安装 word2number
。
from word2number import w2n
import re
def strTimeToSec(s):
s = s.replace(' and', '')
time = re.split(' hour| hours| minute| minutes| second| seconds', s)[:-1]
if not('hour' in s):
time = ['zero']+time
elif not('minute' in s):
time = [time[0]]+['zero']+[time[1]]
elif not('second' in s):
time = time+['zero']
time = [w2n.word_to_num(x) for x in time]
out = time[0]*3600+time[1]*60+time[2]
return str(out)+' seconds'
>>> print(strTimeToSec('one hour and forty five minute'))
6300 seconds
>>> print(strTimeToSec('one hour forty five minute and thirty three seconds'))
6333 seconds