none
Week 52 or Week 53 RRS feed

  • Question

  • Hi Great People

    I have a problem with My week Number code. that I thought was working fine. I have tried to write code to find out if the Date I have chosen from the Date time Picker (dtpFirstDayOfYear). And with my Code....

     Dim lastdayOfYear = dtpStartYearDate.Value.AddYears(1).AddDays(-1)
    
            txtLastDayOfYear.Text = lastdayOfYear.ToString("dddd  dd  MMMM  yyyy")
    
            Dim startDate As DateTime = txtFirstDayOfYear.Text
            Dim newDate As DateTime = txtLastDayOfYear.Text
            Dim dateDif As TimeSpan = newDate.Subtract(startDate)
            Dim day As FirstDayOfWeek = FirstDayOfWeek.Friday
            Dim WeekNumber As Integer = (dateDif.Days \ 7) + 1
    
            If isLeapYear(True) Then
                txtWeekNumber.Text = (dateDif.Days \ 7) + 1
            ElseIf isLeapYear(False) Then
                txtWeekNumber.Text = (dateDif.Days \ 7)
    
            End If
    
            txtWeekNumber.Text = WeekNumber.ToString("00")


    .... Dim WeekNumber As Integer = (dateDif.Days \ 7) + 1

    This gives me 53 Week no matter what year I am in.. But If I remove the (+1) This gives me 52 weeks No matter what Year I am in.

    S0 I created A Function called ...

    Shared Function isLeapYear(Year As Boolean). To try and find out, if the Date I selected In a certain year is a 52 week year or a 53 week year

    Full Code I have so far is Below...

    Shared Function isLeapYear(Year As Boolean) 
            'Return Date.IsLeapYear(Year)
    
            Dim result = False
            If Year Mod 4 = 0 Then
                If Year Mod 100 <> 0 Then
                    result = True
                ElseIf Year Mod 400 = 0 Then
                    result = False
                End If
            End If
            Return result
        End Function
    
        Private Sub txtFirstDayOfYear_TextChanged(sender As Object, e As EventArgs) Handles txtFirstDayOfYear.TextChanged
    
            Dim lastdayOfYear = dtpStartYearDate.Value.AddYears(1).AddDays(-1)
    
            txtLastDayOfYear.Text = lastdayOfYear.ToString("dddd  dd  MMMM  yyyy")
    
            Dim startDate As DateTime = txtFirstDayOfYear.Text
            Dim newDate As DateTime = txtLastDayOfYear.Text
            Dim dateDif As TimeSpan = newDate.Subtract(startDate)
            Dim day As FirstDayOfWeek = FirstDayOfWeek.Friday
            Dim WeekNumber As Integer = (dateDif.Days \ 7)
    
            If isLeapYear(True) Then
                txtWeekNumber.Text = (dateDif.Days \ 7) + 1
            ElseIf isLeapYear(False) Then
                txtWeekNumber.Text = (dateDif.Days \ 7)
    
            End If
    
            txtWeekNumber.Text = WeekNumber.ToString("00")
    
    
        End Sub
     

    Please put me right or point me in the right Direction. I have searched the Library code Looked on youtube for code...

    Kind Regards

    Gary


    Gary Simpson

    Wednesday, August 16, 2017 1:21 PM

Answers

  • Gary,

    I'll add my two cents worth in: Even though I don't know what all your new program is and does, you need to get away from using the form's code for anything other than a WinForms UI.

    Instead, create a class library (and I'll help you get started with that if you want). It gives you maximum flexibility both now and down the road, but beyond that - it will also "break" the relationship you're currently using: Controls.

    Let's put this together as a stand-alone, independent of a given control.

    As a quick idea here, I created a class library (that I'll upload for you tomorrow if you want) to show you what I mean. I used "today" as my example fiscal starting date:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Imports FiscalYear.Accounting
    
    Public Class Form1
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            Dim fiscalYear As New Period(Today)
    
            Stop
    
        End Sub
    End Class

    I realize that you're not seeing the code behind "fiscalYear" right now - that's for later, but just by creating a new one as I did, this is the result:

    Full Size Version Here

    The collection that you see is an idea of what you might want to have for each day of that fiscal year. We can alter that any way you want, but the idea is that doing it like that will quickly "answer" what day number it is, what week number it is, what day of the week it is, what the date is ... whatever else you want.

    Give it some thought and we can talk more Thursday. :)

    ***** EDIT *****

    I see an error in calculating the week number, but that can be worked out if you're interested in going this route.

    Let me know and we'll proceed tomorrow.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Wednesday, August 16, 2017 11:03 PM ...error spotted
    • Marked as answer by Gary Simpson Saturday, August 26, 2017 2:30 PM
    Wednesday, August 16, 2017 10:54 PM
  • Gary,

    I've made some changes since yesterday and one big one is that by default, the starting date of the fiscal year will be the first of that month. You can optionally set it to literally any date, but even though accounting very much isn't my thing, in observation I've never seen a starting date other than the first of a particular month.

    The first of October, for example, is the start of the U.S. government's fiscal year and many companies here follow that same schedule.

    Also, I've added in fiscal quarters as that's commonplace here, but if you set the option to NOT use the first - it's null.

    The type is a Nullable(Of Integer) which defaults to "Nothing". If you use the first of a given month, the quarters will make sense, otherwise this doesn't try to work those out.

    The constructor for the class is overloaded: You can give it a date (and optionally tell it NOT to use the first of that month) or you can give it a month (as an integer) and a year (as an integer) and it will then assume the first of that month.

    This is how it looks as an overview (the class diagram):

    The question mark you see above shows that it's a nullable type. That might be confusing but we'll talk about it as this develops.

    The methods aren't really developed much yet because I don't yet know what you want, but like I said earlier, let's start here and see how it goes.

    I have the project folder zipped up and uploaded here:

    http://www.fls-online.net/VBNet_Forum/08-17-17/Test_GaryAccounting.zip

    Download that and extract the contents somewhere, then open it in Visual Studio. When you do, you'll be prompted to convert it to your version so just follow the prompts and it should work ok.

    Once it opens in Visual Studio, look at Solution Explorer and you should see something like this:

    As shown above, there are two projects in this solution.

    That's how I've come to set up a class library: I start with a WinForms application so that I'll immediately have a way to test it. I then add a new project (a class library) and back in the WinForms application, once the library is built, I add a reference to it and sometimes an Imports statement.

    "GA" above is "Gary Accounting" and the namespace is "Accounting". Currently there's only one class in that namespace named "FiscalYear".

    In the test form, you'll see this:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Imports GA.Accounting
    
    Public Class Form1
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            Dim fy As New FiscalYear(10, 2016)
    
            Stop
    
            Dim instance As FiscalYear.Days = fy.Day(New Date(2017, 3, 12))
    
            Stop
    
        End Sub
    End Class

    Go ahead and run it -- it's pretty fast to initialize. The "Stops" above work like breakpoints. When it gets to the first one, hover your mouse over the variable "fy" and you'll see this:

    View Full Size

    One thing that I'd like for you to remember is that the culture for dates are different here than they are there; don't let that confuse you though - an instant in time is represented in a DateTime instance without regard to how it's displayed.

    Notice please that the FiscalEndDate has a time value of one second before midnight on that date. The fiscal year is 365(6) days long minus one second - at least that's what I have it set as. You may or may not be dealing with the time portion of DateTime in this but *just in case you do*, that should have it covered.

    To get the "data" for a particular date that's in the internal collection, I set up the "Day" method that uses a DateTime instance as a parameter. Continue your program and let's see the data for March 12 of this year. Hover your mouse over "instance" and you'll see this:

    View Full Size

    *****

    When you get back to this, let me know what you think so far and if you have questions about it then ask and we'll go from there. :)


    "A problem well stated is a problem half solved.” - Charles F. Kettering




    • Edited by Frank L. Smith Thursday, August 17, 2017 8:18 PM ...typos
    • Marked as answer by Gary Simpson Saturday, August 26, 2017 2:32 PM
    Thursday, August 17, 2017 8:08 PM

All replies

  • Hi

    Week numbers are difficult to resolve. If you look at the year 2018, then the year starts with Jan 1 as the first day of week 1, and Dec 31 as week 53 of the year since Dec 31 falls into the 'next week' so to speak.

    Given such a year, how would you want the week numbers to be - you can't have Dec 31 as week 1 of the next year. How would you want that day to be treated?


    Regards Les, Livingston, Scotland

    Wednesday, August 16, 2017 1:43 PM
  • Hi

    Week numbers are difficult to resolve. If you look at the year 2018, then the year starts with Jan 1 as the first day of week 1, and Dec 31 as week 53 of the year since Dec 31 falls into the 'next week' so to speak.

    Given such a year, how would you want the week numbers to be - you can't have Dec 31 as week 1 of the next year. How would you want that day to be treated?


    Regards Les, Livingston, Scotland

    Hi Les

    Thank you very much for getting back to me. I have this code to get week Number But it put's it in a folder on your Desktop. But I don't know how to get the result from this code into my Program ...

    Public Class Form1
      
        Private Sub Form1_Load(sender As System.Object,
                               e As System.EventArgs) Handles MyBase.Load
            'TestPart the week dates are written to the desktop
            Dim objWriter As New System.IO.StreamWriter(Environment.GetFolderPath(
                                      Environment.SpecialFolder.DesktopDirectory) & "\weekdates.txt")
            Dim datums(1) As Date
            For intYear As Integer = 2017 To 2025
                objWriter.WriteLine("YEAR: " & CStr(intYear))
                objWriter.WriteLine(StrDup(50, "="))
                For intWeek As Integer = 1 To 53
                    datums = GiveDateFromWeek(intYear, intWeek, False)
                    If Not datums Is Nothing Then
                        objWriter.WriteLine("Week: " & intWeek & " Friday: " & datums(0).ToShortDateString & _
                                 " Thursday: " & datums(1).ToShortDateString)
                    End If
                Next
                objWriter.WriteLine(StrDup(50, "="))
            Next
            objWriter.Close()
        End Sub
        'The weekFunction
        Public Function GiveDateFromWeek(Year As Integer, WeekNumber As Integer,
                             Optional ByVal ShowError As Boolean = False) As Date()
            'WEEK CALENDAR ACCORDING TO ISO 8601
            Dim result(1) As Date
            Dim dtpStartYearDate As Date = CDate("1-1-" & Year) ' Here I have Used a Date Time Picker
            Dim EndYearDate As Date = CDate("31-12-" & Year)
            Dim daysToAdd As Integer
            If WeekNumber = 53 Then
                If dtpStartYearDate.DayOfWeek <> _
                                DayOfWeek.Thursday And EndYearDate.DayOfWeek _
                                              <> DayOfWeek.Thursday Then
                    If ShowError = True Then
                        MsgBox("This year hasn't got 53 weeks according to ISO 8601", _
                                                        MsgBoxStyle.Critical, "ISO 8601")
                    End If
                    Return Nothing
                End If
            End If
            Select Case dtpStartYearDate.DayOfWeek
                Case DayOfWeek.Monday
                    daysToAdd = 0
                Case DayOfWeek.Tuesday
                    daysToAdd = -1
                Case DayOfWeek.Wednesday
                    daysToAdd = -2
                Case DayOfWeek.Thursday
                    daysToAdd = -3
                Case DayOfWeek.Friday
                    daysToAdd = +3
                Case DayOfWeek.Saturday
                    daysToAdd = +2
                Case DayOfWeek.Sunday
                    daysToAdd = +1
            End Select
            dtpStartYearDate = DateAdd(DateInterval.Day, daysToAdd, dtpStartYearDate)
            result(0) = DateAdd(DateInterval.WeekOfYear, WeekNumber - 1, dtpStartYearDate)
            result(1) = result(0).AddDays(4)
            Return result
        End Function
        Private Sub dtpStartYearDate_CloseUp(sender As Object, e As EventArgs) Handles dtpStartYearDate.CloseUp
            Dim StartOfYear As Date = dtpStartYearDate.Text
            txtFirstDayOfYear.Text = StartOfYear.ToString("dddd  dd  MMMM  yyyy")
        End Sub

    Kind Regards

    Gary


    Gary Simpson

    Wednesday, August 16, 2017 2:03 PM
  • Hi Gary

    First of all, since you have accumulated 65 points from your contributions in this forum, then why do you not remember to post code in a code block?

    *

    Secondly, getting a week number is trivial.

    *

    The issue is the fact that a year doesn't always have 52 weeks as I showed in my last post.

    The question I asked in my last post still needs to be answered.

    Get a week number

    Dim dt As New DateTime(2018, 12, 31)
    
    Dim WeekNumber As Integer = DatePart(DateInterval.WeekOfYear, dt, FirstDayOfWeek.Sunday, FirstWeekOfYear.System)
    


    Regards Les, Livingston, Scotland


    • Edited by leshay Wednesday, August 16, 2017 2:18 PM added code
    Wednesday, August 16, 2017 2:09 PM
  • Gary,

    You seems to like very much the datediff. As I wrote yesterday, I never use it. 

    The DateTime has a  function which tells if the date is in a leapyear.

    https://msdn.microsoft.com/en-us/library/system.datetime.isleapyear(v=vs.110).aspx


    Success
    Cor


    Wednesday, August 16, 2017 2:14 PM
  • Hi Les

    I want to use Week Numbers For collecting Records of that particular Week, So as for being Trivial I don't think so.

    As for Not posting Code in a block I had done just that. So Something Must have gone wrong Somewhere Between My Post And you Viewing it.. 

    Gary

    Public Class Form1
    
       
        Private Sub Form1_Load(sender As System.Object,
                               e As System.EventArgs) Handles MyBase.Load
            'TestPart the week dates are written to the desktop
            Dim objWriter As New System.IO.StreamWriter(Environment.GetFolderPath(
                                      Environment.SpecialFolder.DesktopDirectory) & "\weekdates.txt")
            Dim datums(1) As Date
            For intYear As Integer = 2017 To 2025
                objWriter.WriteLine("YEAR: " & CStr(intYear))
                objWriter.WriteLine(StrDup(50, "="))
                For intWeek As Integer = 1 To 53
                    datums = GiveDateFromWeek(intYear, intWeek, False)
                    If Not datums Is Nothing Then
                        objWriter.WriteLine("Week: " & intWeek & " Friday: " & datums(0).ToShortDateString & _
                                 " Thursday: " & datums(1).ToShortDateString)
                    End If
                Next
                objWriter.WriteLine(StrDup(50, "="))
            Next
            objWriter.Close()
        End Sub
    
        'The weekFunction
        Public Function GiveDateFromWeek(Year As Integer, WeekNumber As Integer,
                             Optional ByVal ShowError As Boolean = False) As Date()
            'WEEK CALENDAR ACCORDING TO ISO 8601
            Dim result(1) As Date
            Dim dtpStartYearDate As Date = CDate("1-1-" & Year) ' Here I have Used a Date Time Picker
            Dim EndYearDate As Date = CDate("31-12-" & Year)
            Dim daysToAdd As Integer
            If WeekNumber = 53 Then
                If dtpStartYearDate.DayOfWeek <> _
                                DayOfWeek.Thursday And EndYearDate.DayOfWeek _
                                              <> DayOfWeek.Thursday Then
                    If ShowError = True Then
                        MsgBox("This year hasn't got 53 weeks according to ISO 8601", _
                                                        MsgBoxStyle.Critical, "ISO 8601")
                    End If
                    Return Nothing
                End If
            End If
            Select Case dtpStartYearDate.DayOfWeek
                Case DayOfWeek.Monday
                    daysToAdd = 0
                Case DayOfWeek.Tuesday
                    daysToAdd = -1
                Case DayOfWeek.Wednesday
                    daysToAdd = -2
                Case DayOfWeek.Thursday
                    daysToAdd = -3
                Case DayOfWeek.Friday
                    daysToAdd = +3
                Case DayOfWeek.Saturday
                    daysToAdd = +2
                Case DayOfWeek.Sunday
                    daysToAdd = +1
            End Select
            dtpStartYearDate = DateAdd(DateInterval.Day, daysToAdd, dtpStartYearDate)
            result(0) = DateAdd(DateInterval.WeekOfYear, WeekNumber - 1, dtpStartYearDate)
            result(1) = result(0).AddDays(4)
            Return result
    
        End Function
    
    
    
        Private Sub dtpStartYearDate_CloseUp(sender As Object, e As EventArgs) Handles dtpStartYearDate.CloseUp
            Dim StartOfYear As Date = dtpStartYearDate.Text
            txtFirstDayOfYear.Text = StartOfYear.ToString("dddd  dd  MMMM  yyyy")
        End Sub


    Gary Simpson

    Wednesday, August 16, 2017 2:17 PM
  • Hi Gary

    I have added the 'trivial' example to my last post.

    As you can see, it is trivial, but, how it fits in with what you want is not.

    *

    You still didn't answer the question - if the week number is actually week 53, then how do you want to treat that case?


    Regards Les, Livingston, Scotland

    Wednesday, August 16, 2017 2:23 PM
  • Hi

    Here is some code to illustrate some of the anomalies in week number finding.

    This puts a monthlycalendar and a couple of labels onto a blank form. The Calendar shows week numbers, and according to it, Jan 1 of this year is week 52 and week number of Dec 31 this year is week number 52 - however, the calculated week numbers differ with the logical week number of 1 for Jan 1 this year and week number 53 for Dec 31 this year. So, one way produces an anomaly at the start of the year and the other way shows the anomaly at the end of the year.

    ' Blank Form1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim mc As New MonthCalendar
        Dim lab1, lab2 As New Label
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            With mc
                .ShowWeekNumbers = True
                .Location = New Point(20, 20)
            End With
            With lab1
                .Text = "Calculated Week Number = "
                .Location = New Point(20, mc.Bottom + 12)
            End With
            With lab2
                .Text = Nothing
                .Location = New Point(lab1.Right + 20, mc.Bottom + 12)
            End With
            Controls.AddRange({mc, lab1, lab2})
            AddHandler mc.DateChanged, AddressOf MonthCalendar1_DateSelected
    
            lab2.Text = WeekNumber(Now).ToString
    
        End Sub
        Function WeekNumber(dt As Date) As Integer
            Return DatePart(DateInterval.WeekOfYear, dt, FirstDayOfWeek.Sunday, FirstWeekOfYear.System)
        End Function
        Private Sub MonthCalendar1_DateSelected(sender As Object, e As DateRangeEventArgs)
            lab2.Text = WeekNumber(e.Start).ToString
        End Sub
    End Class


    Regards Les, Livingston, Scotland

    Wednesday, August 16, 2017 2:42 PM
  • Unless you post a list of acceptable answers it is hard to say much.

    Here is my list. Is it correct?

    If not why not?

    Wednesday, August 16, 2017 3:02 PM
  • Unless you post a list of acceptable answers it is hard to say much.

    Here is my list. Is it correct?

    If not why not?

    Tommy,

    I guess because Gary is not dealing with ISO weeknumbers but has his own starting day of a week. 

    https://en.wikipedia.org/wiki/ISO_week_date

    I'm still curious why you all try to calculate the leapyear while it is a function in .Net likewise I've showed in this thread. 


    Success
    Cor

    Wednesday, August 16, 2017 3:40 PM
  • Cor,

    Yes. Its still the same problem.

    My point is if the givens and druthers are not specified in advance there is no way to write an algorithm.

    And the only way to test it is to know what the correct answers are.

    So if OP tells us the rules then there is something to do. Otherwise my example works and I am done.

    All we have so far is Gary's code that does not work. But it seems we dont know what working is exactly. Or at least I don't but maybe I missed it?

    PS My example is for Sunday as the first day of the week. Like on a calendar. Is it the correct years? If not why not? What is the correct answer?

    Wednesday, August 16, 2017 4:06 PM
  • PS Here is my example which starts on Sunday as first day of the week. If a day is not part of the year it is not counted. etc. So lets start here. If the answer is wrong then what is the rule(s)?

    Public Class Form7
        Private Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'assume week starts with sunday as in a calendar
            Label1.Text = ""
    
            For y As Integer = 2000 To 2030
                Label1.Text += y.ToString & ": " & GetWeeksStr(y) & vbLf
            Next
    
        End Sub
    
        Private Function GetWeeksStr(thisYear As Integer) As String
            GetWeeksStr = "52 Weeks"
    
            Dim jan1 As Date = DateTime.Parse("#1/1/" & thisYear.ToString & "#")
            Dim firstday As String = jan1.DayOfWeek.ToString
            Dim leapyear As Boolean
            If DateTime.IsLeapYear(thisYear) Then leapyear = True
    
            Dim totalWeeks As String = "52 weeks."
    
            If firstday = "Thursday" Or firstday = "Friday" Or firstday = "Saturday" Then
                If leapyear Then
                    GetWeeksStr = "53 weeks."
                Else
                    If firstday <> "Thursday" Then GetWeeksStr = "53 weeks."
                End If
            End If
        End Function
    End Class

    Wednesday, August 16, 2017 4:43 PM
  • Hi Cor

    Is what I need Is to figure out if a year has 52 or 53 weeks From The Date Time Picker (Date Selected)

    Gary


    Gary Simpson


    Wednesday, August 16, 2017 4:50 PM
  • To get the week number from a date, there is also GetCalendarWeekNumber() from kernel32.dll (DllImport)

    I tested quickly in C++ and it returns 33 for today (in France...), so it seems to work (?)


    • Edited by Castorix31 Wednesday, August 16, 2017 4:57 PM
    Wednesday, August 16, 2017 4:51 PM
  • Hi Cor

    Is what I need Is to figure out if a year has 52 or 53 weeks From The Date Time Picker (Date Selected)

    Gary


    Gary Simpson


    Hi

    This code will show the number of weeks for the year containing the date selected in the DateTimePicker.

    ' Form1 with DateTimePicker1
    Option Strict On
    Option Explicit On
    Public Class Form1
        Dim lab1, lab2 As New Label
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            With lab1
                .Text = "Calculated Week Number = "
                .Location = New Point(DateTimePicker1.Left, DateTimePicker1.Bottom + 12)
            End With
            With lab2
                .Text = Nothing
                .Location = New Point(lab1.Right + 20, DateTimePicker1.Bottom + 12)
            End With
            Controls.AddRange({lab1, lab2})
    
            Dim yr As DateTime = New Date(DateTimePicker1.Value.Year, 12, 31)
            lab2.Text = WeekNumber(yr).ToString
    
        End Sub
        Function WeekNumber(dt As Date) As Integer
            Return DatePart(DateInterval.WeekOfYear, dt, FirstDayOfWeek.Sunday, FirstWeekOfYear.System)
        End Function
        Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
            Dim yr As DateTime = New Date(DateTimePicker1.Value.Year, 12, 31)
            lab2.Text = WeekNumber(yr).ToString
        End Sub
    End Class


    Regards Les, Livingston, Scotland

    Wednesday, August 16, 2017 5:11 PM
  • Gary,

    I'll add my two cents worth in: Even though I don't know what all your new program is and does, you need to get away from using the form's code for anything other than a WinForms UI.

    Instead, create a class library (and I'll help you get started with that if you want). It gives you maximum flexibility both now and down the road, but beyond that - it will also "break" the relationship you're currently using: Controls.

    Let's put this together as a stand-alone, independent of a given control.

    As a quick idea here, I created a class library (that I'll upload for you tomorrow if you want) to show you what I mean. I used "today" as my example fiscal starting date:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Imports FiscalYear.Accounting
    
    Public Class Form1
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            Dim fiscalYear As New Period(Today)
    
            Stop
    
        End Sub
    End Class

    I realize that you're not seeing the code behind "fiscalYear" right now - that's for later, but just by creating a new one as I did, this is the result:

    Full Size Version Here

    The collection that you see is an idea of what you might want to have for each day of that fiscal year. We can alter that any way you want, but the idea is that doing it like that will quickly "answer" what day number it is, what week number it is, what day of the week it is, what the date is ... whatever else you want.

    Give it some thought and we can talk more Thursday. :)

    ***** EDIT *****

    I see an error in calculating the week number, but that can be worked out if you're interested in going this route.

    Let me know and we'll proceed tomorrow.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Wednesday, August 16, 2017 11:03 PM ...error spotted
    • Marked as answer by Gary Simpson Saturday, August 26, 2017 2:30 PM
    Wednesday, August 16, 2017 10:54 PM
  • Revised:

    Full Size Version Here


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Wednesday, August 16, 2017 11:17 PM
  • Gary,

    I'll add my two cents worth in: Even though I don't know what all your new program is and does, you need to get away from using the form's code for anything other than a WinForms UI.

    Instead, create a class library (and I'll help you get started with that if you want). It gives you maximum flexibility both now and down the road, but beyond that - it will also "break" the relationship you're currently using: Controls.

    Let's put this together as a stand-alone, independent of a given control.

    As a quick idea here, I created a class library (that I'll upload for you tomorrow if you want) to show you what I mean. I used "today" as my example fiscal starting date:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Imports FiscalYear.Accounting
    
    Public Class Form1
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            Dim fiscalYear As New Period(Today)
    
            Stop
    
        End Sub
    End Class

    I realize that you're not seeing the code behind "fiscalYear" right now - that's for later, but just by creating a new one as I did, this is the result:

    Full Size Version Here

    The collection that you see is an idea of what you might want to have for each day of that fiscal year. We can alter that any way you want, but the idea is that doing it like that will quickly "answer" what day number it is, what week number it is, what day of the week it is, what the date is ... whatever else you want.

    Give it some thought and we can talk more Thursday. :)

    ***** EDIT *****

    I see an error in calculating the week number, but that can be worked out if you're interested in going this route.

    Let me know and we'll proceed tomorrow.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    Hi Frank 

    I would be glad of any help you are willing to give. But forgive If I seem Stupid. As I have to look after my Wife At the Moment As She has Had Cancer removed. It's been Quite Daunting the last few day.. It might take me Time to get back to you. But it will only be hours before I do get back to you

    Thank you very much Frank

    regards Gary


    Gary Simpson

    Thursday, August 17, 2017 4:26 PM


  • Hi Frank 

    I would be glad of any help you are willing to give. But forgive If I seem Stupid. As I have to look after my Wife At the Moment As She has Had Cancer removed. It's been Quite Daunting the last few day.. It might take me Time to get back to you. But it will only be hours before I do get back to you

    Thank you very much Frank

    regards Gary


    Gary Simpson

    I'm very sorry to know that you two are having to deal with that. All my very best wishes for a speedy recovery.

    *****

    I didn't know if you were interested in this approach or not so I'll continue with this, at least to get it to something we can then discuss.

    One thing I want to change is the hierarchy:

    Imports FiscalYear.Accounting

    That's backwards!

    It's not so bad to start this anew and do it right so I'll have something back in a few hours or at least by morning.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 17, 2017 4:40 PM


  • Hi Frank 

    I would be glad of any help you are willing to give. But forgive If I seem Stupid. As I have to look after my Wife At the Moment As She has Had Cancer removed. It's been Quite Daunting the last few day.. It might take me Time to get back to you. But it will only be hours before I do get back to you

    Thank you very much Frank

    regards Gary


    Gary Simpson

    I'm very sorry to know that you two are having to deal with that. All my very best wishes for a speedy recovery.

    *****

    I didn't know if you were interested in this approach or not so I'll continue with this, at least to get it to something we can then discuss.

    One thing I want to change is the hierarchy:

    Imports FiscalYear.Accounting

    That's backwards!

    It's not so bad to start this anew and do it right so I'll have something back in a few hours or at least by morning.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Hi Frank 

    I have Done what you said "Imports FiscalYear. Accounting" But I don't seem to have It...

    Gary


    Gary Simpson

    Thursday, August 17, 2017 5:14 PM
  • Hi Frank 

    I have Done what you said "Imports FiscalYear. Accounting" But I don't seem to have It..

    No - because I haven't given it to you yet.

    We're creating all of that ourselves which is what makes it so flexible. It's not tied (coupled) to any form or control or component.

    This will make sense when I get it to you. Be patient please.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 17, 2017 5:20 PM
  • Gary,

    I've made some changes since yesterday and one big one is that by default, the starting date of the fiscal year will be the first of that month. You can optionally set it to literally any date, but even though accounting very much isn't my thing, in observation I've never seen a starting date other than the first of a particular month.

    The first of October, for example, is the start of the U.S. government's fiscal year and many companies here follow that same schedule.

    Also, I've added in fiscal quarters as that's commonplace here, but if you set the option to NOT use the first - it's null.

    The type is a Nullable(Of Integer) which defaults to "Nothing". If you use the first of a given month, the quarters will make sense, otherwise this doesn't try to work those out.

    The constructor for the class is overloaded: You can give it a date (and optionally tell it NOT to use the first of that month) or you can give it a month (as an integer) and a year (as an integer) and it will then assume the first of that month.

    This is how it looks as an overview (the class diagram):

    The question mark you see above shows that it's a nullable type. That might be confusing but we'll talk about it as this develops.

    The methods aren't really developed much yet because I don't yet know what you want, but like I said earlier, let's start here and see how it goes.

    I have the project folder zipped up and uploaded here:

    http://www.fls-online.net/VBNet_Forum/08-17-17/Test_GaryAccounting.zip

    Download that and extract the contents somewhere, then open it in Visual Studio. When you do, you'll be prompted to convert it to your version so just follow the prompts and it should work ok.

    Once it opens in Visual Studio, look at Solution Explorer and you should see something like this:

    As shown above, there are two projects in this solution.

    That's how I've come to set up a class library: I start with a WinForms application so that I'll immediately have a way to test it. I then add a new project (a class library) and back in the WinForms application, once the library is built, I add a reference to it and sometimes an Imports statement.

    "GA" above is "Gary Accounting" and the namespace is "Accounting". Currently there's only one class in that namespace named "FiscalYear".

    In the test form, you'll see this:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Imports GA.Accounting
    
    Public Class Form1
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            Dim fy As New FiscalYear(10, 2016)
    
            Stop
    
            Dim instance As FiscalYear.Days = fy.Day(New Date(2017, 3, 12))
    
            Stop
    
        End Sub
    End Class

    Go ahead and run it -- it's pretty fast to initialize. The "Stops" above work like breakpoints. When it gets to the first one, hover your mouse over the variable "fy" and you'll see this:

    View Full Size

    One thing that I'd like for you to remember is that the culture for dates are different here than they are there; don't let that confuse you though - an instant in time is represented in a DateTime instance without regard to how it's displayed.

    Notice please that the FiscalEndDate has a time value of one second before midnight on that date. The fiscal year is 365(6) days long minus one second - at least that's what I have it set as. You may or may not be dealing with the time portion of DateTime in this but *just in case you do*, that should have it covered.

    To get the "data" for a particular date that's in the internal collection, I set up the "Day" method that uses a DateTime instance as a parameter. Continue your program and let's see the data for March 12 of this year. Hover your mouse over "instance" and you'll see this:

    View Full Size

    *****

    When you get back to this, let me know what you think so far and if you have questions about it then ask and we'll go from there. :)


    "A problem well stated is a problem half solved.” - Charles F. Kettering




    • Edited by Frank L. Smith Thursday, August 17, 2017 8:18 PM ...typos
    • Marked as answer by Gary Simpson Saturday, August 26, 2017 2:32 PM
    Thursday, August 17, 2017 8:08 PM
  • Hi Frank 

    I have downloaded And Viewed. And from what I see, It Does look good. Here are some of my screen shots of Your Program...

    T

    Thank you very much for your help Frank. And for taking the time and trouble...


    Gary Simpson

    Thursday, August 17, 2017 9:16 PM
  • Hi Frank 

    I have downloaded And Viewed. And from what I see, It Does look good.

    Let's talk more tomorrow.

    With this as a starting point you can set it up to do what you want. :)


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Thursday, August 17, 2017 9:21 PM
  • I would suggest using NodaTime library (install from Visual Studio via NuGet package manager) which does one thing, work with date/time.

    Imports NodaTime
    Imports NodaTime.Calendars
    Module Module1
        Sub Main()
            '
            ' You can use a DateTimePicker to get the date-time
            '
            Dim currentDate = Now
            Dim someDate As New LocalDate(currentDate.Year, currentDate.Month, currentDate.Day)
            ' set the rule for using methods in the library
            Dim rule As IWeekYearRule = WeekYearRules.Iso
            Console.WriteLine($"WeekOfWeekYear: {rule.GetWeekOfWeekYear(someDate)}")
            Console.ReadLine()
        End Sub
    
    End Module
    
    

    Validate https://weeknumber.net/


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Friday, August 18, 2017 11:26 AM
    Moderator
  • Gary,

    Yesterday you seemed to be a bit confused about adding a reference and what the purpose of an Imports statement is, etc.. When you get a few minutes, this is short review of those topics:

    https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/program-structure/references-and-the-imports-statement

    Do you understand how to use this new assembly in your own program, etc.? Let me know if you have any questions about it all.

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, August 18, 2017 1:12 PM
  • Gary,

    Yesterday you seemed to be a bit confused about adding a reference and what the purpose of an Imports statement is, etc.. When you get a few minutes, this is short review of those topics:

    https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/program-structure/references-and-the-imports-statement

    Do you understand how to use this new assembly in your own program, etc.? Let me know if you have any questions about it all.

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Frank, 

    Let me give you a sample of how I see It. Lets say there is a house with many rooms, and in the center of the house is a room called (Program) And if I want certain information on how I want it processed, I would go to  another room in the house "Called" (Reference), And get the information, then take that information back to the room (Program) And use that Information. and once finished with Said Information, Put it back into the room called (Reference)

    Sorry it's a bit childish the way I explained on how I see it...

    Basically I import from reference with an Alias Name (What ever I have named It in the Class/Module) then call the name in that Module..

    Tell me if I am wrong...

    Gary 


    Gary Simpson

    Friday, August 18, 2017 2:22 PM

  • Frank, 

    Let me give you a sample of how I see It. Lets say there is a house with many rooms, and in the center of the house is a room called (Program) And if I want certain information on how I want it processed, I would go to  another room in the house "Called" (Reference), And get the information, then take that information back to the room (Program) And use that Information. and once finished with Said Information, Put it back into the room called (Reference)

    Sorry it's a bit childish the way I explained on how I see it...

    Basically I import from reference with an Alias Name (What ever I have named It in the Class/Module) then call the name in that Module..

    Tell me if I am wrong...

    Gary 


    Gary Simpson

    That's a reasonable analogy. Do understand that an Imports statement is never ever needed. It's helpful to reduce typing (especially if you include an alias), but that's all it is. You can always fully-qualify methods, properties and other members that you want to use.

    The reference has to be there first though; if it's not then you'll get a compile error like you saw yesterday before I uploaded the zip file.

    In that example program, in Solution Explorer, double-click "My Project" for the test program and then click on the References tab. You'll see the reference has been added - that's the part that I'm not sure you're following?

    Do you understand how you'd use it in your own program and what to do for distribution?


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Friday, August 18, 2017 2:38 PM ...added screenshot
    Friday, August 18, 2017 2:29 PM

  • Frank, 

    Let me give you a sample of how I see It. Lets say there is a house with many rooms, and in the center of the house is a room called (Program) And if I want certain information on how I want it processed, I would go to  another room in the house "Called" (Reference), And get the information, then take that information back to the room (Program) And use that Information. and once finished with Said Information, Put it back into the room called (Reference)

    Sorry it's a bit childish the way I explained on how I see it...

    Basically I import from reference with an Alias Name (What ever I have named It in the Class/Module) then call the name in that Module..

    Tell me if I am wrong...

    Gary 


    Gary Simpson

    That's a reasonable analogy. Do understand that an Imports statement is never ever needed. It's helpful to reduce typing (especially if you include an alias), but that's all it is. You can always fully-qualify methods, properties and other members that you want to use.

    The reference has to be there first though; if it's not then you'll get a compile error like you saw yesterday before I uploaded the zip file.

    In that example program, in Solution Explorer, double-click "My Project" for the test program and then click on the References tab. You'll see the reference has been added - that's the part that I'm not sure you're following?

    Do you understand how you'd use it in your own program and what to do for distribution?


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    Yes my References Looks like Yours Picture


    Gary Simpson

    Friday, August 18, 2017 2:48 PM

  • Yes my References Looks like Yours Picture


    Gary Simpson

    Ok, in the picture please notice that "Copy Local" is true. If it's not, please change it but it should be set that way.

    When you go to distribute your application, make sure that .dll file ("GA.dll") is distributed also or it your program won't even start good before you'll see an exception.

    This is true no matter if it's my assembly or any other third-party assembly. You can also merge it with your application's .exe, but that's another discussion for another time. ;-)


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, August 18, 2017 2:52 PM

  • Gary Simpson

    Friday, August 18, 2017 2:56 PM

  • Gary Simpson

    Ok, good then.

    Let me know if you have any questions.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, August 18, 2017 3:08 PM
  • Hi Gary,

    Do you resolve the issue, if yes, could you please share your solution and mark it as answer, or mark helpful reply as answer, it will be beneficial to other communities who have the similar issue.

    if not, please provide a more information and feel free let us know.

    Best regards,

    Cole


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, August 25, 2017 6:05 AM
    Moderator