Newsgroup: it.comp.lang.visual-basic
Titolo: Numero settimana andata e ritorno

Ciao a tutti,
è tutto il giorno che ci provo, sembrava tanto banale...
Per recuperare il numero di settimana secondo la normativa ISO IS-8601, che
dice che la prima settimana di un'anno è quella che contiene il primo
giovedì dell'anno (cioè la prima settimana che ha almeno 4 giorni nell'anno
in corso) non ho trovato altra via che ripiegare su
DatePart("ww", dtData, vbMonday, vbFirstFourDays)
Sarò tonto ma facendo il calcolo a mano non c'è stato verso.
Adesso il problema è tornare indietro: dato il numero della settimana
calcolare il primo giorno di quella settimana.
Ad esempio per la settimana 1 del 2005 la data corrispondente sarebbe il
03/01/2005.
Voi come fareste?
Ciao

 ha scritto

non sapevo del giovedi'.
cmq credo chiederei cos'e' il primo giorno dell'anno. se <= giovedi', la
prima e' quella, seno' quella dopo.
sempre che win non consideri firstdayofyear la pentecoste del primo
bisestile dall'attivazione del calendario gregoriano.
ciao, j.

 Voi come fareste?
Questa mi pare funzionare, prova un po' a vedere se gestisce correttamente
i casi particolari...
termoPilucco
Function primoGiornoDellaSettimana(anno As Long, ByVal settimana As Long)
As Date
Dim dt As Date
Dim NumGiorniDellaPrimaSettimana As Integer
Dim scartoDellaSettimana As Integer
NumGiorniDellaPrimaSettimana = 8 - Weekday(DateSerial(anno, 1, 1),
vbMonday)
If NumGiorniDellaPrimaSettimana >= 4 Then '
    ' la settimana che cerco è la precedente e lo scarto
    ' è negativo
    scartoDellaSettimana = 7 - NumGiorniDellaPrimaSettimana
Else
    ' siamo già nella settimana corretta e lo scarto è
    ' positivo
    scartoDellaSettimana = NumGiorniDellaPrimaSettimana
End If
' trovo un qualsiasi giorno della settimana desiderata
dt = DateSerial(anno, 1, 7 * (settimana - 1) + scartoDellaSettimana + 1)
' mi porto a lunedì
dt = dt - (Weekday(dt, vbMonday) - 1)
' qui si potrebbe testare se year(dt)<>anno nel caso tu voglia
' che la prima settimana non parta dall'anno precedente
primoGiornoDellaSettimana = dt
End Function
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 ha scritto nel messaggio
news:34q6vpF...@individual.net...

Così dovrebbe andare:
Function PrimoGiorno(NrSettimana As Integer, Anno As Long) As Date
    Dim Mydate As Date
    Dim i As Integer
    For i = 1 To 7
        Mydate = DateSerial(Anno, 1, i)
    If Weekday(Mydate, vbMonday) = 4 Then Exit For
    Next i
    Mydate = Mydate - 3
    PrimoGiorno = Mydate + 7 * (NrSettimana - 1)
End Function
--
Ciao
Galliano

 in corso)
curiosità, se il primo gennaio è un giovedì, il primo giorno della prima
settimana dell'anno è lunedì 29/12 ?
-- 
Salutoni
Sergio
Per rispondere... togli il group dall'indirizzo


 calcolare il primo giorno di quella settimana.
io calcolerei, con una tecnica simile a quella utilizzata da termopilucco,
il primo lunedě dell'anno , poi farei
dateadd("ww", numerosettimana-1,primolunedědellanno)


 settimana dell'anno è lunedì 29/12 ?
come l'anno scorso?
In quel caso giovedì è il primo giorno della prima settimana  dell'anno.
Ciao
--
Qualunque mentecatto può scrivere codice che un computer possa capire.
I buoni programmatori scrivono codice che gli uomini possano capire.
[Martin Fowler]

In quel caso giovedì è il primo giorno della prima settimana  dell'anno.
Allora aggiungo alla mia funzione (alla fine del codice) questo :)
if year(dt)<>anno then
	dt=dateserial(anno,1,1)
end if
termoPilucco

 Ciao
Io ho scritto questo codice. Puo andare?
Private Function FirstDayOfWeek(ByVal Settimana As Integer, Optional 
ByVal Anno As Integer) As Date
    Dim Capodanno As Date
    Dim GiornoSettimanaCapodanno As Integer
    Dim PrimaSettimana As Date
    If IsMissing(Anno) Then
       Anno = Year(Date)
    End If
    Capodanno = DateSerial(Anno, 1, 1)
    GiornoSettimanaCapodanno = Weekday(Capodanno, vbMonday)
    If GiornoSettimanaCapodanno < 5 Then
       PrimaSettimana = Capodanno - (GiornoSettimanaCapodanno - 1)
    Else
       PrimaSettimana = Capodanno + (7 Mod GiornoSettimanaCapodanno) + 1
    End If
    FirstDayOfWeek = PrimaSettimana + (Settimana - 1) * 7
End Function

    End If
...poi usi IsMissing(Anno).
IsMissing testa un flag del tipo variant e non funziona con gli altri tipi :)
Infatti se esegui la funzione senza specificare l'anno, restituisce l'anno 2000
anzichè, come era tua intenzione, l'anno attuale.
Ovviamente per correggere la cosa basta modificare la dichiarazione del
parametro Anno in Variant.
Inoltre cambierei l'istruzione 
7 Mod GiornoSettimanaCapodanno
in 
7 - GiornoSettimanaCapodanno
Nei limiti fissati (GiornoSettimanaCapodanno compreso tra 5 e 7) funzionano allo
stesso modo, ma il meno  è più facile da comprendere e più rapido da eseguire :)
Per il resto mi sembra la soluzione più concisa :)
termoPilucco

termoPilucco ha scritto:

Considerando il tuo spiccato senso critico, quest'ultima affermazione mi 
manda letteralmente in giuggiole! :)

manda letteralmente in giuggiole! :)
Beh, la concisione del codice (meno righe di codice, meno loop) è un fatto
oggettivo, non sono io che decido  :)
termoPilucco

 Per il resto mi sembra la soluzione più concisa :)
Sì, ma non funziona :)
? FirstDayOfWeek(1,2004)
Ora provo le altre :P


 ? FirstDayOfWeek(1,2004)
La mia function restituisce lunedě 29/12/2003, che č appunto il primo 
giorno della 1^ settimana del 2004. Perchč non č giusto? Da come hai 
esposto tu il problema mi sembrerebbe essere la risposta esatta. Oppure 
mi sono perso io qualcosa?

 Ciao
Perchč non funziona? Se non mi sono perso io qualcosa del tuo 
ragionamento, il 01/01/2004 capita di giovedě, quindi la prima settimana
comincia di lunedě 29/12/2003. E tanto restituisce la mia funzione. La 
riposto con la correzione sul tipo del parametro Anno, che deve essere 
variant, come giustamente suggerisce termopilucco che ringrazio.
Private Function FirstDayOfWeek(ByVal Settimana As Integer, Optional 
ByVal Anno As Variant) As Date
    Dim Capodanno As Date
    Dim GiornoSettimanaCapodanno As Integer
    Dim PrimaSettimana As Date
    If IsMissing(Anno) Then
       Anno = Year(Date)
    End If
    Capodanno = DateSerial(Anno, 1, 1)


 variant, come giustamente suggerisce termopilucco che ringrazio.
Sinceramente preferisco rendere entrambi i parametri obbligatori e del tipo
corretto.
Poi, per complicare la vita se c'č ancora qualcuno che vuole divertirsi mi
servirebbe cosě:
Private Function FirstDayOfWeek(ByVal Settimana As Integer, ByVal Anno As
Integer, ByVal GiornoSettimana as Integer) As Date
L'ultimo parametro serve per risolvere problemi come quello esposto sopra.
Mettiamo che GiornoSettimana sia martedě allora, dato che ad es. per il 2004
il martedě della prima settimana cade nell'anno precedente, il martedě
valido č quello della settimana successiva, oppure, meglio ancora, se
GiornoSettimana č omesso allora dovrebbe restituire il primo giorno valido
dell'anno.
Comunque complimenti.
Sarebbe bello trovare anche l'algoritmo per simulare
DatePart("ww", dtData, vbMonday, vbFirstFourDays)
Se non altro perchč non mi piace affidarmi a funzioni del linguaggio per
problemi contabili reali.
E comunque credo che questo thread debba finire nelle FAQ del sito comune
per rispondere a questa domanda che ogni tanto salta fuori ma che non č mai
stata risolta in modo definitivo :)
Ciao
--
Qualunque mentecatto puň scrivere codice che un computer possa capire.


 restituire il primo giorno valido dell'anno.
Questo si puň ottenere facilmente come giŕ suggerito da TermoPilucco; anche nella mia
funzione basta aggiungere in fondo:
If Year(PrimoGiorno) < Anno Then
    PrimoGiorno = DateSerial(Anno, 1,1)
End if
[cut]
--
Ciao
Galliano.