[PATCH 2/2] vbscript: Implement DateAdd().

Nikolay Sivov nsivov at codeweavers.com
Sun May 15 07:50:57 CDT 2022


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52686
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/vbscript/global.c      | 57 +++++++++++++++++++++++++++++++++++--
 dlls/vbscript/tests/api.vbs | 29 +++++++++++++++++++
 2 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
index da3da1f04d8..f8770093f0e 100644
--- a/dlls/vbscript/global.c
+++ b/dlls/vbscript/global.c
@@ -2209,10 +2209,61 @@ static HRESULT Global_GetObject(BuiltinDisp *This, VARIANT *args, unsigned args_
     return hres;
 }
 
-static HRESULT Global_DateAdd(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
+static HRESULT Global_DateAdd(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, VARIANT *res)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    BSTR interval = NULL;
+    UDATE ud = { 0 };
+    HRESULT hres;
+    double date;
+    int count;
+
+    TRACE("\n");
+
+    assert(args_cnt == 3);
+
+    hres = to_string(args, &interval);
+    if (SUCCEEDED(hres))
+        hres = to_int(args + 1, &count);
+    if (SUCCEEDED(hres))
+        hres = to_system_time(args + 2, &ud.st);
+    if (SUCCEEDED(hres))
+    {
+        if (!wcscmp(interval, L"yyyy"))
+            ud.st.wYear += count;
+        else if (!wcscmp(interval, L"q"))
+            ud.st.wMonth += 3 * count;
+        else if (!wcscmp(interval, L"m"))
+            ud.st.wMonth += count;
+        else if (!wcscmp(interval, L"y")
+                || !wcscmp(interval, L"d")
+                || !wcscmp(interval, L"w"))
+        {
+            ud.st.wDay += count;
+        }
+        else if (!wcscmp(interval, L"ww"))
+            ud.st.wDay += 7 * count;
+        else if (!wcscmp(interval, L"h"))
+            ud.st.wHour += count;
+        else if (!wcscmp(interval, L"n"))
+            ud.st.wMinute += count;
+        else if (!wcscmp(interval, L"s"))
+            ud.st.wSecond += count;
+        else
+        {
+            WARN("Unrecognized interval %s.\n", debugstr_w(interval));
+            hres = MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
+        }
+    }
+
+    SysFreeString(interval);
+
+    if (SUCCEEDED(hres))
+        hres = VarDateFromUdateEx(&ud, 0, 0, &date);
+
+    if (SUCCEEDED(hres))
+        hres = return_date(res, date);
+
+    return hres;
 }
 
 static HRESULT Global_DateDiff(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs
index f65789184e0..d8b8578be2e 100644
--- a/dlls/vbscript/tests/api.vbs
+++ b/dlls/vbscript/tests/api.vbs
@@ -1986,4 +1986,33 @@ call testDateSerial(2000, 14, 2, 2001, 2, 2)
 call testDateSerial(9999, 12, 1, 9999, 12, 1)
 call testDateSerialError()
 
+sub testDateAdd(d, interval, number, expected_date)
+    dim x
+    x = DateAdd(interval, number, d)
+    call ok(Year(x) = Year(expected_date), "year = " & Year(x) & " expected " & Year(expected_date))
+    call ok(Month(x) = Month(expected_date), "month = " & Month(x) & " expected " & Month(expected_date))
+    call ok(Day(x) = Day(expected_date), "day = " & Day(x) & " expected " & Day(expected_date))
+    call ok(getVT(x) = "VT_DATE*", "getVT = " & getVT(x))
+end sub
+
+sub testDateAddError()
+    on error resume next
+    call Err.clear()
+    call DateAdd("k", 1, DateSerial(2000, 2, 1))
+    call ok(Err.number = 5, "Err.number = " & Err.number)
+end sub
+
+call testDateAdd(DateSerial(2000, 1, 1), "yyyy", 1, DateSerial(2001, 1, 1))
+call testDateAdd(DateSerial(2000, 1, 1), "q", 1, DateSerial(2000, 4, 1))
+call testDateAdd(DateSerial(2000, 1, 1), "m", -1, DateSerial(1999, 12, 1))
+call testDateAdd(DateSerial(2000, 12, 31), "y", 1, DateSerial(2001, 1, 1))
+call testDateAdd(DateSerial(2000, 12, 31), "d", 1, DateSerial(2001, 1, 1))
+call testDateAdd(DateSerial(2000, 12, 31), "w", 1, DateSerial(2001, 1, 1))
+call testDateAdd(DateSerial(2000, 1, 1), "y", -1, DateSerial(1999, 12, 31))
+call testDateAdd(DateSerial(2000, 1, 1), "d", -1, DateSerial(1999, 12, 31))
+call testDateAdd(DateSerial(2000, 1, 1), "w", -1, DateSerial(1999, 12, 31))
+call testDateAdd(DateSerial(2000, 1, 1), "ww", 1, DateSerial(2000, 1, 8))
+call testDateAdd(DateSerial(2000, 1, 1), "ww", -1, DateSerial(1999, 12, 25))
+call testDateAddError()
+
 Call reportSuccess()
-- 
2.35.1




More information about the wine-devel mailing list