Ricavare la data

giovedì 17 agosto 2006 - 13.29

bluland Profilo | Guru

salve,

avendo a disposizione il WEEK e l'anno come posso ricavare la data precisa del Lunedi di quel week??
es.
week 33 anno 2006
result: 14/08/2006

idee?

darisole Profilo | Junior Member

Crei una nuova data al primo giorno dell'anno (1 gennaio), quindi fai un ciclo fino a trovare il primo lunedì, poi aggiungi 33 settimane oppure 231 giorni.

DateTime temp = new DateTime(2006, 1, 1); while(temp.DayOfWeek != DayOfWeek.Monday) { temp = temp.AddDays(1); } temp = temp.AddDays(33 * 7);

Ora temp è il lunedì della settimana 33, se non ho fatto errori.

EDIT: Ah, scusa, ma tu intendevi in T-SQL? Allora non lo so.

bluland Profilo | Guru

Grazie cmq

alx_81 Profilo | Guru

Ciao!
io farei così, con sql 2000/2005..
dato un anno ed una settimana..

declare @anno int declare @week int set @anno = 2006 set @week = 33 -- con la prima operazione (365/52*@week)-6 trovo l'ultimo giorno della settimana -- se l'anno è bisestile, devi usare 365 e -3 select dateadd(day,(365/52*@week)-6,cast(cast(@anno as varchar(4)) + '0101' as datetime))

ho provato qualche test e sembra funzionare..
ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino

bluland Profilo | Guru

ho provato a mettere

anno 2007
week 1

e non va mi da lo stesso del 2006

alx_81 Profilo | Guru

in effetti ho fatto poche prove e ho visto che in alcuni casi le settimane non sono 52, ma anche 53.. il mio tentativo funziona solo per l'anno di esempio =)
continuerò a guardarci..
Alx81 =)

http://blogs.dotnethell.it/suxstellino

bluland Profilo | Guru

ok grazie nel frattempo mi continuo a cervellare

bluland Profilo | Guru

ok grazie nel frattempo mi continiuo a cervellare

alx_81 Profilo | Guru

Prova con questa..
dai test che ho fatto sembra migliore della prima..
fammi sapere!!

Ciao!

set datefirst 1; declare @week int declare @anno int declare @data_settimane datetime declare @primo_giorno int declare @lunedi datetime set @week = 31 set @anno = 2000 set @data_settimane = dateadd(day,@week*7,cast(cast(@anno as char(4)) + '0101' as datetime)) set @primo_giorno = datepart(dw,@data_settimane) if @primo_giorno > 1 select @lunedi = dateadd(day,1-datepart(dw,@data_settimane),@data_settimane) else select @lunedi = dateadd(day,-7,@data_settimane) select @lunedi set datefirst 7;
Alx81 =)

http://blogs.dotnethell.it/suxstellino

lbenaglia Profilo | Guru

>avendo a disposizione il WEEK e l'anno come posso ricavare la
>data precisa del Lunedi di quel week??
>es.
>week 33 anno 2006
>result: 14/08/2006
>
>idee?

Allora, prima di tutto quel risultato non è corretto per noi italiani
Per gli italiani il primo giorno della settimana è il lunedì e non la domenica come per gli angosassoni (e gli americani).
Probabilmente stai utilizzando una login che ha come lingua di default l'inglese, pertanto il primo giorno della settimana è la domenica. Impostando l'italiano come lingua di default della login, oppure utilizzando il comando SET LANGUAGE Italiano; o ancora ricorrendo al comando SET DATEFIRST 1; imposterai il lunedì come primo giorno della settimana.

Perché il tuo risultato è sbagliato? Perché tenendo presente che per noi il primo giorno della settimana è il lunedì, la settimana corrente del giorno 14/08/2006 è la 34sima e non la 33sima:

/* Imposto come il lunedì come primo giorno della settimana */ SET DATEFIRST 1; GO SELECT DATEPART(week, '20060814') AS Week; GO /* Output: Week ----------- 34 (1 row(s) affected) */

OK, a questo punto ti propongo la seguente soluzione:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Come vedi l'algoritmo è semplice:

- Ricavo il giorno della settimana del 01 gennaio dell'anno passato come parametro;
- Sommo le settimane passate - 1 al 01 gennaio dell'anno passato come parametro, sottraggo il weekday del 01 gennaio (ottenendo la domenica della settimana precedente) ed infine ci aggiungo 1 per ottenere il lunedì.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

bluland Profilo | Guru

X Alex:accidenti a prima vista sembra funzionare lo testo con calma e' ti faccio sapere!!


XLorenzo: grazie me la studio e ti faccio sapere!

bluland Profilo | Guru

X Lorenzo:

non ho capito una cosa ad esempio se metto come dati:

1. EXEC dbo.up_GetDate 1, 2006, @Date OUTPUT;

result

2005-12-26 00:00:00

2. EXEC dbo.up_GetDate 53, 2005, @Date OUTPUT;

result

2005-12-26 00:00:00

coincidono?? e poi cmq il primo week del 2006 non dovrebbe essere quello che parte dal primo lunedi dell'anno ??

saluti

Enzo

bluland Profilo | Guru

x Alex:

sto provando il codice postato sembra funzionare

ma non ho capito alcuni passaggi, vorrei farti alcune domande cosi magari imparo qualcosa:

1. @data_settimane = dateadd(day,@week*7,cast(cast(@anno as char(4)) + '0101' as datetime)) perche' metti +'0101' non sarebbe uguale ometterlo?

2. if @primo_giorno > 1 ma il primo giorno può essere anche < di 1?

3. select @lunedi = dateadd(day,1-datepart(dw,@data_settimane),@data_settimane) perchè select e non set??

4. set datefirst 7; perche alla fine set il datefirst 7??

grazie e saluti

Enzo

lbenaglia Profilo | Guru

>non ho capito una cosa ad esempio se metto come dati:
>
>1. EXEC dbo.up_GetDate 1, 2006, @Date OUTPUT;
>
>result
>
>2005-12-26 00:00:00
>
>2. EXEC dbo.up_GetDate 53, 2005, @Date OUTPUT;
>
>result
>
>2005-12-26 00:00:00
>
>coincidono??

Scusa, tu hai fatto l'esempio del 14/8/2006.
Hai scritto di volere recuperare "il lunedì di quel week". Bene.
Il 01/01/2006 è domenica. Il mio esempio ti restituisce ESATTAMENTE il lunedì DI QUELLA SETTIMANA (di calendario), ovvero il 26/12/2005. Il lunedì della 53sima settimana del 2006 è proprio il 26/12/2005 quindi a me il discorso torna.

>e poi cmq il primo week del 2006 non dovrebbe
>essere quello che parte dal primo lunedi dell'anno ??
No. Se impostiamo come primo giorno della settimana il lunedì, avremo la seguente situazione: Il 01/01/2006 cade di domenica e corrisponde alla prima settimana del 2006, il 02/01/2006 è lunedì e corrisponde alla seconda settimana del 2006.

Il problema è che non esiste alcun lunedì per la prima settimana del 2006 (di SQL Server) dato che quella settimana è composta solo da 1 giorno, il 01/01/2006!!

SELECT DATEPART(week, '20051231') AS week, DATEPART(weekday, '20051231') AS weekday; GO /* Output: week weekday ----------- ----------- 53 6 (1 row(s) affected) */ SELECT DATEPART(week, '20060101') AS week, DATEPART(weekday, '20060101') AS weekday; GO /* Output: week weekday ----------- ----------- 1 7 (1 row(s) affected) */ /* Come vedi la settimana 53 del 2005 e ** la settimana (di calendario) 1 del 2006 ** COINCIDONO! */ SELECT DATEPART(week, '20060102') AS week, DATEPART(weekday, '20060102') AS weekday; GO /* Output: week weekday ----------- ----------- 2 1 (1 row(s) affected) */

Quindi devi chiarirti un po' le idee sul risultato che vuoi ottenere

>saluti
Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lbenaglia Profilo | Guru

Anche se non sono Alessandro provo a risponderti io

>1. @data_settimane = dateadd(day,@week*7,cast(cast(@anno as char(4))
>+ '0101' as datetime)) perche' metti +'0101' non sarebbe uguale
>ometterlo?

In questo caso specifico si potrebbe omettere '0101' dato che l'anno è castato a stringa e SQL Server effettua un cast implicito a datetime in modo "furbo", capendo che la stringa rappresenta un anno e attribuendogli il primo giorno del primo mese.
Ma attenzione, nel caso l'anno fosse espresso come numero intero, SQL Server lo interpreterebbe come numero di giorni dopo la data base del 01/01/1900:

SELECT CAST('2006' AS datetime) AS Data GO /* Output: Data ------------------------ 2006-01-01 00:00:00.000 (1 row(s) affected) */ SELECT CAST(2006 AS datetime) AS Data GO /* Output: Data ------------------------ 1905-06-30 00:00:00.000 (1 row(s) affected) */

>2. if @primo_giorno > 1 ma il primo giorno può essere anche
>< di 1?
No, il weekday è compreso tra 1 e 7.

>3. select @lunedi = dateadd(day,1-datepart(dw,@data_settimane),@data_settimane)
>perchè select e non set??

Leggi attentamente questo articolo di Narayana Vyas Kondreddi:
http://vyaskn.tripod.com/differences_between_set_and_select.htm

>4. set datefirst 7; perche alla fine set il datefirst 7??
Boh, probabilmente per ripristinare le impostazioni relative alla sua login.

>grazie e saluti
Prego.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alx_81 Profilo | Guru

confermo tutto quello che ha detto Lorenzo,
sì.. l'ultima istruzione era per ripristinare lo stato iniziare..
ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino

bluland Profilo | Guru

x Alex:

>2. if @primo_giorno > 1 ma il primo giorno può essere anche
>< di 1?
>No, il weekday è compreso tra 1 e 7.

1. ma allora se e' cosi puo' essere anche omessa questa parte:

else
select @lunedi = dateadd(day,-7,@data_settimane)


2. ma weekday cosa indica?? non sono i giorni lavorativi??

x Lorenzo:

lo so che il tuo algoritmo funziona!
beh allora sto facendo confusione tra italiani ed anglosassoni

poiche devo rispettare i calendari che ho qui, e qui i calendari mi portano come 52 week il 26/12/2006
invece se faccio con sql:

SELECT DATEPART(week, '20051226') as week

Result

week
53

infatti contro prova:
DECLARE @Date smalldatetime;
EXEC dbo.up_GetDate 53, 2005, @Date OUTPUT;
SELECT @Date AS [Date];

Result

Date
2005-12-26 00:00:00

invece dovrebbe essere 52 che e' il week che portano i calendari!
c'e qualcosa che non ho capito!

invece con la soluzione posta da Alex se pongo gli stessi dati week 52 anno 2005

risultato: 2005-12-26 00:00:00.000 cioe' come da calendario ma non come pensa Sql!

saluti
Enzo


ps. lo so lo so mia culpa non riesco mai ad essere poco stringato

lbenaglia Profilo | Guru

>>2. if @primo_giorno > 1 ma il primo giorno può essere anche
>>< di 1?
>>No, il weekday è compreso tra 1 e 7.
>
>1. ma allora se e' cosi puo' essere anche omessa questa parte:
>
>else
> select @lunedi = dateadd(day,-7,@data_settimane)
No. Alessandro ha postato questo codice:

if @primo_giorno > 1 select @lunedi = dateadd(day,1-datepart(dw,@data_settimane),@data_settimane) else select @lunedi = dateadd(day,-7,@data_settimane)

L'else verrà eseguito nel caso in cui @primo_giorno valga 1.

>2. ma weekday cosa indica?? non sono i giorni lavorativi??
No. weekday restituisce il giorno della settimana (un valore compreso tra 1 e 7 dove 1 è lunedì e 7 domenica):

"SET DATEFIRST"
http://msdn.microsoft.com/library/en-us/tsqlref/ts_set-set_4qic.asp

>poiche devo rispettare i calendari che ho qui, e qui i calendari
>mi portano come 52 week il 26/12/2006
I tuoi calendari sono sbagliati

>invece con la soluzione posta da Alex se pongo gli stessi dati
>week 52 anno 2005
>
>risultato: 2005-12-26 00:00:00.000 cioe' come da calendario ma
>non come pensa Sql!
Nessun problema, utilizza la sua

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

bluland Profilo | Guru

Accidenti i calendari sono sbagliati!!

un macello cmq con queste date!!

grazie dell'aiuto ora posso chiudere il thread (qualcuno dira' era ora)

bluland Profilo | Guru

X Alex:

ciao ho letto l'articolo postato da Lorenzo, ma purtoppo ancora devo capire perche in questa parte di codice hai usato SELECT invece che SET:

if @primo_giorno > 1
SELECT @lunedi = dateadd(day,1-@primo_giorno,@data_settimane)

--7.2
else
SELECT @lunedi = dateadd(day,-7,@data_settimane)

anzi secondo quell'articolo si sarebbe potuto usare tranquillamente il SET, me lo potresti spiegare?

saluti

ENzo

alx_81 Profilo | Guru

Ciao..
il problema sta nel fatto che se provi a mettere la prima settimana di un anno che inizia da Lunedì, salta il primo.. quindi lo gestisco..
prova a mettere settimana = 1 anno = 2007 e tirar via il controllo e lo capirai..


Alx81 =)

http://blogs.dotnethell.it/suxstellino

lbenaglia Profilo | Guru

>if @primo_giorno > 1
>SELECT @lunedi = dateadd(day,1-@primo_giorno,@data_settimane)
>
>--7.2
>else
> SELECT @lunedi = dateadd(day,-7,@data_settimane)
>
>anzi secondo quell'articolo si sarebbe potuto usare tranquillamente
>il SET, me lo potresti spiegare?

In questo contesto sarebbe stato più corretto utilizzare il SET dato che rispetta lo standard ANSI e si intende valorizzare una singola variabile.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

alx_81 Profilo | Guru

ok, ora mi sono reso conto di averti risposto ad un post tuo un po' vecchiotto..
oggi sono in coma.. ..
Alx81 =)

http://blogs.dotnethell.it/suxstellino

bluland Profilo | Guru

>In questo contesto sarebbe stato più corretto utilizzare il SET dato che rispetta lo standard >ANSI e si intende valorizzare una singola variabile.

infatti dall'articolo letto il SET era più adatto

Ciao!

grazie Ciao
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5