FreeDateItem

Free an allocated, unbound date item

Overview

FreeDateItem releases a standalone DATE_ITEM_HANDLE previously returned by functions such as NewDateItem(), GetDateItemCopy(), or InitializeDateItem(). Items that are still bound/linked to a date log core (recognizable by their sentinel indicator fields) are silently ignored and not freed, to prevent accidental corruption of the core's internal array.

Purpose

Date items come from two very different places: they are either standalone allocations owned by the caller, or they are entries that live directly inside a date log core's array and are owned by that core. FreeDateItem is the single release call for standalone items, and it is deliberately defensive so that a handle which points into a core cannot be freed by mistake.

Key Features

Function Signature


void FreeDateItem(
    _In_ _Post_invalid_ DATE_ITEM_HANDLE hDateItem
);

Parameters

hDateItem

[In, Post-invalid] DATE_ITEM_HANDLE

The standalone (unlinked) date item to release.

  • Type: DATE_ITEM_HANDLE (opaque void*, see datelog.h).
  • NULL: allowed; the call is a no-op.
  • Valid values: a handle obtained from InitializeDateItem(), GetDateItemCopy() (or NewDateItem()), or a handle that is already linked into a core (which is ignored).
  • Ownership/lifetime: ownership of a standalone item belongs to the caller. After the call the handle is invalid (_Post_invalid_) and must not be used again, unless the call skipped it because it was bound to a core (see Remarks). Do not free the same standalone item twice.

Return Values

This function returns no value, so there is nothing to test with FAILED/SUCCEEDED.

Return valueMeaning
voidNo return value. The handle is invalid after this call unless it was skipped because it is bound to a date log core.

Behavior and Operations

Test for NULL
→
Check sentinel fields
→
Free standalone item

The function frees the item only when bookmarkLenOrInd, iNumberLenOrInd, and dateLenOrInd are all equal to DATE_LOG_SENTINEL. This is the signature of a standalone item, as opposed to one stored directly inside a DATE_LOG_CORE array, which must never be individually freed. Any other item is ignored without an error.

Remarks

Every handle returned by InitializeDateItem() or GetDateItemCopy() must be released with exactly one call to FreeDateItem().
Handles returned by FindDateItemHandle: FindDateItemHandle() returns a pointer into the collection's internal array. That is not a standalone item and must not be freed; passing it to FreeDateItem() is silently ignored. To keep an item beyond the collection's lifetime, take a standalone copy with GetDateItemCopy() and free that copy.

See Also

Sample Code


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

static BOOL MakeFiletime(WORD wYear, WORD wMonth, WORD wDay, PFILETIME pFiletime)
{
    SYSTEMTIME st = { 0 };

    st.wYear = wYear;
    st.wMonth = wMonth;
    st.wDay = wDay;
    return SystemTimeToFileTime(&st, pFiletime);
}

int main(void)
{
    HOLIDAYS_HANDLE  hHolidays = NULL;
    DATE_LOG_HANDLE  hDateLog = NULL;
    DATE_ITEM_HANDLE hItem = NULL;
    DATE_ITEM_HANDLE hCopy = NULL;
    FILETIME         ft = { 0 };
    HRESULT          hr = E_FAIL;
    int              exitCode = 1;

    hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
    if (FAILED(hr)) {
        printf("InitializeDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hDateLog, HandleIsForDatelog);
    if (FAILED(hr)) {
        printf("InitializeDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    if (!MakeFiletime(2026, 10, 13, &ft)) {
        printf("SystemTimeToFileTime failed: %lu\n", GetLastError());
        goto cleanup;
    }

    /* InitializeDateItem returns a standalone item that the caller must free. */
    hr = InitializeDateItem(hDateLog, &ft, NULL, &hItem);
    if (hr == ERR_DATE_IS_HOLIDAY) {
        printf("2026-10-13 is a weekend or market holiday.\n");
        goto cleanup;
    }
    if (FAILED(hr)) {
        printf("InitializeDateItem failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* GetDateItemCopy also returns a standalone item (NULL on failure). */
    hCopy = GetDateItemCopy(hItem);
    if (hCopy == NULL) {
        printf("GetDateItemCopy failed.\n");
        goto cleanup;
    }

    /* Each standalone item is released exactly once. */
    FreeDateItem(hCopy);
    hCopy = NULL;
    FreeDateItem(hItem);
    hItem = NULL;

    /* FreeDateItem(NULL) is a documented no-op, so unconditional cleanup is safe. */
    FreeDateItem(hItem);
    exitCode = 0;

cleanup:
    FreeDateItem(hCopy);
    FreeDateItem(hItem);
    if (hDateLog != NULL) {
        hr = CloseDateLogHandle(hDateLog);
        if (FAILED(hr)) {
            printf("CloseDateLogHandle [date log] failed: 0x%08lX\n", (unsigned long)hr);
        }
    }
    if (hHolidays != NULL) {
        hr = CloseDateLogHandle(hHolidays);
        if (FAILED(hr)) {
            printf("CloseDateLogHandle [holidays] failed: 0x%08lX\n", (unsigned long)hr);
        }
    }
    return exitCode;
}