GetDateLogHolidayHandle

Return a duplicated holidays handle associated with a date log

Overview

GetDateLogHolidayHandle returns a new, independently reference-counted HOLIDAYS_HANDLE that shares the same underlying context as the holidays handle associated with hDatelogHandle. The new handle is obtained through DuplicateDateLogHandle.

Purpose

Allows callers to obtain their own closable reference to a date log's holidays handle without affecting the original handle's lifetime or requiring direct access to internal context pointers. The result can be used wherever a holidays-capable handle is accepted, for example InitializeDateItem, IsDateItemHoliday or IsDateItemCoveredByHolidaysHandle.

Key Features

Function Signature


HOLIDAYS_HANDLE _Check_return_ _Success_(return != NULL) GetDateLogHolidayHandle(
    _In_ DATE_LOG_HANDLE hDatelogHandle
);

Parameters

hDatelogHandle

[In] DATE_LOG_HANDLE

Handle whose associated holidays handle is to be duplicated and returned. Must be a valid date log handle that has a holidays handle (see InitializeDateLogHandle).

NULL is not allowed and results in a NULL return value. The handle is validated and locked during the call and is not modified or closed; the caller keeps ownership of it.

Return Values

ValueMeaning
Non-NULL HOLIDAYS_HANDLEA new handle that the caller owns and must release via CloseDateLogHandle.
NULLhDatelogHandle is NULL, fails validation/locking, or duplication fails.
No HRESULT is available from this function. If you need to diagnose a failure, validate the handle first with IsValidDateLogHandle. See date_error_h for ERR_INVALID_DATELOG_HANDLE, ERR_INVALID_HOLIDAY_HANDLE and ERR_DATELOG_NO_HOLIDAYS (holidays handle invalid inside the date log), which are reported by HRESULT-returning functions.

Behavior and Operations

Validate & Lock
→
DuplicateDateLogHandle(hHolidays)
→
Unlock & Return
If duplication or unlocking fails, any partially duplicated handle is closed via CloseDateLogHandle() before returning NULL.

Remarks

Thread Safety

The date log handle is validated and locked while the holidays handle is duplicated, so the call is safe with respect to other operations on the same handle. Each returned handle tracks its own state; a separate duplicate per thread avoids contending on a single handle's mutex.

Handle Lifetime and Reference Counting

The returned handle references the same shared context as the date log's holidays handle and increments its reference count. The shared context is freed only when the last handle referencing it is closed. Closing the returned handle does not invalidate hDatelogHandle, and closing hDatelogHandle does not invalidate the returned handle.

Ownership

The caller owns the returned handle and must close it exactly once with CloseDateLogHandle. Do not use it after it has been closed.

Ordering

Create the holidays handle first (HandleIsForHolidays), then the date log with that holidays handle, then call this function. Close the returned handle, the date log and the original holidays handle in any order, each exactly once.

The previous revision of this page typed the result as DATE_LOG_HANDLE; the header declares it as HOLIDAYS_HANDLE.

See Also

Sample Code


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

/* Builds a FILETIME for midnight (UTC) of the given calendar date. */
static BOOL MakeFiletime(WORD wYear, WORD wMonth, WORD wDay, FILETIME *pFileTime)
{
    SYSTEMTIME st = { 0 };

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

int main(void)
{
    HRESULT hr = E_FAIL;
    HOLIDAYS_HANDLE hHolidays = NULL;
    HOLIDAYS_HANDLE hLogHolidays = NULL;
    DATE_LOG_HANDLE hDateLog = NULL;
    DATE_ITEM_HANDLE hDateItem = NULL;
    FILETIME ft = { 0 };
    int holiday = -1;
    int exitCode = 1;

    /* A holidays handle is created with HandleIsForHolidays; hHolidays must be NULL for that type. */
    hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hHolidays, HandleIsForHolidays);
    if (FAILED(hr)) {
        printf("Holidays handle creation failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* The date log duplicates hHolidays internally; the caller still owns hHolidays. */
    hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, hHolidays, &hDateLog, HandleIsForDatelog);
    if (FAILED(hr)) {
        printf("Date log creation failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    /* Obtain our own reference to the holidays handle the date log is using. */
    hLogHolidays = GetDateLogHolidayHandle(hDateLog);
    if (hLogHolidays == NULL) {
        printf("GetDateLogHolidayHandle failed.\n");
        goto cleanup;
    }

    if (!IsValidDateLogHandle(hLogHolidays)) {
        printf("The returned holidays handle is not valid.\n");
        goto cleanup;
    }

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

    hr = InitializeDateItem(hLogHolidays, &ft, NULL, &hDateItem);
    if (FAILED(hr)) {
        printf("InitializeDateItem failed: 0x%08lX\n", (unsigned long)hr);
        goto cleanup;
    }

    holiday = IsDateItemHoliday(hDateItem, hLogHolidays);
    if (holiday < 0) {
        printf("IsDateItemHoliday reported an error.\n");
        goto cleanup;
    }
    printf("The date %s a market holiday.\n", holiday == 1 ? "is" : "is not");

    exitCode = 0;

cleanup:
    if (hDateItem != NULL) {
        FreeDateItem(hDateItem);
    }
    /* Every handle obtained from InitializeDateLogHandle or GetDateLogHolidayHandle is closed exactly once. */
    if (hLogHolidays != NULL) {
        CloseDateLogHandle(hLogHolidays);
    }
    if (hDateLog != NULL) {
        CloseDateLogHandle(hDateLog);
    }
    if (hHolidays != NULL) {
        CloseDateLogHandle(hHolidays);
    }
    return exitCode;
}