Wochentage ermitteln

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.
Antworten
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

Moin Leute,
ich habe das Problem, dass ich den/die Wochentag(e) ermitteln muss. Ich habe aber nur die Kalenderwoche und das Jahr zur verfügung. Habe mir schon die Hilfe von time() angesehen, finde dort aber keinen Hinweis der mich weiter bringt.

Gruss
Toeffel
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Den Wochentag von heute kriegst du so:

Code: Alles auswählen

>>> from datetime import date
>>> heute = date.today()
>>> print heute
2005-09-19
>>> print heute.weekday()
0
>>> print ("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag")[heute.weekday()]
Montag
>>> 
Wenn du nur das Jahr und die Kalenderwoche zur Verfügung hast, dann hast du ja wie der Name Kalenderwoche sagt ne ganze Woche?!
Das sind genau alle sieben Wochentage, wenn ich mich nicht irre ,-)
Aber ich nehme mal an du wolltest wissen, wie man zu einem konkreten Datum den Wochentag bestimmt, ansonsten würd ich mal in der Doku zum datetime-Modul gucken, damit kann man ziemlich viel machen...

edit:
Aber auch mit time dürfte das kein Problem sein:

The other representation is a tuple of 9 integers giving local time.
The tuple items are:
year (four digits, e.g. 1998)
month (1-12)
day (1-31)
hours (0-23)
minutes (0-59)
seconds (0-59)
weekday (0-6, Monday is 0)
Julian day (day in the year, 1-366)
DST (Daylight Savings Time) flag (-1, 0 or 1)

Code: Alles auswählen

>>> import time
>>> print time.localtime(time.time())
(2005, 9, 19, 12, 4, 45, 0, 262, 1)
>>> 
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

Nein, ich habe wirklich nur die KW und das Jahr! Nun möchte ich wissen welches Datum dahinter steckt. Mir würde Jaschon reichen, wenn ich den Montag kenne. Die KW1 beginnt ja mit dem ersen Montag im Jahr, also teste ich erst mal auf den 1.1., ergibt dies eine Zahl > 00 dann ist der erste Tag des Jahres ein Montag, ergo beginnt das Jahr am 1.1. mit der 1. KW.
Nun finde ich aber keine Funktion die mir den Montag in einer gegebenen KW ausgiebt :-(

:idea: Mir kommt da beim schreiben gerade eine Idee, wenn ich die angegebene KW mit 7 multiliziere und davon 7 Tage abziehe, sollte ich daoch ganz dich dran sein, nun brauche ich nur noch die Anzahl der wochentage vor der 1. KW, max. 6 ...
das Probier ich mal eben!

Töffel
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Den ersten Montag im Jahr bekommst du einfach so:

Code: Alles auswählen

from datetime import date
janfirst = datetime.date(JAHR,1,1)
monday = (7-janfirst.weekday()) % 7 +1
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

Ich hab auch eine Lösung gefunden, die aber nicht so elegant ist :oops:
Werde noch mal ein wenig Basteln, übriegens wie bekomme das Listing den hier rein??

Toeffel
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Toeffel hat geschrieben:Werde noch mal ein wenig Basteln, übriegens wie bekomme das Listing den hier rein??
Den Code in [ python ] [ /python ] einschließen (ohne Leerzeichen zwischen [ und ])
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

So hier ist meine Lösung:

Code: Alles auswählen

#! /usr/bin/python
# Berechnung des Datuns des 1ten Wochentages einer bestimmten Kalenderwoche
# (puh ist das ein Satz)
#
# Importe
import time
import datetime 
#import date
#Konstanten
Sekunden = Minuten =60
Stunden = 24
WochenTage = 7
# Globale Variablen
KW = Jahr = WochenTagOff = KWTuple = 0

def ersterWochentagdesJahres(Jahr):
	"""
	Hier wird berechnet, welcher Wochentag der 1.1. eines Jahres ist. Um damit weiter zurechnen, 
	ist es notwendig den Offset zum Montag zu haben
	"""
	global WochenTagOff
	d = 0
	d = time.localtime(time.mktime((Jahr,1,1,0,0,0,0,0,0,)))
	WTO = int(time.strftime('%w',d))
	if WTO == 0:
		WochenTagOff = +1		# Sonntag
	elif WTO == 1:
		WochenTagOff = 0		# Montag
	elif WTO == 2:
		WochenTagOff = -1		#Dienstag
	elif WTO == 3:
		WochenTagOff = -2		# Mittwoch
	elif WTO == 4:
		WochenTagOff = -3		# Donnerstag
	elif WTO == 5:
		WochenTagOff = -4		# Freitag
	elif WTO == 6:
		WochenTagOff = -5		# Samstag
	
	return

def berechnungWochenTag():
	global KWTuple
		
	KWTuple=((( KW * WochenTage ) + WochenTagOff ) * Sekunden * Minuten * Stunden )	# Sekunden die vergangen sind seit anfang des Jahres
	KWTuple = KWTuple + time.mktime((Jahr,1,1,0,0,0,0,0,0))	# Plus die seit 1.1.1970
	
	return KWTuple


if __name__ == '__main__':
	KW = 40
	Jahr = 2004
	ersterWochentagdesJahres(Jahr)
	berechnungWochenTag()
	print time.strftime("Die Kalenderwoche " + str(KW) + " beginnt am %A,den %d.%m.%Y", time.localtime(KWTuple))
Kommentare sind sehr willkommen, ist ja auch erst mein 2tes Python Script!

Toeffel

Edit (Leonidas): BBCode aktiviert, damit Python-Tags wirken.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hier hast du mal eine kürzere Offsetberechnung:

Code: Alles auswählen

import datetime

def first_monday(year):
    """
    Hier wird berechnet, welcher Wochentag der 1.1. eines Jahres ist. Um damit weiter zurechnen,
    ist es notwendig den Offset zum Montag zu haben
    """
    date = datetime.date(year, 1, 1)
    
    wto = date.weekday()
    
    # mo, di, mi, do, fr, sa, so
    shifts = [0, -1, -2, -3, -4, -5, +1]
    offset = shifts[wto]
    
    return offset
Bin grad dabei auch den Rest mir neu zu überdenken.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Okay, ich habe das komplett neu überdacht und mir ist aufgefallen, dass ich das Modul time am besten komplett vermeide da es sich mit Timestamps grauenhaft rechnet. Stattdessen habe ich das Modul datetime ausgiebig benutzt, besonders date und timedelta.

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import sys, datetime

def calc_weekday(year, cw):
    # get the first monday of the year
    begin = first_mon(year)
    # create the first monday in the year
    start = datetime.date(year, 1, begin)
    
    # get the progress (in days) of the year
    progress = cw * 7 - 1
    delta = datetime.timedelta(progress)
    # add the progress to the year
    enddate = start + delta
    
    # calculate the begin of the week, 
    #+enddate ist the last day of that week (sunday)
    startdate = enddate - datetime.timedelta(6)
    
    return startdate

def first_mon(year):
    """Gets the date of the first january in the year"""
    janfirst = datetime.date(year, 1, 1)
    monday = (7 - janfirst.weekday()) % 7 +1
    return monday

def main():
    try:
        year, cw = [int(value) for value in sys.argv[1:3]]
    except ValueError:
        print 'Syntax: python weekday.py YEAR CW'
        sys.exit(1)

    start = calc_weekday(year, cw)
    print "Die %i. Kalenderwoche beginnt am %s." % \
        (cw, start.strftime("%d.%m.%Y"))

if __name__ == '__main__':
    main()
Gestartet wirds mit
Kommandozeile hat geschrieben:python weekday.py 2005 38
Übrigens werden globale Variablen hier nicht verändert, so vermeidet man Nebeneffekte (und das Schlüsselwort global, dass ich inzwischen für ähnlich böse halte wie exec).

Interessierte seien noch an das Modul calendar verwiesen, damit könnte man vielleicht auch noch eine Implementation basteln.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Hab mich auch ein wenig gespielt, und bin auf folgendes gekommen:

Code: Alles auswählen

import datetime

def kalenderwoche(year, kw):
    first_monday = 4 - datetime.date(year,1,4).weekday()
    monday_of_kw = first_monday + (kw - 1)*7
    return range(monday_of_kw, monday_of_kw + 7)

print kalenderwoche(2005,2)
Gruß, mawe
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Cool (nette kurze Lösung *g*), das sind die Tage.. aber wo ist der Monat?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

Stimmt. Naja, hier mit Monat:

Code: Alles auswählen

import datetime

def kalenderwoche(year, kw):
    fourth_of_january = datetime.date(year,1,4).weekday()
    first_monday = datetime.date(year,1,4-fourth_of_january)
    monday_of_kw = first_monday + datetime.timedelta(days=(kw-1)*7)
    data = []
    for i in range(7):
        d = monday_of_kw + datetime.timedelta(days=i)
        data.append("%s.%s" % (d.day, d.month))
    return data

print kalenderwoche(2005,5)
Gruß, mawe
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Einloggen macht Freude :D
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hallo,

Ich hab es auch mal versucht. Bei folgender Funktion wird die komplette Woche als Liste zurückgegeben.
Jeder Tag der Woche entspricht einen time.struct_time- tuple.
Dieser kann dann z.B. mit time.strftime() verarbeitet werden.

Code: Alles auswählen

#Module laden
import datetime

def GetWeekDays(y, w):
    """
    Returns a list with timetuple's (like time.struct_time), for
    every day of week.
    y = year
    w = week

    """
    weekdays = []
    for day in range(-14, 14, 1):
        day = datetime.date(y, 1, 1) + datetime.timedelta(w*7+day)
        if day.isocalendar()[1] == w or weekdays and len(weekdays) < 7:
            weekdays.append(day.timetuple())
    return weekdays


if __name__ == '__main__' :
    # Test
    print GetWeekDays(2004, 01)
Gruß, Harry
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

echt Klasse wie kurz der Code geworden ist.
Erstmal Herzlichen Dank an Harry und Mawe!!!!

Harry:
Nur mit der range komme ich nicht ganz klar?? WIeso von -14 bis +14 ?

Gruss
Toeffel
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hi Toeffel,

Das errechnete Anfangsdatum der Woche mit 'w*7' gibt dieses nur ungefähr an.
Erstens beginnt nicht jede Woche am 1.1 des jeweiligen Jahres und zweites hat nicht jede Woche gleich viel Tage.
Des wegen habe ich den Suchzeitraum etwas größer gelegt (-14 bis +14 ist willkürlich von mir so festgelegt).
Man könnte genau festlegen wie groß der Suchzeitraum minimal und maximal sein muß. Ich bin einfach etwas größer gegangen und habe mich auf eben 4 Wochen beschränkt.
Gruß, Harry
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
HarryH hat geschrieben: Erstens beginnt nicht jede Woche am 1.1 des jeweiligen Jahres
Nur eine Anmerkung: Laut ISO-Norm ist die erste Woche des Jahres die, in der der 4. Januar liegt. Deshalb hab ich auch dieses Datum als Start gewählt, und dann auf den dazugehörigen Montag zurückgerechnet.

Gruß, mawe
Toeffel
User
Beiträge: 7
Registriert: Donnerstag 15. September 2005, 09:57

habe deinen Code komplett übersehen, tschuldige :oops:
Wenn ich das Richtig verstehe wir der Return-Wert von calc_weekday(), in die Variable start geschrieben wird. Wenn ich eine Variable benutze die vorher nicht initialisiert wurde, bekomme ich einen Fehler, dies passiert hier nicht, wieso?
Gut finde ich das mit den Übergebenen Variablen, das werde ich bestimmt nutzen können :D

Gruss
Toeffel
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Toeffel hat geschrieben: habe deinen Code komplett übersehen, tschuldige
Du meinst das Script von Leonidas, oder? :)
Toeffel hat geschrieben: Wenn ich das Richtig verstehe wir der Return-Wert von calc_weekday(), in die Variable start geschrieben wird.
Genau.
Toeffel hat geschrieben: Wenn ich eine Variable benutze die vorher nicht initialisiert wurde, bekomme ich einen Fehler, dies passiert hier nicht, wieso?
Zeigst Du bitte mal ein Beispiel.
Antworten