vb6parse 1.0.0

vb6parse is a library for parsing and analyzing VB6 code, from projects, to controls, to modules, and forms.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="VB6Parse Library Reference - dateserial - Datetime">
    <title>dateserial - Datetime - VB6Parse Library Reference</title>
    <link rel="stylesheet" href="../../../assets/css/style.css">
    <link rel="stylesheet" href="../../../assets/css/docs-style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
    <script src="../../../assets/js/theme-switcher.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/vbnet.min.js"></script>
    <script>hljs.highlightAll();</script>
</head>
<body>
    <header class="docs-header">
        <div class="container">
            <h1><a href="../../../index.html">VB6Parse</a> / <a href="../../../library/index.html">Library</a> / <a href="../../../library/functions/datetime/index.html">Datetime</a> / dateserial</h1>
            <p class="tagline">VB6 Library Reference</p>
        </div>
    </header>

    <nav class="docs-nav">
        <div class="container">
            <a href="../../../index.html">Home</a>
            <a href="../../../library/index.html">Library Reference</a>
            <a href="../../../documentation.html">Documentation</a>
            <a href="https://docs.rs/vb6parse" target="_blank">API Docs</a>
            <a href="https://github.com/scriptandcompile/vb6parse" target="_blank">GitHub</a>
            <button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
                <span class="theme-icon">🌙</span>
            </button>
        </div>
    </nav>

    <main class="container">
        
        <article class="library-item">
            <h1 id="dateserial-function">DateSerial Function</h1>
<p>Returns a <code>Variant</code> (<code>Date</code>) for a specified year, month, and day.</p>
<h2 id="syntax">Syntax</h2>
<pre><code class="language-vbnet">DateSerial(year, month, day)</code></pre>
<h2 id="parameters">Parameters</h2>
<ul>
<li><strong>year</strong>: Required. <code>Integer</code> expression between 100 and 9999, inclusive, or a numeric
  expression. Values from 0 to 29 are interpreted as 2000-2029; values from 30 to 99
  are interpreted as 1930-1999.</li>
<li><strong>month</strong>: Required. <code>Integer</code> expression from 1 to 12, but can be any numeric expression
  representing months from -32,768 to 32,767. Month values outside 1-12 adjust the year
  accordingly.</li>
<li><strong>day</strong>: Required. <code>Integer</code> expression from 1 to 31, but can be any numeric expression
  representing days from -32,768 to 32,767. Day values outside the valid range adjust
  the month and year accordingly.</li>
</ul>
<h2 id="return-value">Return Value</h2>
<p>Returns a <code>Variant</code> of subtype <code>Date</code> representing the specified date. The time portion
is set to midnight (00:00:00).</p>
<h2 id="remarks">Remarks</h2>
<p>The <code>DateSerial</code> function is used to construct a date value from individual year, month,
and day components. It's particularly useful for date calculations and building dates
programmatically.
<strong>Important Characteristics:</strong>
- Accepts values outside normal ranges and adjusts automatically
- Month values &gt; 12 or &lt; 1 adjust the year
- Day values outside valid range adjust the month
- Can use 0 or negative values for relative date calculations
- Two-digit years: 0-29 → 2000-2029, 30-99 → 1930-1999
- Always returns midnight (00:00:00) for time portion
- Invalid combinations return compile-time or runtime errors</p>
<h2 id="range-adjustment-examples">Range Adjustment Examples</h2>
<pre><code class="language-vbnet">&#x27; Month adjustment
DateSerial(2025, 13, 1)    &#x27; Returns 1/1/2026 (13th month = Jan next year)
DateSerial(2025, 0, 1)     &#x27; Returns 12/1/2024 (0th month = Dec previous year)
DateSerial(2025, -1, 1)    &#x27; Returns 11/1/2024 (month -1 = Nov previous year)
&#x27; Day adjustment
DateSerial(2025, 1, 32)    &#x27; Returns 2/1/2025 (32nd day = Feb 1)
DateSerial(2025, 1, 0)     &#x27; Returns 12/31/2024 (0th day = last day of prev month)
DateSerial(2025, 1, -1)    &#x27; Returns 12/30/2024 (day -1)
&#x27; Combined adjustment
DateSerial(2025, 13, 32)   &#x27; Returns 2/1/2026</code></pre>
<h2 id="examples">Examples</h2>
<h3 id="basic-usage">Basic Usage</h3>
<pre><code class="language-vbnet">&#x27; Create a specific date
Dim birthday As Date
birthday = DateSerial(1990, 5, 15)  &#x27; May 15, 1990
&#x27; Create date from variables
Dim y As Integer, m As Integer, d As Integer
y = 2025
m = 12
d = 25
Dim christmas As Date
christmas = DateSerial(y, m, d)
&#x27; Current year&#x27;s date
Dim thisYear As Date
thisYear = DateSerial(Year(Date), 1, 1)  &#x27; January 1 of current year</code></pre>
<h3 id="last-day-of-month">Last Day of Month</h3>
<pre><code class="language-vbnet">Function GetLastDayOfMonth(year As Integer, month As Integer) As Date
    &#x27; Use day 0 of next month to get last day of current month
    GetLastDayOfMonth = DateSerial(year, month + 1, 0)
End Function
&#x27; Usage
Dim lastDay As Date
lastDay = GetLastDayOfMonth(2025, 2)  &#x27; Feb 28, 2025 (or 29 in leap year)</code></pre>
<h3 id="first-day-of-month">First Day of Month</h3>
<pre><code class="language-vbnet">Function GetFirstDayOfMonth(someDate As Date) As Date
    GetFirstDayOfMonth = DateSerial(Year(someDate), Month(someDate), 1)
End Function</code></pre>
<h2 id="common-patterns">Common Patterns</h2>
<h3 id="month-boundaries">Month Boundaries</h3>
<pre><code class="language-vbnet">Function GetMonthStart(someDate As Date) As Date
    GetMonthStart = DateSerial(Year(someDate), Month(someDate), 1)
End Function
Function GetMonthEnd(someDate As Date) As Date
    GetMonthEnd = DateSerial(Year(someDate), Month(someDate) + 1, 0)
End Function
&#x27; Get entire month range
Dim startDate As Date
Dim endDate As Date
startDate = GetMonthStart(Date)
endDate = GetMonthEnd(Date)</code></pre>
<h3 id="year-boundaries">Year Boundaries</h3>
<pre><code class="language-vbnet">Function GetYearStart(someDate As Date) As Date
    GetYearStart = DateSerial(Year(someDate), 1, 1)
End Function
Function GetYearEnd(someDate As Date) As Date
    GetYearEnd = DateSerial(Year(someDate), 12, 31)
End Function</code></pre>
<h3 id="quarter-boundaries">Quarter Boundaries</h3>
<pre><code class="language-vbnet">Function GetQuarterStart(year As Integer, quarter As Integer) As Date
    Dim month As Integer
    month = (quarter - 1) * 3 + 1
    GetQuarterStart = DateSerial(year, month, 1)
End Function
Function GetQuarterEnd(year As Integer, quarter As Integer) As Date
    Dim month As Integer
    month = quarter * 3
    GetQuarterEnd = DateSerial(year, month + 1, 0)
End Function</code></pre>
<h3 id="add-months-correctly">Add Months Correctly</h3>
<pre><code class="language-vbnet">Function AddMonths(startDate As Date, months As Integer) As Date
    Dim y As Integer, m As Integer, d As Integer
    y = Year(startDate)
    m = Month(startDate)
    d = Day(startDate)
    &#x27; Add months (DateSerial handles overflow)
    AddMonths = DateSerial(y, m + months, d)
End Function
&#x27; Handle day overflow gracefully
Function AddMonthsSafe(startDate As Date, months As Integer) As Date
    Dim y As Integer, m As Integer, d As Integer
    Dim lastDay As Date
    y = Year(startDate)
    m = Month(startDate)
    d = Day(startDate)
    &#x27; Get last day of target month
    lastDay = DateSerial(y, m + months + 1, 0)
    &#x27; Use smaller of original day or last day of month
    If d &gt; Day(lastDay) Then
        d = Day(lastDay)
    End If
    AddMonthsSafe = DateSerial(y, m + months, d)
End Function</code></pre>
<h3 id="leap-year-detection">Leap Year Detection</h3>
<pre><code class="language-vbnet">Function IsLeapYear(year As Integer) As Boolean
    Dim feb29 As Date
    On Error Resume Next
    feb29 = DateSerial(year, 2, 29)
    IsLeapYear = (Err.Number = 0)
End Function</code></pre>
<h3 id="days-in-month">Days in Month</h3>
<pre><code class="language-vbnet">Function DaysInMonth(year As Integer, month As Integer) As Integer
    Dim lastDay As Date
    lastDay = DateSerial(year, month + 1, 0)
    DaysInMonth = Day(lastDay)
End Function</code></pre>
<h3 id="birthday-this-year">Birthday This Year</h3>
<pre><code class="language-vbnet">Function GetBirthdayThisYear(birthDate As Date) As Date
    GetBirthdayThisYear = DateSerial(Year(Date), Month(birthDate), Day(birthDate))
End Function
Function HasBirthdayPassed(birthDate As Date) As Boolean
    HasBirthdayPassed = (GetBirthdayThisYear(birthDate) &lt;= Date)
End Function</code></pre>
<h3 id="week-start-monday">Week Start (Monday)</h3>
<pre><code class="language-vbnet">Function GetWeekStart(someDate As Date) As Date
    Dim offset As Integer
    offset = Weekday(someDate, vbMonday) - 1
    GetWeekStart = DateSerial(Year(someDate), Month(someDate), Day(someDate) - offset)
End Function</code></pre>
<h3 id="generate-date-range">Generate Date Range</h3>
<pre><code class="language-vbnet">Function GenerateMonthStarts(year As Integer) As Variant
    Dim dates(1 To 12) As Date
    Dim i As Integer
    For i = 1 To 12
        dates(i) = DateSerial(year, i, 1)
    Next i
    GenerateMonthStarts = dates
End Function</code></pre>
<h2 id="advanced-usage">Advanced Usage</h2>
<h3 id="fiscal-year-calculations">Fiscal Year Calculations</h3>
<pre><code class="language-vbnet">Function GetFiscalYearStart(calendarYear As Integer, fiscalStartMonth As Integer) As Date
    GetFiscalYearStart = DateSerial(calendarYear, fiscalStartMonth, 1)
End Function
Function GetFiscalYearEnd(calendarYear As Integer, fiscalStartMonth As Integer) As Date
    &#x27; Fiscal year end is day before next fiscal year starts
    GetFiscalYearEnd = DateSerial(calendarYear + 1, fiscalStartMonth, 0)
End Function
Function GetCurrentFiscalYear(fiscalStartMonth As Integer) As Integer
    Dim currentMonth As Integer
    currentMonth = Month(Date)
    If currentMonth &gt;= fiscalStartMonth Then
        GetCurrentFiscalYear = Year(Date)
    Else
        GetCurrentFiscalYear = Year(Date) - 1
    End If
End Function</code></pre>
<h3 id="date-table-generator">Date Table Generator</h3>
<pre><code class="language-vbnet">Sub PopulateDateDimension(startYear As Integer, endYear As Integer)
    Dim y As Integer, m As Integer, d As Integer
    Dim currentDate As Date
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    &#x27; Open recordset...
    For y = startYear To endYear
        For m = 1 To 12
            Dim daysInMonth As Integer
            daysInMonth = Day(DateSerial(y, m + 1, 0))
            For d = 1 To daysInMonth
                currentDate = DateSerial(y, m, d)
                rs.AddNew
                rs(&quot;DateKey&quot;) = Format(currentDate, &quot;yyyymmdd&quot;)
                rs(&quot;FullDate&quot;) = currentDate
                rs(&quot;Year&quot;) = y
                rs(&quot;Quarter&quot;) = DatePart(&quot;q&quot;, currentDate)
                rs(&quot;Month&quot;) = m
                rs(&quot;Day&quot;) = d
                rs(&quot;DayOfWeek&quot;) = Weekday(currentDate)
                rs.Update
            Next d
        Next m
    Next y
End Sub</code></pre>
<h3 id="anniversary-calculator">Anniversary Calculator</h3>
<pre><code class="language-vbnet">Function GetAnniversaryDate(originalDate As Date, yearsLater As Integer) As Date
    Dim y As Integer, m As Integer, d As Integer
    y = Year(originalDate)
    m = Month(originalDate)
    d = Day(originalDate)
    GetAnniversaryDate = DateSerial(y + yearsLater, m, d)
End Function
&#x27; Handle Feb 29 anniversaries
Function GetAnniversaryDateSafe(originalDate As Date, yearsLater As Integer) As Date
    Dim y As Integer, m As Integer, d As Integer
    y = Year(originalDate) + yearsLater
    m = Month(originalDate)
    d = Day(originalDate)
    &#x27; For Feb 29, use Feb 28 in non-leap years
    If m = 2 And d = 29 Then
        If Not IsLeapYear(y) Then
            d = 28
        End If
    End If
    GetAnniversaryDateSafe = DateSerial(y, m, d)
End Function</code></pre>
<h3 id="relative-date-builder">Relative Date Builder</h3>
<pre><code class="language-vbnet">Function BuildRelativeDate(baseDate As Date, yearOffset As Integer, _
                         monthOffset As Integer, dayOffset As Integer) As Date
    BuildRelativeDate = DateSerial(Year(baseDate) + yearOffset, _
                                  Month(baseDate) + monthOffset, _
                                  Day(baseDate) + dayOffset)
End Function
&#x27; Get date 2 years, 3 months, and 5 days from now
Dim futureDate As Date
futureDate = BuildRelativeDate(Date, 2, 3, 5)</code></pre>
<h3 id="easter-calculation-simplified">Easter Calculation (Simplified)</h3>
<pre><code class="language-vbnet">Function GetEasterSunday(year As Integer) As Date
    &#x27; Simplified Meeus/Jones/Butcher algorithm
    Dim a As Integer, b As Integer, c As Integer
    Dim d As Integer, e As Integer, f As Integer
    Dim g As Integer, h As Integer, i As Integer
    Dim k As Integer, l As Integer, m As Integer
    Dim month As Integer, day As Integer
    a = year Mod 19
    b = year \ 100
    c = year 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
    month = (h + l - 7 * m + 114) \ 31
    day = ((h + l - 7 * m + 114) Mod 31) + 1
    GetEasterSunday = DateSerial(year, month, day)
End Function</code></pre>
<h3 id="business-month-end-handler">Business Month-End Handler</h3>
<pre><code class="language-vbnet">Function GetBusinessMonthEnd(year As Integer, month As Integer) As Date
    Dim lastDay As Date
    Dim dayOfWeek As Integer
    lastDay = DateSerial(year, month + 1, 0)
    dayOfWeek = Weekday(lastDay)
    &#x27; If weekend, back up to Friday
    If dayOfWeek = vbSaturday Then
        lastDay = DateSerial(year, month + 1, -1)  &#x27; Friday
    ElseIf dayOfWeek = vbSunday Then
        lastDay = DateSerial(year, month + 1, -2)  &#x27; Friday
    End If
    GetBusinessMonthEnd = lastDay
End Function</code></pre>
<h3 id="date-validator">Date Validator</h3>
<pre><code class="language-vbnet">Function IsValidDate(year As Integer, month As Integer, day As Integer) As Boolean
    On Error Resume Next
    Dim testDate As Date
    testDate = DateSerial(year, month, day)
    IsValidDate = (Err.Number = 0) And _
                  (Year(testDate) = year) And _
                  (Month(testDate) = month) And _
                  (Day(testDate) = day)
End Function</code></pre>
<h2 id="error-handling">Error Handling</h2>
<pre><code class="language-vbnet">Function SafeDateSerial(year As Integer, month As Integer, day As Integer) As Variant
    On Error GoTo ErrorHandler
    &#x27; Validate ranges
    If year &lt; 100 Or year &gt; 9999 Then
        SafeDateSerial = Null
        Exit Function
    End If
    SafeDateSerial = DateSerial(year, month, day)
    Exit Function
ErrorHandler:
    SafeDateSerial = Null
End Function</code></pre>
<h3 id="common-errors">Common Errors</h3>
<ul>
<li><strong>Error 5</strong> (Invalid procedure call): Year outside 100-9999 range</li>
<li><strong>Error 13</strong> (Type mismatch): Non-numeric arguments</li>
<li><strong>Error 6</strong> (Overflow): Result date outside valid range</li>
</ul>
<h2 id="performance-considerations">Performance Considerations</h2>
<ul>
<li><code>DateSerial</code> is very fast for date construction</li>
<li>More efficient than parsing date strings</li>
<li>Automatic range adjustment is performant</li>
<li>No string formatting overhead</li>
<li>Ideal for loop-based date generation</li>
</ul>
<h2 id="best-practices">Best Practices</h2>
<h3 id="use-for-date-construction">Use for Date Construction</h3>
<pre><code class="language-vbnet">&#x27; Good - Clear and unambiguous
deadline = DateSerial(2025, 12, 31)
&#x27; Avoid - Locale-dependent
deadline = CDate(&quot;12/31/2025&quot;)  &#x27; May fail in different locales</code></pre>
<h3 id="leverage-range-adjustment">Leverage Range Adjustment</h3>
<pre><code class="language-vbnet">&#x27; Use day 0 for last day of previous month
lastDayPrevMonth = DateSerial(year, month, 0)
&#x27; Use month 0 for last month of previous year
dec31 = DateSerial(year, 0, 31)</code></pre>
<h3 id="validate-before-critical-operations">Validate Before Critical Operations</h3>
<pre><code class="language-vbnet">If IsValidDate(y, m, d) Then
    result = DateSerial(y, m, d)
Else
    MsgBox &quot;Invalid date components&quot;
End If</code></pre>
<h3 id="extract-components-for-manipulation">Extract Components for Manipulation</h3>
<pre><code class="language-vbnet">&#x27; Extract, modify, rebuild
y = Year(someDate)
m = Month(someDate)
d = 1  &#x27; First of month
newDate = DateSerial(y, m, d)</code></pre>
<h2 id="comparison-with-other-functions">Comparison with Other Functions</h2>
<h3 id="dateserial-vs-date-literals"><code>DateSerial</code> vs Date Literals</h3>
<pre><code class="language-vbnet">&#x27; DateSerial - Dynamic, programmatic
dt = DateSerial(Year(Date), 12, 25)
&#x27; Date Literal - Static, hardcoded
dt = #12/25/2025#</code></pre>
<h3 id="dateserial-vs-datevalue"><code>DateSerial</code> vs <code>DateValue</code></h3>
<pre><code class="language-vbnet">&#x27; `DateSerial` - From numeric components
dt = DateSerial(2025, 12, 25)
&#x27; `DateValue` - From string representation
dt = DateValue(&quot;December 25, 2025&quot;)</code></pre>
<h3 id="dateserial-vs-dateadd"><code>DateSerial</code> vs <code>DateAdd</code></h3>
<pre><code class="language-vbnet">&#x27; DateSerial - Absolute date construction
nextMonth = DateSerial(Year(Date), Month(Date) + 1, 1)
&#x27; DateAdd - Relative date calculation
nextMonth = DateAdd(&quot;m&quot;, 1, Date)</code></pre>
<h2 id="limitations">Limitations</h2>
<ul>
<li>Year must be between 100 and 9999</li>
<li>Two-digit year interpretation fixed (0-29=2000-2029, 30-99=1930-1999)</li>
<li>Always returns midnight (no time component)</li>
<li>Cannot directly specify time components</li>
<li>Invalid dates may raise runtime errors</li>
</ul>
<h2 id="related-functions">Related Functions</h2>
<ul>
<li><code>DateValue</code>: Converts a string to a date</li>
<li><code>TimeSerial</code>: Creates a time from hour, minute, and second</li>
<li><code>DateAdd</code>: Adds a time interval to a date</li>
<li><code>Year</code>, <code>Month</code>, <code>Day</code>: Extract date components</li>
<li><code>Date</code>: Returns current system date</li>
<li><code>Now</code>: Returns current date and time</li>
<li><code>IsDate</code>: Tests if a value can be converted to a date</li>
<li><code>CDate</code>: Converts an expression to a Date</li>
</ul>
        </article>
        
        <div style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border-color);">
            <p>
                <a href="index.html">← Back to Datetime</a> |
                <a href="../index.html">View all functions</a>
            </p>
        </div>

    </main>

    <footer>
        <div class="container">
            <p>&copy; 2024-2026 VB6Parse Contributors. Licensed under the MIT License.</p>
        </div>
    </footer>
</body>
</html>