CompareDateItem

Compare two DATE_ITEM structures by their FILETIME member

Overview

CompareDateItem compares two date items using the FILETIME member of each. The relation returned is similar to that of strcmp() in the standard C library: a negative value, zero, or a positive value. Only the sign of a non-zero result is meaningful; do not compare it against specific values such as -1 or 1.

Purpose

Lets callers order, sort, and test for equality of DATE_ITEM_HANDLE values. Because the comparison is defined for NULL arguments, it can be used directly as a comparator without pre-checking the handles.

Key Features

Function Signature


int CompareDateItem(
    _In_ DATE_ITEM_HANDLE pDateItem1,
    _In_ DATE_ITEM_HANDLE pDateItem2
);

The function is declared in datelog.h under “Analysis & Comparison”, with the same signature.

Parameters

pDateItem1

[In] DATE_ITEM_HANDLE

The first date item.

  • NULL: allowed; a NULL first item sorts before any non-NULL second item
  • Ownership: not retained or modified; the caller keeps ownership
  • Lifetime: must remain valid for the duration of the call. Standalone items (from InitializeDateItem or GetDateItemCopy) are freed by the caller with FreeDateItem
pDateItem2

[In] DATE_ITEM_HANDLE

The second date item.

  • NULL: allowed; a NULL second item sorts before any non-NULL first item (the result is then positive)
  • Ownership/lifetime: same as pDateItem1

Return Values

The function returns an int, not an HRESULT.

ReturnMeaning
0The date items are equal (or both are NULL)
< 0pDateItem1 is earlier than pDateItem2, or pDateItem1 is NULL and pDateItem2 is not
> 0pDateItem1 is later than pDateItem2, or pDateItem2 is NULL and pDateItem1 is not

Remarks

Comparison Semantics

Only the FILETIME member of each item takes part in the comparison; other members (for example the item GUID or item number) are not considered, so two items for the same date compare equal even if they came from different logs or have different identifiers. To compare raw FILETIME values directly, use CompareFiletime; to retrieve an item’s FILETIME, use GetDateItemFiletime.

Thread Safety

The function takes no log handle, so it acquires no log lock; the existing documentation does not describe any synchronization for it. Callers must ensure that neither item is freed, and that no log core owning the item is closed with CloseDateLogHandle, while the comparison runs. Standalone copies made with GetDateItemCopy are independent of any log and are the safest choice when sharing items between threads.

Ownership

The function neither frees nor retains its arguments. Items returned by lookup functions that refer to entries stored inside a date log core must not be passed to FreeDateItem.

Sample Code

The example creates two standalone date items from a holidays handle, compares them in both directions, compares an item with its copy, demonstrates the NULL rules, and frees everything it allocated.


#include <stdio.h>
#include "datelog.h"

static HRESULT MakeItem(HOLIDAYS_HANDLE hHolidays, WORD wYear, WORD wMonth, WORD wDay,
                        DATE_ITEM_HANDLE *phItem)
{
    SYSTEMTIME st = { 0 };
    FILETIME   ft = { 0 };

    st.wYear = wYear;
    st.wMonth = wMonth;
    st.wDay = wDay;
    if (!SystemTimeToFileTime(&st, &ft)) {
        return HRESULT_FROM_WIN32(GetLastError());
    }
    /* A HOLIDAYS_HANDLE is accepted directly; holiday dates fail with ERR_DATE_IS_HOLIDAY. */
    return InitializeDateItem(hHolidays, &ft, NULL, phItem);
}

static const char *Relation(int cmp)
{
    return (cmp < 0) ? "earlier than" : (cmp > 0) ? "later than" : "equal to";
}

int main(void)
{
    HOLIDAYS_HANDLE  hHolidays = NULL;
    DATE_ITEM_HANDLE hEarly    = NULL;
    DATE_ITEM_HANDLE hLate     = NULL;
    DATE_ITEM_HANDLE hCopy     = NULL;
    HRESULT          hr        = E_FAIL;
    int              cmp       = 0;
    int              rc        = 1;

    /* Holidays handle. Populate it with your market holiday data (see
       LoadDateLogHandle) before building date logs; that step is application specific. */
    hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
    if (FAILED(hr)) {
        printf("InitializeDateLogHandle failed for holidays: 0x%08lX\n", (unsigned long)hr);
        return 1;
    }

    hr = MakeItem(hHolidays, 2024, 1, 2, &hEarly);
    if (FAILED(hr)) {
        printf("Creating the first item failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    hr = MakeItem(hHolidays, 2024, 1, 31, &hLate);
    if (FAILED(hr)) {
        printf("Creating the second item failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    cmp = CompareDateItem(hEarly, hLate);
    printf("2024-01-02 is %s 2024-01-31\n", Relation(cmp));

    cmp = CompareDateItem(hLate, hEarly);
    printf("2024-01-31 is %s 2024-01-02\n", Relation(cmp));

    /* A standalone copy carries the same FILETIME, so it compares equal. */
    hCopy = GetDateItemCopy(hEarly);
    if (hCopy == NULL) {
        printf("GetDateItemCopy failed.\n");
        goto cleanup;
    }
    cmp = CompareDateItem(hEarly, hCopy);
    printf("Item compared with its copy: %s\n", Relation(cmp));

    /* NULL sorts before any item; two NULLs are equal. */
    cmp = CompareDateItem(NULL, hEarly);
    printf("NULL is %s an item\n", Relation(cmp));
    cmp = CompareDateItem(NULL, NULL);
    printf("NULL is %s NULL\n", Relation(cmp));

    rc = 0;

cleanup:
    FreeDateItem(hCopy);
    FreeDateItem(hLate);
    FreeDateItem(hEarly);
    if (FAILED(CloseDateLogHandle(hHolidays))) {
        rc = 1;
    }
    return rc;
}

See Also