Seite 1 von 1

Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwandeln

Verfasst: Samstag 28. Dezember 2013, 12:39
von Diealready
Ich habe auf meinem Gameserver ein Plugin was die Spielzeiten alias "Playtime" jedes Spieler in Sekunden speichert.
Also wenn Spieler "123456" exact 5 Minuten auf meinem Server gespielt hat wird in der Datenbank 300.00 Sekunden angezeigt (60 sekunden * 5=300 sekunden)

Nun hab ich ein Script erstellt was die Sekunden in jeweils Sekunden oder Stunden oder Tage oder Wochen oder Monate ausgibt.

Code: Alles auswählen

def formatTimeAgo(seconds):
    if seconds < 60:
        return "%i seconds" % seconds
    elif seconds < 3600:
        return "%i minutes" % (seconds/float(60))
    elif seconds < (3600*24):
        return "%.1f hours" % (seconds/float(3600))
    elif seconds < (3600*24*7):
        return "%.1f Days" % (seconds/float(3600*24))
    elif seconds < (3600*24*7*30):
        return "%.1f Weeks" % (seconds/float(3600*24*7))
    else:
        return "%.1f Months" % (seconds/float(3600*24*30))
Dieses Script funktioniert einwand frei denn es zeigt für Spieler 123456 exakt 5 Minutes also "5 minutes" an.
Doch ich möchte gerne das es mir ab Wochen also "Weeks" nicht einfach nur als Beispiel (21523 Sekunden) Es würde mir 3.4 Wochen anzeigen also im Spiel 3.4 Weeks. Doch ich möchte das es mir gerne anzeigt 3 Wochen 2 Tage also "3 Weeks 2 Days" anzeigt oder für 1 Monat 2 Wochen "1 month 2 Weeks".

Viel Dank im vorraus.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Samstag 28. Dezember 2013, 13:05
von EyDu
Hallo und willkommen im Forum!

Schau dir mal den Modulo-Operator an, damit geht es recht schnell. Du berechnest also erst die Anzahl der Wochen und aus dem Rest dann die Tage. Wenn dann noch etwas die Stunden, dann die Minuten und abschließend die Sekunden.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Samstag 28. Dezember 2013, 13:44
von BlackJack
So ein Stück weit können die Sachen aus dem `datetime`-Modul auch helfen diese Umrechnung zu machen.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Samstag 28. Dezember 2013, 13:50
von Diealready
EyDu hat geschrieben:Hallo und willkommen im Forum!

Schau dir mal den Modulo-Operator an, damit geht es recht schnell. Du berechnest also erst die Anzahl der Wochen und aus dem Rest dann die Tage. Wenn dann noch etwas die Stunden, dann die Minuten und abschließend die Sekunden.
Hallo Eydu,

Danke für die freundliche Begrüßung.

Ich werde mir dies mal anschauen. Danke

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 29. Dezember 2013, 08:51
von NoPy
Ist sicher keine Schönheit, was die Funktion selbst oder die Ausgabe betrifft, aber im Prinzip würde ich es so machen.
Wie dann Deine Rückgabezeichenkette aussehen soll, das musst Du natürlich selbst festlegen.

Code: Alles auswählen

def to_special_string(sekunden):
    #falls tatsaechlich mal ein float ankommt
    sekunden = int(sekunden)

    #Ermitteln der Einzelwerte
    minuten = sekunden/60
    sekunden -= minuten*60
    
    stunden = minuten/60
    minuten -= stunden*60
    
    tage = stunden/24
    stunden -= tage*24
    
    wochen = tage/7
    tage -=wochen*7
    
    monate = wochen/4
    wochen -= monate*4

    #Monate sind natuerlich tricky, ich habe mich für 4 Wochen entschieden, ansonsten kann es seltsam werden
    #angenommen, Du gehst von 30 Tagen aus:
    #29 Tage = 4 Wochen, 1 Tag
    #30 Tage = 1 Monat, 0 Wochen, 0 Tage
    #die Herangehensweise wäre analog, Du muesstest erst die Anzahl der Monate aus den Tagen ermitteln, danach die Wochen aus den Tagen, also:
    #monate = tage/30
    #tage -= monate*30
    #wochen = tage/7
    #tage -= wochen*7
    
    #Zusammenbasteln eines Rueckgabewertes
    return_value = ''
    if monate>0:
        if monate>1:
            return_value += "%d Monate " % monate
        else:
            return_value += "einen Monat "
    
    if wochen>0:
        if wochen>1:
            return_value += "%d Wochen " % wochen
        else:
            return_value += "eine Woche "

    if tage>0:
        if tage>1:
            return_value += "%d Tage " % tage
        else:
            return_value += "einen Tag "
    
    print monate,wochen,tage,stunden,minuten,sekunden #nur zur Kontrolle
    return_value += "%02d:%02d:%02d" % (stunden, minuten, sekunden)

    return return_value
Gibt es an der Herangehensweise etwas auszusetzen?

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 29. Dezember 2013, 11:24
von Sirius3
@NoPy: Es gibt den Modulo-Operator »%« der den Rest einer Division ermittelt (»mod« in Delphi), in Python sogar »divmod« das Division und Rest gleichzeitig berechnet. In Python wird gerne mit Listen gearbeitet, z.B. um einen String aus mehreren Teilen zusammenzusetzen benutzt man eine Liste und »'..'.join«. Dazu wäre es praktisch, alles irgendwo in Listen zu speichern, um so Redundanzen im Code zu vermeiden:

Code: Alles auswählen

UNITS = ('Monate', 'Wochen', 'Tage', 'Stunden' ,'Minuten', 'Sekunden')
SPANS = (60, 60, 24, 7, 4)

def to_special_string(seconds):
    parts = [seconds]
    for span in SPANS:
        parts[:1] = divmod(parts[0], span)
    return ' '.join(
        '%d %s'%(value, unit) if value!=1 else '1 %s'%unit[:-1]
        for value, unit in zip(parts, UNITS) if value)

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 29. Dezember 2013, 11:28
von snafu
Hier mal mit Trennung von Berechnung und Ausgabe:

Code: Alles auswählen

from collections import namedtuple

class Duration(namedtuple('Duration', 'weeks, days, hours, minutes, seconds')):
    def __str__(self):
        return ', '.join(self._get_formatted_units())

    def _get_formatted_units(self):
        for unit_name, value in self._asdict().items():
            if value > 0:
                if value == 1:
                    unit_name = unit_name.rstrip('s')
                yield '{} {}'.format(value, unit_name)


def get_duration(seconds):
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    weeks, days = divmod(days, 7)
    return Duration(weeks, days, hours, minutes, seconds)
Beispiele aus der Python-Shell:

Code: Alles auswählen

>>> print get_duration(3)
3 seconds
>>> print get_duration(59)
59 seconds
>>> print get_duration(1)
1 second
>>> print get_duration(61)
1 minute, 1 second
>>> print get_duration(62)
1 minute, 2 seconds
>>> print get_duration(121)
2 minutes, 1 second
>>> print get_duration(3600)
1 hour
>>> print get_duration(3601)
1 hour, 1 second
>>> print get_duration(3602)
1 hour, 2 seconds
>>> print get_duration(3120)
52 minutes
>>> print get_duration(42354365)
70 weeks, 5 hours, 6 minutes, 5 seconds
Die Fehlerausgabe bei negativen Werten und die Sonderbehandlung von einer 0-sekündigen Spieldauer (hierfür würde mein Code überhaupt keine formattierte Ausgabe liefern) habe ich mal weggelassen...

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 29. Dezember 2013, 19:01
von snafu
Hier nochmal eine deutlich flexiblere Variante, basierend auf den Ideen von Sirius3:

Code: Alles auswählen

from collections import namedtuple, OrderedDict

UNITS = OrderedDict([
    ('Monate', 1), ('Wochen', 4), ('Tage', 7),
    ('Stunden', 24), ('Minuten', 60), ('Sekunden', 60)
])

class Duration(namedtuple('Duration', UNITS.keys())):
    def __str__(self):
        return ', '.join(self._get_formatted_units())

    def _get_formatted_units(self):
        data = self._asdict()
        if not any(data.values()):
            yield '0 {}'.format(data.keys()[-1])
            return
        for unit_name, value in data.items():
            if value:
                if value == 1:
                    unit_name = unit_name[:-1]
                yield '{} {}'.format(value, unit_name)

def get_duration(seconds):
    parts = [seconds]
    for span in reversed(UNITS.values()[1:]):
        parts[:1] = divmod(parts[0], span)
    return Duration(*parts)
Ich habe jetzt auch die Behandlung einer 0-sekündigen Spieldauer eingebaut.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 19:28
von Diealready
Ich entschuldige mich für meine verspätete Antwort (hat schon seine Gründe ;>)

Ich danke euch erstmal für die Antworten , sehen auch ziemlich vielversprechend aus , doch wäre dies auch möglich ohne irgendwelche module zu importieren? sondern einfach meinen vorgegebenen Code zu ändern? (<< Dies ist eine Frage :D)

Schönen Abend euch und einen guten Arbeitsstart ;)

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 19:50
von BlackJack
@Diealready: Die Antwort ist ganz offensichtlich ja. Aber warum sollte man keine Module benutzen? Noch dazu wenn sie schon in der Standardbibliothek vorhanden sind?

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 20:48
von Diealready
Ich mags eigentlich sehr ungern module zu importieren , da ich die Scripts für meinen Gameserver benutze , und daher die libs von dem jeweiligen modul einfügen muss.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 20:51
von BlackJack
@Diealready: Das sind Module aus der Standardbibliothek. Die sind dabei, die muss man nicht hinzufügen.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 21:53
von Diealready
Danke für die schnelle Antwort :)

Doch leider bekomm ich trotzdem die nachricht
"no module named 'namedtuple'()"

Gruß

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 5. Januar 2014, 22:13
von BlackJack
@Diealready: Das wird wahrscheinlich weder die tatsächliche Meldung sein, noch wird das von einer hier gezeigten Quelltextzeile stammen. Was versuchst Du denn da tatsächlich und wie sieht die Meldung tatsächlich aus?

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Dienstag 7. Januar 2014, 18:48
von NoPy
Bei mir geht es ohne Probleme. Sieht lustig aus :)

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Dienstag 7. Januar 2014, 19:26
von HarteWare
Sorry, aber ich muss mal kurz nochmals anmerken, das ist... sagen wir nicht sehr gut, wenn du irgendwie bewusst keine module nutzen willst.

Du willst schließlich nicht Zeit damit verschwenden, das Rad täglich neu zu erfinden. Dazu sind die Lösungen der Standardbibliothek einfach besser - da steckt richtig Zeit und Arbeit drin.

Das ist auch übrigens, meiner Meinung nach, einer der Stärken von Python. Es gibt eigentlich für die meisten Sachen irgendein Modul...
Da wäre es doch schade drum, diese auch nicht zu nutzen, wenn angemessen.

LG

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Samstag 11. Januar 2014, 19:06
von Diealready
Leider siehts danach aus das Eventscripts Python die Standartmodule von Python nicht dabei hat.

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Sonntag 12. Januar 2014, 12:15
von Hyperion
Diealready hat geschrieben:Leider siehts danach aus das Eventscripts Python die Standartmodule von Python nicht dabei hat.
Sollte es sich um ein Python 2.5 handeln, wäre ``namedtuple`` tatsächlich nicht dabei. Man kann sich aber ja sicher die Python-Version anzeigen lassen, oder?

Re: Sekunden in jeweils Stunden / Tagen /Wochen/Monate umwan

Verfasst: Samstag 1. Februar 2014, 13:27
von Diealready
Auf der Seite steht.

Full Python 2.5 language support for addons: