How does the DateAdd function in ASP Classic work with the "ww" weeks option? - vbscript

I have to replicate functionality in C# from an old asp classic codebase.
The codebase seems to assume that the year can have up to 54 weeks and uses the DateAdd method with the "ww" option to figure out the "week ID" for purposes of categorising some files.
All of the online documentation I have found seems to ignore this question and a straightforward reading of it suggests that adding weeks is the same as adding (weeks * 7) days, however, I don't want to break backwards compatibility. I think that the old code has an off by one error but I don't want to assume it. It's possible for a year to have its days in 54 different weeks but I don't think that doing a DateAdd with a value greater than 52 ever makes sense.
My question is, how does the
DateAdd("ww", x, date)
work?
Is it the equivalent of
date.AddDays(7 * x)
in C#?
Are there edge cases where the first of January falls on (for example) a Saturday and DateAdd("ww", 53, date) could return a valid date in the same year?

I can tell you that DateAdd("ww", i, date) is equivalent to DateAdd("d", 7*i, date); therefore, provided that both functions in C# and vbScript have the same meaning, they must be equivalent.
To ensure DateAdd("ww", i, date) is equivalent to DateAdd("d", 7*i, date) I used the script bellow, it cycles 2 years and for each day, it cycles for 104 weeks if adding days or adding weeks mismatch somehow, it raises an error.
date0 = Date()
For i = 0 to 2 * 365
date1 = DateAdd("d", i, date0)
For j = 0 to 2 * 53
date2 = DateAdd("d", j * 7, date1)
date3 = DateAdd("WW", j, date1)
assert = DateDiff("s", date2, date3)
If assert <> 0 Then
errMsg = _
"OPS addDays And addWeeks unmatched" &_
vbCrLf &_
CStr(date1) & vbTab &_
CStr(date2) & vbTab &_
CStr(date3) & vbTab &_
assert & vbTab
Call Err.Raise(vbObjectError + 10, "Test DateAdd(""ww"", i, date)", errMsg)
End If
Next
Next
So I guess you can use date.AddDays(7 * x) to replace DateAdd("ww", x, date) with no concerns in mismatching dates.

Related

DateSerial overflow with dates greater than 17/09/2059

I am currently working on a VB6 project that handles event data transmit by UK rail stock. Occasionally the trains 'gets confused' about the date and will transmit events dated wildly in the future, I have seen events dated as far as 2088. The date is transmit as Unix time (seconds from 1/1/1970).
I understand what the issue is, i am just struggling to find a solution. The issue appears to be when the date exceeds '17/09/2059' it overflows the integer used for the 'day' that DateSerial can handle. The code below is the line where the overflow occurs, so when 'intDays+1' is > 32767.
UnixTimestampToDateTime = DateSerial(1970, 1, intDays + 1) + TimeSerial(intHours, intMins, CInt(intSecs))
The goal is to convert Unix time into the following format "dd/mm/yyyy hh:mm:ss". Can i get DateSerial to work beyond this date limitation or do i need to completely change how i calculate the date? Any help would be appreciated. Cheers.
You could initialize your result to 01/01/1970 and then add the required seconds:
Dim unix_time As Currency
Dim max_long As Long
Dim result As Variant
' Determine unix time
unix_time = .....
' Initialize result to 01/01/1970 00:00:00
result = DateSerial(1970, 1, 1) + TimeSerial(0, 0, 0)
' Determine maximum number of seconds we can add in a single call
max_long = 2147483647
' Add desired time
While unix_time > max_long
result = DateAdd("s", max_long, result)
unix_time = unix_time - max_long
Wend
result = DateAdd("s", CLng(unix_time), result)
Actually it is quite trivial to come up with a replacement version of DateSerial that accepts Long for days, e.g. try this:
Private Function MyDateSerial(ByVal Year As Integer, ByVal Month As Integer, ByVal Day As Long)
MyDateSerial = DateSerial(Year, Month, 1) + Day - 1
End Function
Here is a simple use-case to test it
Debug.Print MyDateSerial(1970, 1, 30000), DateSerial(1970, 1, 30000)
19.2.2052 19.2.2052

Dim Leap Year, VBScript

I have a series of Ratios calculated in VBScript which incorporates the total days in the year. For 2016 we need to utilize "366" days instead of the normal "365."
I created a Dim variable to populate based on the year, but it's clear the script isn't working and instead zeros out.
VBScript:
'/ Adding YrDays to account for Leap Years'/
If POV_Year = "2012" OR "2016" OR "2020" OR "2024" OR "2028" Then
YrDays = "366"
Else YrDays = "365"
End If
HS.Exp "A#Ratio007.C1#[None]" & DynC1 & " =
((A#Tohinc" & Tops & " * (YrDays / A#numberdays.E#PVTB Admin))
/ (A#Totass" & Tops &")) * 100"
When I upload the Business Rules into Oracle HFM, the VBScript uploads without errors but fails to calculate the ratio.
There is no account in HFM for YrDays as I want to calculate the value (YrDays) during the consolidation and calculation. I've verified POV_Year, Numberdays, and other values are loading properly.
Any idea what I might be doing wrong?
Software:
Oracle HFM 11.1.2.3.500
VBScript Rule.rle file editing in Notepad++
Edit:
This is the solution I went with:
'/ Adding YrDays to account for Leap Years'/
SELECT CASE POV_YEAR
CASE "2012", "2016", "2020", "2024", "2028"
YrDays = 366
Case Else
YrDays = 365
End Select
I also needed to change the way YrDays was referenced in the formula, I should have known it needed to be in Quotation marks to be referenced in the calculation.
HS.Exp "A#Ratio007.C1#[None]" & DynC1 & " =
((A#Tohinc" & Tops & " * ("& YrDays & "/ A#numberdays.E#PVTB Admin))
/ (A#Totass" & Tops &")) * 100"
Your code might be better as a Select Case statement.
Select Case POV_Year
Case 2012, 2016, 2020, 2024, 2028
YrDays = 366
Case Else
YrDays = 365
End Select
However, there may be an easier method.
'/ Adding YrDays to account for Leap Years'/
YrDays = DateSerial(POV_Year + 1, 1, 1) - DateSerial(POV_Year, 1, 1)
'alternate
YrDays = 365 - (POV_Year = 2012 Or POV_Year = 2016 Or POV_Year = 2020 Or POV_Year = 2024 Or POV_Year = 2028)
I've remove the quoted numbers; numbers should stay as numbers. However "2016" does not equal 2016 so you might have to put them back or adjust the remainder of your code. You can concatenate a true number into a string.

How to find the week number of a given date in Visual Basic 6?

Has anyone a working function that returns the week number of a given date in vb6?
This used to work:
Dim W As Integer
W = Format(DateSerial(2010, 1, 1), "ww", vbMonday, vbFirstFourDays)
But in Windows 8.1 you now get "Out of stack space".
The answer is a bit more complex given the offsets
The following function should work well for what you need. Simply pass it a valid Date object, and it will return an Integer of the Week number.
Private Function Week(dteValue As Date) As Integer
'Monday is set as first day of week
Dim lngDate As Long
Dim intWeek As Integer
'If january 1. is later then thursday, january 1. is not in week 1
If Not Weekday("01/01/" & Year(dteValue), vbMonday) > 4 Then
intWeek = 1
Else
intWeek = 0
End If
'Sets long-value for january 1.
lngDate = CLng(CDate("01/01/" & Year(dteValue)))
'Finds the first monday of year
lngDate = lngDate + (8 - Weekday("01/01/" & Year(dteValue), vbMonday))
'Increases week by week until set date is passed
While Not lngDate > CLng(CDate(dteValue))
intWeek = intWeek + 1
lngDate = lngDate + 7
Wend
'If the date set is not in week 1, this finds latest week previous year
If intWeek = 0 Then
intWeek = Week("31/12/" & Year(dteValue) - 1)
End If
Week = intWeek
End Function
This code is courtesy of FreeVBCode.com (included a reference to give attribute to the original author).

Having the day value of date start with 0

I am editing a VBScript so it will take yesterdays date add a string to the front off it and search for that file before moving it to a folder.
sDate = day(date)-1
sName= "Blaa" & "_" & sDate
Using the above bits of code I would get a result - Blaa_10 or Blaa_9
The issue is the files, I want it to search for when under 10 would be named as Blaa_09.
Is there anyway I can format the value day so when it is under 10 it starts with 0? Think I could write an If statement to do this but was hoping there is another way.
The canonical way to left-pad a day of month with a zero in VBScript looks like this:
Right("0" & Day(Date), 2)
Just went with
sDay = day(date) -1
IF sDay < 10 Then
sDate = "0"& sDay & monthname(month(DateAdd("m",-1,Date)), True) & year(date)
WScript.Echo "Date = " & sDate
This worked fine, if anyone has an easier way please feel free to share.

Clarification needed in VB Script for performing some day calculations

I am currently working on defining workflow scripts in HP Application Lifecycle management tool using VB Script.
My problem is I have to generate an Excel chart for calculating the efforts put on by various developers in a particular Sprint(timeframe). In process of generating the same my condition is to eliminate the weekend dates(ie., Saturday and Sunday) from the chart. If the Sprint startdate falls on a weekend the date shoud automatically be initialized to the next immediate monday and if the Sprint End date falls on a weekend the end date should be displayed as the Friday that just passed. I have validated these two conditions. I am trying to shave off the Saturday and Sundays that come inbetween these two days. Please help me on the same. Also please let me know if you need any inputs from my side.
#Sabaresh, I believe this is what you are looking for.
Tip: See this answer for information on downloading Microsoft's authoritative WSH reference as a Windows help file.
Option Explicit
Dim dCandidateDate, dActualStartDate, dActualEndDate
dCandidateDate = CDate("2012/08/18")
dActualStartDate = SprintStartDate(dCandidateDate)
dCandidateDate = CDate("2012/09/16")
dActualEndDate = SprintEndDate(dCandidateDate)
WScript.Echo "Sprint date range: " _
& dActualStartDate & " through " & dActualEndDate
'
' Return following Monday if dCandidateDate is
' Saturday or Sunday.
'
Function SprintStartDate(dCandidateDate)
Dim nWeekday : nWeekday = DatePart("w", dCandidateDate)
Select Case nWeekday
Case 7 ' Saturday
SprintStartDate = DateAdd("d", 2, dCandidateDate)
Case 1 ' Sunday
SprintStartDate = DateAdd("d", 1, dCandidateDate)
Case Else
SprintStartDate = dCandidateDate
End Select
End Function
'
' Return previous Friday if dCandidateDate is
' Saturday or Sunday.
'
Function SprintEndDate(dCandidateDate)
Dim nWeekday : nWeekday = DatePart("w", dCandidateDate)
Select Case nWeekday
Case 7 ' Saturday
SprintEndDate = DateAdd("d", -1, dCandidateDate)
Case 1 ' Sunday
SprintEndDate = DateAdd("d", -2, dCandidateDate)
Case Else
SprintEndDate = dCandidateDate
End Select
End Function

Resources