-1
with proc.oneshot():
    uptime = timedelta(seconds=time() - proc.create_time())
    uptime_minutes, uptime_seconds = divmod(uptime.seconds, 60)
    uptime_hours, uptime_minutes = divmod(uptime_minutes, 60)
    uptime_days, uptime_hours = divmod(uptime_hours, 24)
    
    if uptime_seconds:
        frmt_uptime = '{:01} Seconds'.format(
        int(uptime_seconds))
    
    if uptime_minutes:
        frmt_uptime = '{:01} Minutes, {:01} Seconds'.format(
        int(uptime_minutes),
        int(uptime_seconds))
    
    if uptime_hours:
        frmt_uptime = '{:01} Hours, {:01} Minutes, {:01} Seconds'.format(
        int(uptime_hours),
        int(uptime_minutes),
        int(uptime_seconds))
     
    if uptime_days:
        frmt_uptime = '{:01} Day(s), {:01} Hour(s), {:01} Minute(s), {:01} Second(s)'.format(
        int(uptime_days),
        int(uptime_hours),
        int(uptime_minutes),
        int(uptime_seconds))

print(frmt_uptime)

Now I want this to show the amount of days but for some reason currently it goes 23hrs 59mins 59secs and then should go 1 day. A second later 1 day, 1 second. A minute later, 1 day 1 minute. But currently it just seems to restart after 24hrs which leads me to believe something is wrong with how I am working out days.

Łukasz Kwieciński
  • 14,992
  • 4
  • 21
  • 39

2 Answers2

1

The way you process the time, you need .total_seconds.

However, your code will not display "1 day, 1 second", because your format string inside if uptime_days: will always include hours and minutes.

Suggestion:

from datetime import timedelta, datetime

def uptime(create_time: datetime):
    uptime = datetime.now() - create_time
    uptime_minutes, uptime_seconds = divmod(uptime.total_seconds(), 60)
    uptime_hours, uptime_minutes = divmod(uptime_minutes, 60)
    uptime_days, uptime_hours = divmod(uptime_hours, 24)

    time_parts = []

    if uptime_days:
        time_parts.append('{:01} Days'.format(int(uptime_days)))

    if uptime_hours:
        time_parts.append('{:01} Hours'.format(int(uptime_hours)))

    if uptime_minutes:
        time_parts.append('{:01} Minutes'.format(int(uptime_minutes)))

    if uptime_seconds:
        time_parts.append('{:01} Seconds'.format(int(uptime_seconds)))

    return ", ".join(time_parts)

print(uptime(datetime(2021, 2,11,16,20)))
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
0

I'm not entirely too sure what's wrong with your code, but my approach would be the following:

from datetime import datetime

bot = commands.Bot(...) # Or `discord.Client`, depends what you're using
bot.uptime = datetime.utcnow()

Inside the command just get the delta and format it

@bot.command()
async def uptime(ctx):
    now = datetime.utcnow()
    delta = now - bot.uptime
    # Feel free to format it as you want
    seconds = int(delta.total_seconds())
    hours, remainder = divmod(seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    
    if hours >= 24:
        days, hours = divmod(hours, 24)
        message = f"Uptime: {days} day(s), {hours} hour(s), {minutes} minute(s), {seconds} second(s)"

    else:
        message = f"Uptime: {hours} hour(s), {minutes} minute(s), {seconds} second(s)"

    await ctx.send(message)
Łukasz Kwieciński
  • 14,992
  • 4
  • 21
  • 39