Mit Zeitwerten rechnen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Mawilo
User
Beiträge: 446
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Mit Zeitwerten rechnen

Beitragvon Mawilo » Dienstag 5. Dezember 2006, 21:28

Hallo allerseits,

irgendwie stehe ich auf dem Schlauch. Ich benötige für ein Programm eine Funktion, mit der ich mit Zeitwerten im Format hh:mm rechnen kann.
Mein Versuch liefert mir leider nicht das genaue Ergebnis.
Ich bin für Hinweise dankbar :D

Hier mein Versuch:

Code: Alles auswählen

wert1 = '-155:00'
wert2 = '-20:20'

def sumZeit(value1, value2, operation):
    operations = ['+', '-']
    if operation in operations:
        v1h, v1m = value1.split(':')
        v2h, v2m = value2.split(':')

        if int(v1h) < 0:
            v1_in_Minuten = int(v1h) * 60 - int(v1m)
        else:
            v1_in_Minuten = int(v1h) * 60 + int(v1m)
        if int(v2h) < 0:
            v2_in_Minuten = int(v2h) * 60 - int(v2m)
        else:
            v2_in_Minuten = int(v2h) * 60 + int(v2m)
           
        print v1_in_Minuten, v2_in_Minuten
       
        if operation == '-':
            v2_in_Minuten = v2_in_Minuten * -1
           
        ergebnis = v1_in_Minuten + v2_in_Minuten

        print ergebnis

        stunden = ergebnis / 60
        minuten = ergebnis - (stunden * 60)

        print '%02i:%02i'%(stunden, minuten)

sumZeit(wert1, wert2, '+')


Stephan
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 5. Dezember 2006, 21:35

Schau dir mal datetime an: http://docs.python.org/lib/module-datetime.html

Beispiele findest du hier im Forum...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Mawilo
User
Beiträge: 446
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Beitragvon Mawilo » Dienstag 5. Dezember 2006, 22:11

Danke für die schnelle Antwort.
Ich habe mal folgendes Beispiel probiert:

Code: Alles auswählen

import datetime as dt

wert1 = '-155:00'
wert2 = '-20:20'

def sumZeit(value1, value2, operation):
    operations = ['+', '-']
    if operation in operations:
        v1h, v1m = value1.split(':')
        v2h, v2m = value2.split(':')

        x1 = dt.timedelta(hours = int(v1h), minutes = int(v1m))
        x2 = dt.timedelta(hours = int(v2h), minutes = int(v2m))
        x3 = x1 + x2
        print x3

sumZeit(wert1, wert2, '+')


Als Ergebnis bekomme ich:

Code: Alles auswählen

-8 days, 17:20:00


Ich benötige aber das Ergebnis im Format: 175:20

Gibt es dafür noch anders formatierte Ausgaben?

Stephan
BlackJack

Beitragvon BlackJack » Dienstag 5. Dezember 2006, 23:19

Für dieses einfache Problem kann man sich auch schnell eine Klasse basteln:

Code: Alles auswählen

class Time(object):
    def __init__(self, hours=0, minutes=0):
        self.minutes = hours * 60 + minutes
   
    def __str__(self):
        return '%d:%02d' % divmod(self.minutes, 60)
   
    def __int__(self):
        return self.minutes
   
    def __add__(self, other):
        return Time(minutes=int(self) + int(other))
   
    def __sub__(self, other):
        return Time(minutes=int(self) - int(other))
   
    @classmethod
    def from_string(cls, time):
        return cls(*map(int, time.split(':')))


def main():
    wert1 = '-155:00'
    wert2 = '-20:20'
   
    print Time.from_string(wert1) + Time.from_string(wert2)


Recht ungetestet, aber da kommt '-175:20' als Ergebnis.

Edit: Formatierung der Minuten in der Zeichenkettendarstellung korrigiert.
Zuletzt geändert von BlackJack am Mittwoch 6. Dezember 2006, 10:44, insgesamt 1-mal geändert.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Beitragvon JR » Dienstag 5. Dezember 2006, 23:44

Hi Stephan!

Hier ist ein lauffähiges Beispiel, wenn man es ohne spezielle Datentypen lösen will.
Meine Tests waren okay, aber teste es selbst nochmal ausgiebig.

[EDIT: Habe einen Fehler entfernt]

Code: Alles auswählen

#!/Python24/python.exe
# -*- coding: iso-8859-1 -*-
# File: time_calc.py
def calc(time1='', time2='', operation='+'):
    result = ''
    argsOk = False
    if time1 and time2 and operation in ['+', '-']:
        pos1 = time1.find(':')
        pos2 = time2.find(':')
        pos_minus1 = time1.find('-')
        pos_minus2 = time2.find('-')

        if pos1 == len(time1) - 3 and pos2 == len(time2) - 3:
           try:
               t1 = time1.replace('-', '').replace(':', '')
               t2 = time2.replace('-', '').replace(':', '')
               int(t1)
               int(t2)
               if pos_minus1 > 0 or pos_minus2 > 0:
                   print 'Einer der beiden Zeitwerte enthält ein Minus an einer falschen Stelle!'
               else:
                   minus1 = 1
                   if time1[0] == '-':
                       minus1 = -1
                       time1 = time1[1:]
                       pos1 -= 1
                   minus2 = 1
                   if time2[0] == '-':
                       minus2 = -1
                       time2 = time2[1:]
                       pos2 -= 1                   
                   argsOk = True
           except:
               print 'Mindestens ein Zeitwert enthält ein ungültiges Zeichen!\nErlaubt sind "-", ":" und Zahlen.'
    if argsOk:

        hh1 = int(time1[:pos1])
        hh2 = int(time2[:pos2])
        mm1 = int(time1[pos1 + 1:])
        mm2 = int(time2[pos2 + 1:])
       
        # zeiten in minuten
        min1 = minus1 * (60 * hh1 + mm1)
        min2 = minus2 * (60 * hh2 + mm2)
       
        if operation == '+':
            min_result = min1 + min2
        else:
            min_result = min1 - min2

        minus = 1
        if min_result < 0:
            minus = -1
           
        hh_result = abs(min_result) / 60
        min_result = abs(min_result) % 60
       
        result = '%.2d:%.2d'%(minus * hh_result, min_result)
        return result

if __name__ == '__main__':
    result = calc('-155:01', '20:37', '-')
    if result:
        print result


Viel Spaß!
Gruß
Jamil
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Beitragvon JR » Mittwoch 6. Dezember 2006, 00:03

Hi BlackJack,

möchte dir nicht auf den Schlips treten, aber -155:01 - 20:37 = -175:38

Grüße
Jamil
BlackJack

Beitragvon BlackJack » Mittwoch 6. Dezember 2006, 01:04

JR hat geschrieben:möchte dir nicht auf den Schlips treten, aber -155:01 - 20:37 = -175:38


Da ich keinen Schlips trage, dürfte das schwierig werden. Und ich weiss auch nicht warum ich mich auf den Schlips getreten fühlen sollte, wenn Du mit anderen Werten ein anderes Ergebnis herausbekommst. Das ist normal. ;-)

Wo wir gerade beim Schlipstreten sind: Dein Quelltext sieht ziemlich, äh, suboptimal aus. Insbesondere was Lesbarkeit und Verständlichkeit angeht.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Beitragvon JR » Mittwoch 6. Dezember 2006, 07:09

Morgen BlackJack!

Ich finde dein Codesnippet auch schöner. Aber meins funktioniert. :o Ich hatte gestern abend nicht mehr die Lust, viel Wert aufs Codedesign zu legen.
Meist schreibe ich erst einmal einen funktionierenden Code und dann kürze, optimiere und verschönere ich ihn.
Das kommt sicher daher, dass Zeit im Beruf Geld ist und der Kunde vor den Kollegen kommt. Also erst dem Kunden die Lösung bereitstellen, dann dafür sorgen, das spätere Anpassungen ebenso schnell erfolgen können.

Grüße dich
Jamil
Benutzeravatar
Mawilo
User
Beiträge: 446
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Beitragvon Mawilo » Mittwoch 6. Dezember 2006, 13:21

Hallo,

vielen Dank für die Vorschläge. Ich werde beide heute Abend mal ausprobieren. :D

Stephan
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Beitragvon Python 47 » Mittwoch 6. Dezember 2006, 14:11

JR hat geschrieben:Morgen BlackJack!

Ich finde dein Codesnippet auch schöner. Aber meins funktioniert.


BlackJacks funktioniert auch:

Code: Alles auswählen

def main():
    wert1 = '-155:00'
    wert2 = '-20:20'


dann bekommt er auch -175:20 raus, du hast aber mit folgendem gerechnet:

Code: Alles auswählen

if __name__ == '__main__':
    result = calc('-155:01', '20:37', '-')


Ist ja wohl logisch, dass wenn man mit unterschiedlichen Werten rechnet, unterschiedliche Ergebnisse bekommt. :P
mfg

Thomas :-)
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Beitragvon JR » Mittwoch 6. Dezember 2006, 14:43

Hi!

Was du da schreibst ist Unfug. Macht aber nichts.
Probier es einfach selbst mit beiden Scripten aus.

Ist nicht immer drin, was drauf steht. Welche Werte ich beim Test benutzt habe, kannst du hier nicht sehen, es sei denn du hast dich auf meinem Rechner eingehackt. Und das bezweifle ich ein wenig :-)

Viele Grüße
Jamil
BlackJack

Beitragvon BlackJack » Mittwoch 6. Dezember 2006, 16:04

JR hat geschrieben:Was du da schreibst ist Unfug. Macht aber nichts.
Probier es einfach selbst mit beiden Scripten aus.


Er schreibt keinen Unfug. Befolge mal Deinen eigenen Rat.

Ist nicht immer drin, was drauf steht. Welche Werte ich beim Test benutzt habe, kannst du hier nicht sehen, es sei denn du hast dich auf meinem Rechner eingehackt. Und das bezweifle ich ein wenig :-)


Welche Werte Du benutzt hast, kann man in dem von Dir hier veröffentlichten Quelltext nachlesen.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Mittwoch 6. Dezember 2006, 16:12

Jack, was ich nicht ganz versteh ist warum du bei ``from_string`` ein Dekorator benutzt :?

lg
BlackJack

Beitragvon BlackJack » Mittwoch 6. Dezember 2006, 16:35

Weil das eine `classmethod` ist und keine "instancemethod". Das ist eine Methode auf der *Klasse* `Time` und nicht auf einem *Exemplar* vom Typ `Time`.
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Beitragvon JR » Mittwoch 6. Dezember 2006, 17:15

BlackJack hat geschrieben:Welche Werte Du benutzt hast, kann man in dem von Dir hier veröffentlichten Quelltext nachlesen.


Hey, wir reden aneinander vorbei :-) Was meint ihr, wie oft ich die main()

über

Code: Alles auswählen

if __name__ == '__main__':
    result = calc('-155:01', '20:37', '-')
    if result:
        print result

ausführen ließ?
Ich habe doch nicht nur einen Test gemacht.

Wenn ich meins ausführe:

Code: Alles auswählen

#!/Python24/python.exe
# -*- coding: iso-8859-1 -*-
# File: time_calc.py
def calc(time1='', time2='', operation='+'):
    result = ''
    argsOk = False
    if time1 and time2 and operation in ['+', '-']:
        pos1 = time1.find(':')
        pos2 = time2.find(':')
        pos_minus1 = time1.find('-')
        pos_minus2 = time2.find('-')

        if pos1 == len(time1) - 3 and pos2 == len(time2) - 3:
           try:
               t1 = time1.replace('-', '').replace(':', '')
               t2 = time2.replace('-', '').replace(':', '')
               int(t1)
               int(t2)
               if pos_minus1 > 0 or pos_minus2 > 0:
                   print 'Einer der beiden Zeitwerte enthält ein Minus an einer falschen Stelle!'
               else:
                   minus1 = 1
                   if time1[0] == '-':
                       minus1 = -1
                       time1 = time1[1:]
                       pos1 -= 1
                   minus2 = 1
                   if time2[0] == '-':
                       minus2 = -1
                       time2 = time2[1:]
                       pos2 -= 1                   
                   argsOk = True
           except:
               print 'Mindestens ein Zeitwert enthält ein ungültiges Zeichen!\nErlaubt sind "-", ":" und Zahlen.'
    if argsOk:

        hh1 = int(time1[:pos1])
        hh2 = int(time2[:pos2])
        mm1 = int(time1[pos1 + 1:])
        mm2 = int(time2[pos2 + 1:])
       
        # zeiten in minuten
        min1 = minus1 * (60 * hh1 + mm1)
        min2 = minus2 * (60 * hh2 + mm2)
       
        if operation == '+':
            min_result = min1 + min2
        else:
            min_result = min1 - min2

        minus = 1
        if min_result < 0:
            minus = -1
           
        hh_result = abs(min_result) / 60
        min_result = abs(min_result) % 60
       
        result = '%.2d:%.2d'%(minus * hh_result, min_result)
        return result

if __name__ == '__main__':
    result = calc('-155:01', '-20:37', '+')
    if result:
        print result


kommt -175:38 raus. Das stimmt doch, oder?

Wenn ich von BlackJack

Code: Alles auswählen

class Time(object):
    def __init__(self, hours=0, minutes=0):
        self.minutes = hours * 60 + minutes
   
    def __str__(self):
        return '%d:%02d' % divmod(self.minutes, 60)
   
    def __int__(self):
        return self.minutes
   
    def __add__(self, other):
        return Time(minutes=int(self) + int(other))
   
    def __sub__(self, other):
        return Time(minutes=int(self) - int(other))
   
    @classmethod
    def from_string(cls, time):
        return cls(*map(int, time.split(':')))


def main():
    wert1 = '-155:01'
    wert2 = '20:37'
   
    print Time.from_string(wert1) - Time.from_string(wert2)
   
if __name__ == '__main__':
    main()


ausführe, kommt -176:24 raus. Das stimmt nicht, oder?

---------------------

Mir geht es hier keineswegs darum, jemanden anzuschwärzen, zu ärgern oder wie auch immer.
BlackJack hatte eh geschrieben:

BlackJack hat geschrieben:Recht ungetestet, aber ...


Korrigiert mich bitte, wenn ich mich irre!

Ansonsten diskutieren wir da am besten jetzt nicht viel weiter, sonst enthalten unsere Beiträge keine hilfreichen Informationen die sich direkt auf Python beziehen.

Viele Grüße
Jamil

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], Sirius3