<% ' rosy_utilities.asp ' Author: Jim Miller ' Running Average Class Class RunningAverage Private queue Private n_StackSize Private recordCount Private recordIndex Private Sub Class_Initialize() Set queue = CreateObject("System.Collections.ArrayList") n_StackSize = 3 ' Default recordCount = 0 recordIndex = 0 End Sub Public Sub Initialize(stackSize) n_StackSize = stackSize End Sub Public Sub Reset(count) Set queue = CreateObject("System.Collections.ArrayList") recordIndex = 0 recordCount = count End Sub Public Function Update(newValue) Dim total, n_FromEnd, average, i, maxQueueSize total = 0 recordIndex = recordIndex + 1 ' Calculate how many points from the end we are n_FromEnd = recordCount - recordIndex ' Special case for the last point - return raw value If n_FromEnd = 0 Then ' For the last point, just return the raw value Update = newValue ' Still add to queue for completeness queue.Add newValue Exit Function End If ' Add the new value to the queue queue.Add newValue ' For normal processing (not near the end), maintain the standard stack size If n_FromEnd > 1 Then ' Standard case - maintain stack size maxQueueSize = n_StackSize ElseIf n_FromEnd = 1 Then ' Second-to-last point - use 2-point average maxQueueSize = 2 End If ' Trim the queue to the appropriate size While queue.Count > maxQueueSize queue.RemoveAt 0 Wend ' Sum the values For i = 0 To queue.Count - 1 total = total + queue(i) Next ' Calculate the average If queue.Count > 0 Then average = total / queue.Count Else average = 0 End If Update = average End Function Public Function GetRecordIndex() GetRecordIndex = recordIndex End Function Public Function GetQueueCount() GetQueueCount = queue.Count End Function Private Sub Class_Terminate() Set queue = Nothing End Sub End Class ' Running Average for Direction Data Class RunningAverage_Dir Private RA_x Private RA_y Private n_StackSize Private Sub Class_Initialize() n_StackSize = 3 ' Default Set RA_x = New RunningAverage RA_x.Initialize n_StackSize Set RA_y = New RunningAverage RA_y.Initialize n_StackSize End Sub Public Sub Initialize(stackSize) n_StackSize = stackSize Set RA_x = New RunningAverage RA_x.Initialize n_StackSize Set RA_y = New RunningAverage RA_y.Initialize n_StackSize End Sub Public Sub Reset(count) RA_x.Reset count RA_y.Reset count End Sub Public Function Update(newDir_deg) Dim x, y, x_avg, y_avg, averageDir_deg ' Convert degrees to radians and get components x = Cos(newDir_deg * (3.14159265358979 / 180.0)) y = Sin(newDir_deg * (3.14159265358979 / 180.0)) ' Update components x_avg = RA_x.Update(x) y_avg = RA_y.Update(y) ' Calculate average angle averageDir_deg = Atn2(y_avg, x_avg) * (180.0 / 3.14159265358979) ' Ensure positive angles If averageDir_deg < 0 Then Update = averageDir_deg + 360.0 Else Update = averageDir_deg End If End Function Private Sub Class_Terminate() Set RA_x = Nothing Set RA_y = Nothing End Sub End Class ' Helper function for arctangent with correct quadrant Function Atn2(y, x) If x = 0 Then If y > 0 Then Atn2 = 1.5707963267949 ' PI/2 ElseIf y < 0 Then Atn2 = -1.5707963267949 ' -PI/2 Else Atn2 = 0 ' Undefined, but return 0 End If Else If x > 0 Then Atn2 = Atn(y / x) ElseIf x < 0 Then If y >= 0 Then Atn2 = Atn(y / x) + 3.14159265358979 ' PI Else Atn2 = Atn(y / x) - 3.14159265358979 ' -PI End If End If End If End Function Function DaylightSavingsTime(dateToCheck) 'rwbr "in DaylightSavingsTime, dateToCheck: " & dateToCheck ' Implementation for US Daylight Saving Time rules (2007 and later) Dim yearVal, dstStart, dstEnd, dateObj ' Convert string to date if needed If IsDate(dateToCheck) Then If VarType(dateToCheck) = 8 Then ' VT_BSTR (String) dateObj = CDate(dateToCheck) Else dateObj = dateToCheck End If Else ' Invalid date format DaylightSavingsTime = False Exit Function End If yearVal = Year(dateObj) ' Second Sunday in March to First Sunday in November (US rules since 2007) dstStart = GetNthSunday(yearVal, 3, 2) ' 2nd Sunday in March dstEnd = GetNthSunday(yearVal, 11, 1) ' 1st Sunday in November ' Add time component (2am) dstStart = dstStart + TimeSerial(2, 0, 0) dstEnd = dstEnd + TimeSerial(2, 0, 0) 'rwbr "dstStart: " & dstStart & ", dateObj: " & dateObj & ", dstEnd: " & dstEnd ' Check if date is within DST period If dateObj >= dstStart And dateObj < dstEnd Then DaylightSavingsTime = True Else DaylightSavingsTime = False End If 'rwbr "out DaylightSavingsTime, DaylightSavingsTime: " & DaylightSavingsTime End Function ' Helper function to get nth Sunday of a month Function GetNthSunday(year, month, n) Dim firstDay, firstSunday, nthSunday ' Get first day of the month firstDay = DateSerial(year, month, 1) ' Find the first Sunday firstSunday = firstDay + (8 - Weekday(firstDay)) Mod 7 ' Calculate the nth Sunday nthSunday = firstSunday + (n - 1) * 7 GetNthSunday = nthSunday End Function ' Function to instantiate running averages Function InstantiateRunningAverages(traceName) Dim nPoints nPoints = 3 ' Create global objects Set RA_x = New RunningAverage RA_x.Initialize nPoints If traceName = "WindDirection" Then Set RA_y = New RunningAverage_Dir RA_y.Initialize nPoints Else Set RA_y = New RunningAverage RA_y.Initialize nPoints End If End Function %>