The code you linked to for the timer is very bad because it is trying to use strings in the manipulation of DateTimes - they are very different things.
I created a new Windows Forms application with only a Label named "TimeNow":
Public Class Form1
Friend WithEvents realTime As Windows.Forms.Timer
Private lastAlarmTime As DateTime
Private alarmTimes As List(Of DateTime)
Private displayTime As String
Public Sub DoStuff()
MessageBox.Show("It's already time", "TIME!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub CheckForAnAlarmTime()
Dim dtNow As DateTime = DateTime.Now()
For Each tt In alarmTimes
' the timer interrupt handler is not necessarily called at exact times. Allow for that.
If tt > lastAlarmTime AndAlso tt < dtNow Then
lastAlarmTime = dtNow
DoStuff()
SetAlarmTimes()
Exit For
End If
Next
End Sub
Public Sub realTime_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles realTime.Tick
Dim candidateDisplayTime As String = DateTime.Now.ToString("HH:mm:ss")
' only update the UI if necessary
If candidateDisplayTime <> displayTime Then
displayTime = candidateDisplayTime
TimeNow.Text = displayTime
End If
CheckForAnAlarmTime()
End Sub
Private Sub SetAlarmTimes()
Dim dtNow As DateTime = DateTime.Now()
alarmTimes = New List(Of DateTime)
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 12, 0, 0))
' Recommendation: do not use exactly midnight without extensive testing, i.e. test over day rollover, month rollover, and year rollover.
' With less testing, use a few milliseconds less than midnight.
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0).AddMilliseconds(-50))
End Sub
Private Sub SetUpAlarmsTimer()
SetAlarmTimes()
lastAlarmTime = DateTime.Now()
realTime_Tick(Me, EventArgs.Empty)
realTime = New Windows.Forms.Timer()
realTime.Interval = 200 ' 200ms will update it more accurately w.r.t. visual appearance
AddHandler realTime.Tick, AddressOf realTime_Tick
realTime.Start()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SetUpAlarmsTimer()
End Sub
End Class
Change the alarmTimes to whatever you need to check that the alarm is raised only once per alarmTimes item.
I am not willing to wait until midnight to check if alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0)
without the .AddMilliseconds(-50)
will work as required, or until the end of the month or year to be absolutely sure. And please don't forget about testing around the end of February when it is a leap year.
The reason for checking against the lastAlarmTime is that it is not certain when a timer event will be raised: for a timer set to tick at 1000ms, you might get two events inside one real second, or none inside one real second. Approximately.
EDIT: You might also want to work in UTC to avoid hassle with daylight savings time changes.