Date Related Functions
This page provides a set of handy date related functions. I have also included some date-realated debugging tips at the end of this page.If your compiler complains that the function should be static, you can add the word "Shared" after the word "Function". (You cannot have shared functions inside modules.) (If the compiler wants shared once, it will probably expect in for most funstions.)
Public Function ...
would become
Public Shared Function ...
- IsValidDate = Date Validation
- Midday = Sets the time part of a date to 12:00
- DateOnlyCompare = Compare two dates (ignoring the time) = returns -1, 0, 1 for <, =, >
- Today = Returns todays date (at 12:00)
- IsLeapYear = Does the year have 29 days in February?
- DaysInMonth = Returns number of days in any month
- DayName = Returns weekday name in current language
- MonthName = Returns month name in current language
- DayOfWeekToString = Convert DayOfWeek Enum to name in current language
- MonthNumberToName = Converts month number to name in current language
- NearestWeekday = Find nearest Weekday (Mon-Fri) to a date
- WeekdayOnOrAfter = Find first Weekday (Mon-Fri) on or after a date
- IsWeekend = Is a date on a Saturday or Sunday
- IsWeekday = Is a date on Mon, Tue, Wed, Thu or Fri
- ClocksForwardUK = Get date for start of UK summer time
- ClocksForwardUSA = Get date for start of USA summer time. Some states do not adjust their clocks
- ClocksBackwardUK = Get date for start of UK winter time
- ClocksBackwardUSA = Get date for start of USA winter time. Some states do not adjust their clocks
Public Function IsValidDate(yyyy As Integer, MM As Integer, dd As Integer) As Boolean
If yyyy <= 1752 OrElse yyyy > 2399 OrElse MM < 1 OrElse MM > 12 OrElse dd < 1 Then Return False
' 1752 - approx date UK switched from Julian to Gregorian Calendar
' 2399 - a date that is in the very distant future
Return dd <= Date.DaysInMonth(yyyy, MM)
End Function
Private Function Midday(dat As Date) As Date
' Changing timeOfDay to midday can avoid certain date-change issues
' however, it should only be done when you are sure hours, minutes wont affect results
Return New Date(dat.Year, dat.Month, dat.Day, 12, 0, 0, 0, 0)
End Function
Public Function DateOnlyCompare(dat1 As Date, dat2 As Date) As Integer
' Use when you only want to compare dates
' i.e. ignore hours, minutes, seconds, milliseconds, microseconds
Dim d1 As Integer = (dat1.Year * 10000) + (dat1.Month * 100) + dat1.Day
Dim d2 As Integer = (dat2.Year * 10000) + (dat2.Month * 100) + dat2.Day
If d1 < d2 Then Return -1
If d1 > d2 Then Return 1
Return 0
' -1 result indicates dat1 < dat2
' 0 result indicates dat1 = dat2
' 1 result indicates dat1 > dat2
End Function
Public Function Today() As Date
Dim dat As Date = Now
Return New Date(dat.Year, dat.Month, dat.Day, 12, 0, 0, 0, 0)
End Function
Public Function IsLeapYear(yyyy As Integer) As Boolean
Return Date.IsLeapYear(yyyy)
End Function
Public Function DaysInMonth(yyyy As Integer, mm As Integer) As Integer
Return Date.DaysInMonth(yyyy, mm)
End Function
Public Function DayName(dat As Date, Optional abbreviate As Boolean = True) As String
If abbreviate Then Return dat.ToString("ddd")
Return dat.ToString("dddd")
End Function
Public Function MonthName(dat As Date, Optional abbreviate As Boolean = True) As String
If abbreviate Then Return dat.ToString("MMM")
Return dat.ToString("MMMM")
End Function
Public Function DayOfWeekToString(ByVal DoW As DayOfWeek, Optional ByVal abbreviate As Boolean = False) As String
Dim text As String
text = DoW.ToString
If abbreviate Then text = Mid(text, 1, 3)
Return text
End Function
Public Function MonthNumberToMonthName(num As Integer, Optional abbreviate As Boolean = True) As String
If num < 1 OrElse num > 12 Then Return String.Empty
Dim dat As New Date(2000, num, 15, 12, 0, 0, 0)
If abbreviate Then Return dat.ToString("MMM")
Return dat.ToString("MMMM")
End Function
Public Function NearestWeekday(ByVal dat As Date, ByVal weekday As DayOfWeek) As Date
dat = New Date(dat.Year, dat.Month, dat.Day, 12, 0, 0, 0)
dat = dat.AddDays(-3)
While dat.DayOfWeek <> weekday
dat = dat.AddDays(1)
End While
Return dat
End Function
Public Function WeekdayOnOrAfter(ByVal dat As Date, ByVal weekday As DayOfWeek) As Date
dat = New Date(dat.Year, dat.Month, dat.Day, 12, 0, 0, 0)
While dat.DayOfWeek <> weekday
dat = dat.AddDays(1)
End While
Return dat
End Function
Public Function IsWeekend(dat As Date) As Boolean
Return (dat.DayOfWeek = DayOfWeek.Saturday OrElse dat.DayOfWeek = DayOfWeek.Sunday)
End Function
Public Function IsWeekday(dat As Date) As Boolean
Return Not (dat.DayOfWeek = DayOfWeek.Saturday OrElse dat.DayOfWeek = DayOfWeek.Sunday)
End Function
Public Function ClocksForwardUK(yyyy As Integer) As Date
' rule is 01:00 last Sunday in March
Dim dat As New Date(yyyy, 3, 31, 12, 0, 0, 0, 0)
While dat.DayOfWeek <> DayOfWeek.Sunday
dat = dat.AddDays(-1)
End While
Return New Date(yyyy, 3, dat.Day, 1, 0, 0, 0, 0)
End Function
Public Function ClocksForwardUSA(yyyy As Integer) As Date
' rule is 02:00 second Sunday in March
' some states do not adjust their clocks
Dim dat As New Date(yyyy, 3, 8, 12, 0, 0, 0, 0)
While dat.DayOfWeek <> DayOfWeek.Sunday
dat = dat.AddDays(1)
End While
Return New Date(yyyy, 3, dat.Day, 2, 0, 0, 0, 0)
End Function
Public Function ClocksBackwardUK(yyyy As Integer) As Date
' rule is 02:00 Last Sunday in October
Dim dat As New Date(yyyy, 10, 31, 12, 0, 0, 0, 0)
While dat.DayOfWeek <> DayOfWeek.Sunday
dat = dat.AddDays(-1)
End While
Return New Date(yyyy, 10, dat.Day, 2, 0, 0, 0, 0)
End Function
Public Function ClocksBackwardUSA(yyyy As Integer) As Date
' rule is 02:00 First Sunday in November
' Some states do not adjust their clocks
Dim dat As New Date(yyyy, 11, 1, 12, 0, 0, 0, 0)
While dat.DayOfWeek <> DayOfWeek.Sunday
dat = dat.AddDays(1)
End While
Return New Date(yyyy, 11, dat.Day, 2, 0, 0, 0, 0)
End Function
Some Useful VB.Net Keywords
Dim daysInMonth As Integer = Date.DaysInMonth(dat.Year, dat.Month)
Dim isLeapYear As Boolean = Date.IsLeapYear(dat.Year)
Dim todaysDate As Date = Date.Today ' identical to Dim todaysDate As Date = Now
Dim tomorrow As Date = Date.Today.AddDays(1)
' (1) can be positive or negative, integer or decimal
' AddDays could be AddDays, AddHours, AddMonths, AddMinutes ....
Dim DoW As DayOfWeek = dat.DayOfWeek
Dim DoY As Integer = dat.DayOfYear
Dim isDST As Boolean = dat.IsDaylightSavingTime
Dim LocalDate As Date = dat.ToLocalTime
' .ToLocalTime converts UTC (GMT) to the local time zone and summer/winter time
Dim UTCDate As Date = dat.ToUniversalTime
' .ToUniversalTime converts local date/time to UTC (GMT)
Dim s As String = dat.ToString("?????")
' Convert a Date variable to text that represents the date
' This is very usefull and well documented on many websites
Dim daysBetweenDates As Long = DateDiff(DateInterval.Day, dat1, dat2)
' DateInterval could be .Year .Month .Day .Hour , Minute etc.
' Returns as Long (integer could overflow e.g. .Millisecond when the dates are years apart)
Common Date Related Problems
Date related progam bugs can be difficult to find. The following comments are occassionally helpful
- Many European countries adjust their clocks on last Sunday in March and Last Sunday in October. Many American countries change their clocks on second Sunday in March and first Sunday in November. Time differences could be different during the periods 2nd Sun March to Last Sun March and Last Sun October to 1st Sun November
- .ToString("d") will return a full fomatted date. .ToString with d and other format charaters will return day-of-month
- Unexpected date changes can occur when an hour or minute change pushes a time through Midnight
- Many calemdrical and astrological calculations return their results in UTC time. Converting to local time will probablay affect the time and could change the date
- The Gregorian (modern) Calendar was first introduced in 1582. It took over 200 years for some countries to adopt the new calendar. This means that old historic dates will relate to the previous Julian Calendar.
-
The Gregorian calendar is a mainly Solar calendar (dates based on Sun movements.) Many countries use alternative calendars and these are often
Lunar (dates based on Moon Phases etc.) There are many complications when converting a date from one calendar to another - including
- Many calendars have days that do not start at midnight e.g. Hebrew or Hijri run from about snset to about sunset.
- Some calendars have leap months, leap days, months of varying length, etc.
- Some calendars calculate the date of a "New Moon" to determine the start day of a month or year. The GPS Location used in this calculation could affect the date that the "new moon" is expected.
- Some calendars wait for the new moon to be seen and this "sighting" triggers the new month or year. Factors including adverse weather could affect the sighting. It may not be possible to accurately convert a date until after the appropriate sighting is officially confirmed.
DigitalDan.co.uk