Gestoppte Zeit im hh:mm:ss Format

  • Hallo,

    irgendwie komme ich an der dieser Stelle nicht weiter.
    Ich habe einen Prozess dessen Ausführungszeit ich erfassen muss.
    Dabei bin ich schon auf die vielen Hinweise von Dennis89 mit time.monotonic() gestossen. Die Laufzeit habe ich nun erst einmal. Jedoch liegt dann der Wert als eine Zahl im Format ss.[irgendwas] vor.
    Nun möchte ich bzw. benötige ich für eine Ausgabe das Ergebnis als STRING im Format HH:MM:SS,[2 Stellen] z.B. 00:13:37,15.
    Wie kann ich das möglichst einfach mit Python 3.9. umsetzen ?

    Danke

    Steffen.

  • `int()` und `divmod()` dürften die beiden Funktionen sein, die Du suchst. Also erst ganze Sekunden daraus machen und dann daraus erst Minuten und Sekunden berechnen und dann aus den Minuten noch mal Stunden und Minuten. Dann noch Zeichenkettenformatierung als f-Zeichenkettenliteral oder mit der `format()`-Methode. Da kann man auch das mit zweistellig und führender 0 regeln.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Hallo,

    ‚monotonic_ns‘ würde schon einen ‚int‘ liefern. Allerdings, wie der Name schon vermuten lässt, werden keine Sekunden geliefert. Aber die Umrechnung ist auch machbar.

    Grüße

    Dennis

    Edit: Die Ausgabe könnte man doch auch mit datetime.time machen? (Bin gerade nur am Handy)

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Edit: Die Ausgabe könnte man doch auch mit datetime.time machen? (Bin gerade nur am Handy)

    Ja, das geht, die Ausgabe muss noch optimiert werden:

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • rpi444 Das meinte ich nicht. Sondern die berechneten Stunden, Minuten und Sekunden in ein time-Objekt anstatt in einen String zu wandeln.

    datetime.time(hour=0, minute=2, second=3)

    zum Beispiel.

    Für die Zahlen halt die berechneten Werte die ‚divmide‘ ausgibt einsetzen. Wobei das auch abhängig ist ob noch weitere Zeitioperationen damit gemacht werden sollen oder ob ein String zur Ausgabe reicht.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Code
    import datetime
    
    
    sekunden = 3601
    
    ganze_minuten, sekunden = divmod(sekunden, 60)
    ganze_stunden, ganze_minuten = divmod(ganze_minuten, 60)
    
    zeit = datetime.time(ganze_stunden, ganze_minuten, sekunden)

    Der Trick dabei ist, dass die Funktion divmod zwei Werte ausgibt. Der erste Wert ist die ganzzahlige Division und der zweite Wert ist der Rest.

    So bekommt man im ersten Schritt die ganzen_minuten und die restlichen sekunden.

    Beim zweiten Schritt werden die ganze_minuten in ganze_stunden und ganze_minuten (rest) umgerechnet.

    Das letzte ist optional. Der Vorteil von datetime.time ist, dass man sie vergleichen kann. Kann man mit einer Tupel aber auch.

  • `datetime.time` ist halt falsch und ein Missbrauch weil es gar nicht um eine Zeit geht, sondern um eine Dauer. Das fällt einem spätestens dann auf die Füsse wenn man eine Dauer ab 24 Stunden hat.

    Python
    In [90]: datetime.time(hour=24)
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Input In [90], in <cell line: 1>()
    ----> 1 datetime.time(hour=24)
    
    ValueError: hour must be in 0..23

    Für Zeitdauern gibt's das hyle ja bereits erwähnte `datetime.timedelta`. Das kommt als zum Wert passender Datentyp nicht nur mit langen Dauern klar, sondern auch mit negativen Werten.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • `datetime.time` ok. Habe ich in den 15 Jahren Python vielleicht 5 Mal verwendet, inklusive heute.

    Mit timedelta geht es sogar noch einfacher:

    Code
    import datetime
    
    
    sekunden = 3601
    delta = datetime.timedelta(seconds=sekunden)

    Wenn man dann umrechnen möchte:

    Code
    delta_stunden = delta / datetime.timedelta(hours=1)

    Da bekommt man aber keine ganzen Zahlen raus und das Ergebnis ist dann ein float und kein timedelta mehr.

  • Habe nun auch mal getestet:

    Python
    >>> import datetime
    >>> messergebnis = 12345
    >>> ausgabe = str(datetime.timedelta(seconds=messergebnis))
    >>> print(f"{ausgabe :0>8}")
    03:25:45

    Ohne dem f-String wäre die Stunde nur einstellig.


    //Edit

    Ich sehe gerade, dass alles was über 86399 Sekunden ist, ein Tag angezeigt wird und die einstelligen Stunden dann auch wieder einstellig angezeigt werden, z.B.: 18 days, 8:38:41

  • Das ist die Repräsentation als str.

    Die Nutzung von str() ist unnötig.

    Bei print wird generell erst die __str__ Methode aufgerufen und wenn es die nicht gibt, wird das von __repr__ zurückgeliefert. Man kann aber auch explizit vorgeben, was man will.

    Wie das mit __str__ und __repr__ funktioniert:

    Falls weder __str__ noch __repr__ vorhanden sind, werden die Methoden von object vererbt und dann hat man die Darstellung mit Name und virtueller Speicheradresse.

    Die Ausgabe würde sich aber z.B. nicht eigenen, um Vergleiche anzustellen, da es sich um str handelt und nicht int oder int in einer tuple.

    Man kann sich das mit timedelta auch sparen. Wie man es manuell berechnen kann, sollte jeder Anfänger als Erstes lernen.

  • Die Nutzung von str() ist unnötig.

    Bitte sehr:

    Code
    >>> messergebnis = 12345
    >>> ausgabe = datetime.timedelta(seconds=messergebnis)
    >>> print(f"{ausgabe :0>8}")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported format string passed to datetime.timedelta.__format__
    >>>
  • Stimmt. Nach längerem Suchen weiß ich jetzt auch warum.

    Die Klasse datetime.timedelta hat keine __format__ Methode, ergo kann man das Objekt nicht formatieren.

    Das geht:

    Code
    print(f"{ausgabe!s:0>8}")

    Das funktioniert deswegen, da zuerst explizit ein str angefordert und erst dann die __format__ Methode angewandt wird.

    Jede Klasse kann ein eigenes Format zur Formatierung anbieten, was z.B. bei datetime.datetime ziemlich billig ist, da der String zur Formatierung der Methode einfach strftime übergeben wird.

    Code
    import datetime
    
    print(f"{datetime.datetime.now():%d.%m.%Y}")

    Format kann man hier nachlesen: https://docs.python.org/3/library/date…rptime-behavior


    PS: Es ist auch sehr ungewöhnlich, timedelta formatieren zu wollen. Eigentlich ist das zum Rechnen da.

    Einmal editiert, zuletzt von RestlessMud46765 (8. November 2022 um 19:17)

  • Danke, Danke und nochmals Danke.

    mir hatte die erste Antwort von __blackjack__ schon gereicht. Ich hatte mir damit so etwas ähnliches zurechtgebastelt wie es DeaD_EyE in Post #7 nur ohne dieses ganze Sache mit datetime.
    Es ist schön das sich hier so viele Gedanken über irgendwelche Ausgabeformate, Formatierung und sonstiges machen. Alles nicht notwendig. Wenn der Zusatz Tag gebraucht werden würde, hätte ich das sicherlich mit erwähnt.

    Danke nochmals an alle

    Steffen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!