Crib Sheets
Home Page
Calculator
Chemistry
Convert Units
Electronic
First Aid
Geography
Geology
Mathematics
Music
Nautical
Numbers
Physics
VB.net Programming
Dates Date Example Maths Text Numeric Textbox

Weather
Web Programming
Wiring
DigitalDan Websites
DigitalDan Sites
Hit Counter 168
 
©2000-2013 DigitalDan.co.uk
 
Contact Details
Email address scroller
DigitalDan.uk
VB.NET Handling Dates

 
The functions outlined below are written in VB.net but it should be possible to modify them for other computer languages.
    ' Set a date to midday
    ' when comparing just the date of a DateTime, it is often
    ' best to ensure hours,minutes,seconds match
    Public Function midday(dat As Date) As Date
        Return New Date(dat.Year, dat.Month, dat.Day, 12, 0, 0)
    End Function


' The ISO standard Week Number can be different to the ' week number returned by some built-in routines. ' During part of first week of year and part of last week of year ' it is possible for the year of in ISO week date not to match the ' year of the normal day,month,year date. Public Function GetISOWeek(dat As Date) As ISOwwyyyy Dim cal As Globalization.Calendar = Globalization.CultureInfo.InvariantCulture.Calendar Dim d As DayOfWeek = cal.GetDayOfWeek(dt) Dim ddd As Integer = dat.DayOfYear Dim yyyy As Integer = dat.Year Dim ret As ISOwwyyyy = New ISOwwyyyy If (d >= DayOfWeek.Monday) AndAlso (d <= DayOfWeek.Wednesday) Then dat = dat.AddDays(3) End If ret.week = cal.GetWeekOfYear(dat, Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) If ((ret.week < 2) And (ddd > 300)) Then yyyy = yyyy + 1 End If If ((ret.week > 50) And (ddd < 60)) Then yyyy = yyyy - 1 End If ret.year = yyyy Return ret End Function
This Function will require use of the following structure
Structures can be placed at the end of a page AFTER the End Class
Public Structure ISOwwyyyy
    Dim week As Integer
    Dim year As Integer
End Structure
Here is an example of how to use this function
Dim ISO as ISOwwyyyy = New ISOwwyyyy
Dim dat as Date = now
ISO = GetISOWeek(dat)
Dim ISOweek, ISOyear as integer
ISOweek = ISO.week
ISOyear = ISO.year


' supply the year and get the date of "western" Easter Sunday ' This is the date used in the UK but some countries ' use a diffierent formula for Coptic or Orthodox Easter. Public Function easter(ByVal yyyy As Integer) As Date Dim a, b, c, d, e, f, g, h, i, k, l, m, mm, dd As Integer a = yyyy Mod 19 b = yyyy \ 100 c = yyyy Mod 100 d = b \ 4 e = b Mod 4 f = (b + 8) \ 25 g = (b - f + 1) \ 3 h = (19 * a + b - d - g + 15) Mod 30 i = c \ 4 k = c Mod 4 l = (32 + 2 * e + 2 * i - h - k) Mod 7 m = (a + 11 * h + 22 * l) \ 451 mm = (h + l - 7 * m + 114) \ 31 dd = ((h + l - 7 * m + 114) Mod 31) + 1 Return New Date(yyyy, mm, dd, 12, 0, 0) ' returned value is Western Easter date valid for all years after 1600 ' things get complicated before 1600 e.g. change from Julian to Gregorian calendar ' This is a fairly standard function, well documented on the internet. ' Some computer languages e.g. PHP have a "built-in" function for Easter. End Function
' This function gets the date of all Public (Bank) holidays ' in England and Wales. (Could easily be adapted for Scotland, ' Ireland or Northern Ireland.) ' It uses the easter function that I have just provided. ' You must also include the structure described at the end of this section. Public Function bankHolidays(yyyy As Integer) As List(Of dateName) Dim ret As List(Of dateName) = New List(Of dateName) Dim dat As Date Dim dn As dateName = New dateName ret.Clear() ' new years day dat = New Date(yyyy, 1, 1, 12, 0, 0) While isWeekend(dat) dat = dat.AddDays(1) End While dn.dat = dat dn.nam = "New Years Day Public Holiday" ret.Add(dn) ' mayday dat = firstMonday("first", "monday", (yyyy * 100) + 5) dn.dat = midday(dat) dn.nam = "May Day Public Holiday" ret.Add(dn) ' spring dat = firstMonday("last", "monday", (yyyy * 100) + 5) dn.dat = midday(dat) dn.nam = "Spring Public Holiday" ret.Add(dn) ' summer dat = firstMonday("last", "monday", (yyyy * 100) + 8) dn.dat = midday(dat) dn.nam = "Summer Public Holiday" ret.Add(dn) ' good friday dat = easter(yyyy).AddDays(-2) dn.dat = midday(dat) dn.nam = "Good Friday Public Holiday" ret.Add(dn) ' easter monday dat = easter(yyyy).AddDays(1) dn.dat = midday(dat) dn.nam = "Easter Monday Public Holiday" ret.Add(dn) ' christmas day dat = New Date(yyyy, 12, 25, 12, 0, 0) While isWeekend(dat) dat = dat.AddDays(1) End While dn.dat = midday(dat) dn.nam = "Christmas Day Public Holiday" ret.Add(dn) ' boxing day dat = dat.AddDays(1) While isWeekend(dat) dat = dat.AddDays(1) End While dn.dat = midday(dat) dn.nam = "Christmas Day Public Holiday" ret.Add(dn) Return ret End Function Public Function isWeekend(ByVal dat As Date) As Boolean Dim answer As Boolean = False If ((dat.DayOfWeek = DayOfWeek.Saturday) Or (dat.DayOfWeek = DayOfWeek.Sunday)) Then answer = True End If Return answer End Function Public Function firstMonday(ByVal first As String, ByVal monday As String, ByVal yyyymm As Integer) As Date Dim dayWeek As DayOfWeek Dim dd, mm, yyyy As Integer yyyy = (Int(yyyymm / 100)) Mod 10000 mm = yyyymm Mod 100 first = Trim(LCase(first)) + " " first = Mid(first, 1, 2) monday = Trim(LCase(monday)) + " " monday = Mid(monday, 1, 2) Select Case first Case "fi" : dd = 1 Case "se" : dd = 8 Case "th" : dd = 15 Case "fo" : dd = 22 Case "la" : dd = 31 Case Else : dd = 1 : first = "fi" End Select dayWeek = text2DayOfWeek(monday) If first = "la" Then dd = Date.DaysInMonth(yyyy, mm) Dim dat As Date = New Date(yyyy, mm, dd) While dat.DayOfWeek <> dayWeek dat = DateAdd(DateInterval.Day, -1, dat) End While Return dat Else Dim dat As Date = New Date(yyyy, mm, dd) While dat.DayOfWeek <> dayWeek dat = DateAdd(DateInterval.Day, 1, dat) End While Return midday(dat) End If End Function Public Function text2DayOfWeek(ByVal text As String) As DayOfWeek Dim DoW As DayOfWeek text = Mid(text & " ", 1, 2).ToLower Select Case text Case "su" : DoW = DayOfWeek.Sunday Case "mo" : DoW = DayOfWeek.Monday Case "tu" : DoW = DayOfWeek.Tuesday Case "we" : DoW = DayOfWeek.Wednesday Case "th" : DoW = DayOfWeek.Thursday Case "fr" : DoW = DayOfWeek.Friday Case Else : DoW = DayOfWeek.Saturday End Select Return DoW End Function ' - - - - ' This structure is inserted after "End Class" Public Structure dateName Dim dat As Date Dim nam As String End Structure
' This function tests a date to see if it is a valid date. ' .NET will often "accept" a bad date, making it safe by converting it to a permissable value ' There are times when you need to know that a user has entered an invalid date. ' The isLeapYear function called within this section can be found in the next section. Private Function isValidDate(yyyy As Integer, mm As Integer, dd As Integer) As Boolean Dim febmax As Integer = 28 If ((yyyy < 2000) Or (yyyy > 2399)) Then Return False If ((mm < 1) Or (mm > 12)) Then Return False If ((dd < 1) Or (dd > 31)) Then Return False If ((mm = 1) Or (mm = 3) Or (mm = 5) Or (mm = 7) Or (mm = 8) Or (mm = 10) or (mm = 12) Then Return True If ((mm <> 2) And (dd <= 30)) Then Return True If isLeapyear(yyyy) Then febmax = 29 Else febmax = 28 If dd > febmax Then Return False Return True End Function
' This function correctly identifies all leap years from start of ' Gregorian calendar until many centuries into the future. ' Some programs dis not identify year 2000 correctly - this function ' correctly establishes that it was a leap-year because the year ' is anexact multiple of 400. Public Function isLeapyear(yyyy As Integer) Dim ret As Boolean = True If yyyy Mod 4 <> 0 Then Return False If yyyy Mod 400 = 0 Then Return True If yyyy Mod 100 = 0 Then Return False Return True End Function
' This function converts a normal western Gregorian Date to a Chinese date ' WARNING - I am not an expert on LuniSolar Calendars. This is intended ' to help someone get started with calendar conversions but it may not ' be complete or accurate. ' If you try this and are familiar with the chinese calendar, please ' let me know whether it works. ' Notes on Chinese Lunar-Solar Calendar dates. The Chinese Calendar ' can "repeat a month" in a similar concept to our Feb 29 Leap Day. ' The leap month can be any of the 12 normal months. In a normal ' year, .NET expects 12 months but there are 13 months in a leap year. ' The Chinese will name years according to a 60 year cycle but ' you often see just the "Animal" part of a year name quoted. ' The Chinese months also have names. Public Function greg2chinese(dat As Date) As chinaDate Dim dc As New System.Globalization.ChineseLunisolarCalendar() Dim china As chinaDate = New chinaDate Dim month(12) As String month = "x,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig,Rat,Ox".Split(",") Dim animal(12) As String animal = "Monkey,Rooster,Dog,Pig,Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Sheep,Monkey".Split(",") Dim element(8) As String element = "Metal,Metal,Water,Water,Wood,Wood,Fire,Fire,Earth,Earth,Metal".Split(",") Dim colour(10) As String colour = "White,White,Black,Black,Green,Green,Red,Red,Brown,Brown,White".Split(",") Dim yangYin(2) As String yangYin = "Yang,Yin,Yang".Split(",") china.yyyy = dc.GetYear(dat) china.mm = dc.GetMonth(dat) china.isLeapMonth = False china.isLeapMonth = dc.IsLeapMonth(dc.GetYear(dat), dc.GetMonth(dat)) Dim lm As Integer = dc.GetLeapMonth(china.yyyy) If lm > 0 Then If dc.GetLeapMonth(dc.GetYear(dat)) <= dc.GetMonth(dat) Then china.mm -= 1 End If End If china.dd = dc.GetDayOfMonth(dat) china.month = month(china.mm) china.animal = animal(china.yyyy Mod 12) china.element = element(china.yyyy Mod 10) china.colour = colour(china.yyyy Mod 10) china.yangYin = yangYin(china.yyyy Mod 2) Return china End Function
This uses this structure
Public Structure chinaDate
    Dim dd As Integer
    Dim mm As Integer
    Dim yyyy As Integer
    Dim isLeapMonth As Boolean
    Dim month As String
    Dim colour As String
    Dim element As String
    Dim animal As String
    Dim yangYin As String
End Structure

' This converts a chinese date to a western gregorian date
' WARNING - I am not an expert on LuniSolar Calendars. This is intended
' to help someone get started with calendar conversions but it may not
' be complete or accurate. 
' If you try this and are familiar with the Chinese calendar, please
' let me know whether it works.
' It always expects a month number in the range 1 to 12. 
' (.NET often uses months 1-13 when a year has a leap-month.)
' In a leap-year, the only way to decide between normal-month and the
' "Leap Month" reoccurence of that month is the CLeapMonth flag.)
Public Function chinese2greg(Cyyyy As Integer, Cmm As Integer, Cdd As Integer, Optional CLeapMonth As Boolean = True) As Date
    Dim ChinaCalendar As System.Globalization.ChineseLunisolarCalendar = New System.Globalization.ChineseLunisolarCalendar
    Dim dc As New Globalization.ChineseLunisolarCalendar()
    ' when there is a leapmonth, .net expects you to add one to all months on/after leapmonth
    ' .net also reports leap month as the month folowing the expected month number
    Dim leapmonth As Integer = dc.GetLeapMonth(Cyyyy)
    ' if no leap month then just get the date
    If leapmonth <= 0 Then Return New Date(Cyyyy, Cmm, Cdd, ChinaCalendar)
    ' remember - according to .net leapmonth shows as as normal month + 1 (not normal month again)
    leapmonth -= 1
    ' if before the leap month then just get the date (but remember leap-month is normal-month + 1 according to .net
    If Cmm < leapmonth Then Return New Date(Cyyyy, Cmm, Cdd, ChinaCalendar)
    ' if we are showing a possible leapmonth then use CLeapMonth to decide whether prime month or leap month required
    If (Cmm = leapmonth) Then
        If CLeapMonth Then
            Return New Date(Cyyyy, Cmm + 1, Cdd, ChinaCalendar)
        Else
            Return New Date(Cyyyy, Cmm, Cdd, ChinaCalendar)
        End If
    End If
    ' if we get here we are showing a month after the leap month and must add 1 to month to keep .net happy
    Return New Date(Cyyyy, Cmm + 1, Cdd, ChinaCalendar)
End Function


DigitalDan.uk is part of the DigitalDan.co.uk group