Newsgroup: it.comp.lang.visual-basic
Titolo: Conversione da n° settimana a date

Ciao a tutti,
Sto lavorando ad un progetto VB2005 dove, dato il numero della settimana, 7 textBox mi mostrano i giorni che compongono quella settimana :
 
Private Function GetMondayFromWeek(ByVal week As Integer, ByVal year As Integer) As Date
 
        Dim dt As Date = New Date(year, 1, 1)
        Dim ngiorno1 As Byte = Nothing
        Dim lunedi1 As Date = Nothing
 
        'controllo che giorno era il primo dell'anno e calcolo il primo lunedi dell'anno
        ngiorno1 = dt.DayOfWeek
        Select Case ngiorno1
            Case 0
                'E' domenica
                'Il lunedi è data dalla domenica meno 6 giorni
                lunedi1 = dt.AddDays(-6)
            Case 1
                'E' gia equivalente a lunedi
                lunedi1 = dt
            Case Is > 1
                'E' da calcolare fancendo ngiorni1 - ngiorni -1
                lunedi1 = dt.AddDays(0 - (ngiorno1 - 1))
        End Select
        'Trovato il lunedi della prima settimana calcolo il lunedi attuale
        Return lunedi1.AddDays(7 * (week))
 
    End Function
 
Poi su pulsante :
 
Me.Anno.Text = Format(CreaData, "yyyy")
 
Me.Lun.Text = Format(GetMondayFromWeek(Settimana.Text, Anno.Text), "dd")
        Me.Mar.Text = Format(GetMondayFromWeek(Settimana.Text, Anno.Text).AddDays(1), "dd")
        Me.Mer.Text = Format(GetMondayFromWeek(Settimana.Text, Anno.Text).AddDays(2), "dd")
 
ecc...
 
 
Se l' anno è quello corrente funziona alla perfezione, ma se volessi definire un altro anno come devo fare?
 
 
TextBox1 = N° settimana
TextBox2 = anno
 
Fammi vedere nella casella TxtLunedì il giorno corrispondente alla settimana
Fammi vedere nella casella TxtMartedì il giorno corrispondente alla settimana
ecc...
grazie
Marco

Fammi vedere nella casella TxtMartedì il giorno corrispondente alla settimana
forse non ho capito bene
ma il tuo codice funziona correttamente
dove sta il problema?
ho solo aggiunto un paio di cast
 
 
Private Function GetMondayFromWeek(ByVal week As Integer, ByVal year
As Integer) As Date
 
        Dim dt As Date = New Date(year, 1, 1)
        Dim ngiorno1 As Byte = Nothing
        Dim lunedi1 As Date = Nothing
 
        'controllo che giorno era il primo dell'anno e calcolo il
primo lunedi dell'anno
        ngiorno1 = CByte(dt.DayOfWeek)
 
        Select Case ngiorno1
            Case 0
                'E' domenica
                'Il lunedi è data dalla domenica meno 6 giorni
                lunedi1 = dt.AddDays(-6)
            Case 1
                'E' gia equivalente a lunedi
                lunedi1 = dt
            Case Is > 1
                'E' da calcolare fancendo ngiorni1 - ngiorni -1
                lunedi1 = dt.AddDays(0 - (ngiorno1 - 1))
        End Select
        'Trovato il lunedi della prima settimana calcolo il lunedi
attuale
        Return lunedi1.AddDays(7 * (week))
 
    End Function
 
 Private Sub Button1_Click(sender As System.Object, e As
System.EventArgs) Handles Button1.Click
 
        Lun.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)), "dd")
        Mar.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(1), "dd")
        Mer.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(2), "dd")
        Gio.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(3), "dd")
        Ven.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(4), "dd")
        Sab.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(5), "dd")
        Dom.Text = Format(GetMondayFromWeek(CType(Settimana.Text,
Integer), CType(Anno.Text, Integer)).AddDays(6), "dd")
 
 
    End Sub

Il fatto è che funziona solo per l' anno 2012!
Ho una casella Settimana e una casella Anno
Se metto settimana 14 anno 2012 mi rende dal 2 al 8 ed è corretto.
Se metto settimana 6 anno 2013 mi rende dal 11 al 17 invece dovrebbe essere dal 4 al 10..
 
Se metto settimana 1 - 2013 parte dal 7 mentre la settimana 1 del 2013 va da martedì 1 a domenica 6
 


cambiamo totalmente approccio
dai come input l'anno e il numero della settimana
la funzione ti restituisce il primo lunedi della settimana
 
Function getFirstLunedi(anno As Integer, settimana As Integer) As
String
    Dim d As Date
    d = DateSerial(anno, 1, 0)
    Dim i As Integer
    Dim nSettimana As Integer
    For i = 1 To 365
        d = DateAdd("d", 1, d)
         nSettimana = CInt(Format(d, "ww", vbMonday))
        If nSettimana = settimana Then
            If Weekday(d) = vbMonday Then
                'non fa niente
            Else
                d = DateAdd("d", 7 - Weekday(d, vbMonday) + 1, d)
            End If
            getFirstLunedi= CStr(d)
            Exit For
        End If
    Next i
End Function
ma fai attenzione a questo
http://support.microsoft.com/kb/200299
 
BUG: Format or DatePart Functions Can Return Wrong Week Number for
Last Monday in Year


 
è in c# ma è traducibile velocemente
        static DateTime GetMondayFromWeek(int week, int year)
        {
            DateTime dt = new DateTime(year, 1, 1);
            var c = DateTimeFormatInfo.CurrentInfo; 
 
            var day = dt.DayOfWeek;
            if (day == DayOfWeek.Monday)
                return dt;
 
            do
            {
                dt = dt.AddDays(-1);
            } while (dt.DayOfWeek != DayOfWeek.Monday);
 
            dt = dt.AddDays(7 * week);
            //if (c.Calendar.GetWeekOfYear(dt, c.CalendarWeekRule, c.FirstDayOfWeek) != week)
            //    dt = dt.AddDays(-7);
            return dt;//dt.AddDays(7 * week);
        }
 

Mi da un errore qui :
 
nSettimana = CInt(Format(d, "ww", vbMonday)) <<< vbMonday
 
Troppi argomenti per Public function Format....
 
Oltre a ciò, ho visto il possibile errore, si può rimediare? basta creare un modulo come dice la guida?

Mi da subito errore in  static DateTime GetMondayFromWeek(int week, int year) 
Il codice va messo in una function o direttamente sul pulsante che calcola?


nSettimana = DatePart("ww", d, vbMonday)

Credo di aver risolto!
 
Private Function PrimoLunediAnno(ByVal nYear As Integer) As DateTime
        'La funzione ritorna il primo lunedì della prima settimana dell'anno secondo la norma ISO8601
        'Se il primo giorno dell'anno è un venerdì, sabato o domenica viene cercato il 
        'primo lunedì successivo al primo dell'anno.
        'Se il primo giorno è negli altri casi (lunedì, martedì, mercoledì, giovedì) viene cercato il primo
        'lunedì antecedente il primo dell'anno.
 
        Dim dt As DateTime = New DateTime(nYear, 1, 1)
        Dim nIndex As Integer = -1
 
        If (dt.DayOfWeek > DayOfWeek.Thursday Or dt.DayOfWeek = DayOfWeek.Sunday) Then
            nIndex = 1
        End If
 
        While (dt.DayOfWeek <> DayOfWeek.Monday)
            dt = dt.AddDays(nIndex)
        End While
 
        PrimoLunediAnno = dt
    End Function
 
    Private Function GetMondayFromWeek(ByVal week As Integer, ByVal year As Integer) As Date
        'Data una settimana ritorna il primo lunedì della settimana. Viene utilizzata la norma ISO8601
        '
http://it.wikipedia.org/wiki/ISO_8601
 
        GetMondayFromWeek = PrimoLunediAnno(year).AddDays((week - 1) * 7)
    End Function
 
Ora mi rende correttamente i valori mettendo settimana e decidendo l' anno