0

I have looked for other answers on StackOverflow with no luck.

I have a mute command in discord.py, that looks like this:

@client.command() @commands.has_permissions(kick_members=True) async def mute(ctx, member: discord.Member, time: typing.Optional[str], *, reason = None): guild = ctx.guild for role in guild.roles: if role.name == "Muted": await member.add_roles(role) await ctx.send("{} has has been muted because {}!" .format(member.username + "#" + member.discriminator, reason)) 

How do I make the time argument into milliseconds? Similar to the ms module in node.js.

For example I want the duration of >mute @user 1h some reason to be parsed into 3600000 milliseconds.

3
  • Is the command given to you as a string or list? Commented Jun 22, 2020 at 23:30
  • Basically, the time is a string that has a value of something like 1h or 10m, meaning 1 hour and 10 minutes, respectively. I want to parse the given time into milliseconds. Commented Jun 22, 2020 at 23:31
  • What did you search for, that gave no help at all? This is "simple" (once you've done it once or twice" string processing; separate the alphabetic part from the numeric part, and directly program the meanings you need. Look for regex to extract the word and pieces, or write a brute-force solution with isnumeric and isalpha. Is that enough of a start? Commented Jun 22, 2020 at 23:44

2 Answers 2

1

I'm going to assume the formats are 1h, 1m and 1s.

We pull the third item from the string (this doesn't perform error checking to ensure it has 3 items)

raw_time = command.split()[2] # Assuming the command is ">mute @user 1h..." value = int(raw_time[0:-1]) # All but the last character time_type = raw_time[-1] # The last character 

Then, we evaluate to see if it's an hour, minute, or second:

if time_type == 'h': return value * 3600000 elif time_type == 'm': return value * 60000 else: return value * 1000 

You can expand this to include any period (e.g. milliseconds). However, it does not perform any error checking. To double check that the given command will work for this, you can run it through this regex:

if re.match('(\S+\s+){2}\d+(h|m|s).*', command) is not None: raw_time = command.split()[2] # Assuming the command is ">mute @user 1h..." value = int(raw_time[0:-1]) # All but the last character time_type = raw_time[-1] # The last character if time_type == 'h': return value * 3600000 elif time_type == 'm': return value * 60000 else: return value * 1000 else: # ... 
Sign up to request clarification or add additional context in comments.

Comments

0

Python has the built-in module timedelta that would work well for this.

If your string can have mixed time input like "1h", "1h10m", or "1h20m30s", you can use the following:

from datetime import timedelta import re def commandToMs(command): # Check for string of type 1h40m5s, any part optional, surrounding by whitespace. # Negative lookahead at beginning to prevent matching \s\s timeMatch = re.search( r"\s(?!\s)((?P<hrs>\d+)h)?((?P<mins>\d+)m)?((?P<secs>\d+)s)?\s", command) if not timeMatch: return 0 timeDict = timeMatch.groupdict() # Convert empty matches from None to 0 # keys() returns in arbitrary order. Sort to get "hrs", "mins", "secs" hrs, mins, secs = ( int(timeDict[key]) if timeDict[key] else 0 for key in sorted(timeDict.keys()) ) delta = timedelta(hours=hrs, minutes=mins, seconds=secs) return delta.total_seconds() * 1000 commandToMs(">mute @user 1h some reason") # 3600000.0 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.