InitializeDateItem

Create and initialize a new date item with market day validation

Overview

InitializeDateItem creates and initializes a new date item from either a FILETIME or LARGE_INTEGER representation, with automatic validation to ensure the date is a valid market day (not a weekend or holiday).

Purpose

This function serves as the primary interface for creating date items within the date log system. It ensures that all created date items represent valid market trading days by:

Key Features

Function Signature

HRESULT _Must_inspect_result_ _Success_(hDateItem != NULL && SUCCEEDED(return))
InitializeDateItem(
    _In_ _Pre_valid_ DATE_LOG_HANDLE hDateLogHandle,
    _In_opt_ _When_(pLargeInteger == NULL, _Notnull_) PFILETIME pFileTime,
    _In_opt_ _When_(pFileTime == NULL, _Notnull_) PLARGE_INTEGER pLargeInteger,
    _Out_ DATE_ITEM_HANDLE* hDateItem
);

Calling Convention

Standard C calling convention with SAL annotations for strict parameter validation and output guarantees.

Return Value Inspection Required: The _Must_inspect_result_ annotation indicates that callers must check the return value. Ignoring the return code may result in undefined behavior or resource leaks.

Parameters

hDateLogHandle

[In] DATE_LOG_HANDLE

Handle to the date log that provides the context for date validation and holidays reference.

  • Must be a valid DATE_LOG_HANDLE, DATE_RANGE_HANDLE, or equivalent handle obtained from InitializeDateLogHandle()
  • Must contain a valid context with initialized holidays handle
  • Precondition: Must be pre-validated and not NULL
  • Used to access the holidays list for market day validation
Invalid Handle Types: Passing a HOLIDAYS_HANDLE directly will fail with ERR_INVALID_DATELOG_HANDLE because holidays handles cannot be used to create date items.
pFileTime

[In, Optional] PFILETIME

Pointer to a FILETIME structure representing the date to initialize.

  • Must be non-NULL if pLargeInteger is NULL
  • When provided, pLargeInteger must be NULL (mutual exclusivity enforced by SAL)
  • Contains 64-bit representation of Windows FILETIME (100-nanosecond intervals since 1601)
  • Time components (hours, minutes, seconds, milliseconds) are ignored; only the date portion is used
Parameter Constraint: SAL annotation _When_(pLargeInteger == NULL, _Notnull_) enforces that when pLargeInteger is NULL, pFileTime must be provided (non-NULL).
pLargeInteger

[In, Optional] PLARGE_INTEGER

Pointer to a LARGE_INTEGER structure representing the date to initialize.

  • Must be non-NULL if pFileTime is NULL
  • When provided, pFileTime must be NULL (mutual exclusivity enforced by SAL)
  • Contains the date as a 64-bit integer (typically in Windows FILETIME format)
Parameter Constraint: SAL annotation _When_(pFileTime == NULL, _Notnull_) enforces that when pFileTime is NULL, pLargeInteger must be provided (non-NULL).
hDateItem

[Out] DATE_ITEM_HANDLE*

Pointer to receive the newly created date item handle.

  • Must not be NULL
  • On successful return, receives a valid DATE_ITEM_HANDLE
  • On failure, receives NULL
  • Caller is responsible for freeing the handle via FreeDateItem()
Post-Call Contract: The function enforces that on success, *hDateItem != NULL is guaranteed. If this contract is violated (function returns success but *hDateItem == NULL), the function will fail with ERROR_INVALID_HANDLE.

Return Values

Success Cases

S_OK (0x00000000)

Date item was successfully created and initialized. The *hDateItem parameter contains a valid handle to the new date item representing a market day.

Error Cases - Input Validation

HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE)

The hDateLogHandle is invalid or does not reference a valid date log context. This occurs when:

HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)

Invalid parameter combination. This occurs when:

Error Cases - Date Validation

ERR_DATE_IS_HOLIDAY

The provided date represents a weekend (Saturday or Sunday) or is listed in the holidays collection. Market trading does not occur on these days, so the date item cannot be created.

HRESULT_FROM_WIN32(ERROR_UNIDENTIFIED_ERROR)

Unexpected error during holiday or market day validation. This typically indicates a failure in IsFiletimeMarketHoliday() or internal date conversion routines.

Error Cases - Internal Operations

ERR_INVALID_DATELOG_HANDLE

The handle type is invalid or not supported for date item creation. This can occur if:

Return Value Checking


// Recommended error checking pattern
DATE_ITEM_HANDLE hNewDate = NULL;

HRESULT hr = InitializeDateItem(
    hDateLog,
    &fileTime,
    NULL,
    &hNewDate
);

if (SUCCEEDED(hr) && hNewDate != NULL) {
    // Date item successfully created
    printf("Date item created successfully\n");
    // Use hNewDate...
    FreeDateItem(hNewDate);
} else if (hr == ERR_DATE_IS_HOLIDAY) {
    printf("Cannot create date item - weekend or holiday\n");
} else if (FAILED(hr)) {
    printf("Failed to create date item: 0x%08X\n", hr);
}

Behavior and Operations

Execution Flow

Validate Inputs
Check Handle Type
Validate Market Day
Create Item
Verify Contract

Step 1: Parameter Validation

The function first validates input parameters:

Step 2: Handle Type Verification

The function determines and validates the handle type:

Step 3: Date Validation Against Holidays

The function checks that the provided date is a valid market day:

If pFileTime is provided:

If pLargeInteger is provided:

Step 4: Date Item Creation

Once validated, create the new date item:

Step 5: Post-Call Contract Verification

Immediately after creation, enforce the output contract:

Holiday and Weekend Checking

The function classifies dates as holidays if they are:

  1. Weekends: Day of week is SATURDAY (6) or SUNDAY (0)
  2. Market Holidays: Date appears in the holidays collection provided by the context
Timezone Handling: All date conversions use the Windows system time functions (FileTimeToSystemTime, SystemTimeToFileTime) which operate in local time or UTC depending on the FILETIME source. Ensure consistency with the holidays list timezone.

Validation Details

Holiday Resolution Process

When IsFiletimeMarketHoliday() is called, it returns one of three values:

Return Value Meaning Action Taken
-1 Error during validation Return ERROR_UNIDENTIFIED_ERROR to caller
0 Valid market day (not holiday, not weekend) Proceed to date item creation via NewDateItem()
> 0 (typically 1) Holiday or weekend detected Return ERR_DATE_IS_HOLIDAY to caller

Handle Validation Sequence

The function validates handles in this order:

  1. Check IsValidDateLogHandle(hDateLogHandle) — immediate rejection if false
  2. Extract context from handle and verify it is not NULL
  3. Determine handle type from context magic number
  4. For DATE_LOG and DATE_RANGE types, extract holidays reference from context
  5. For HOLIDAYS type, immediately return ERR_INVALID_DATELOG_HANDLE
  6. Verify holidays handle is valid before using it

Parameter Mutual Exclusivity

The SAL annotations enforce that exactly one date input is provided:

Compiler Enforcement: SAL annotations enable static code analysis tools (like PREfast or Code Analysis in Visual Studio) to detect violations at compile time, preventing parameter misuse before runtime.

Usage Examples

Example 1: Creating a Date Item from FILETIME

// Get current date in FILETIME format
SYSTEMTIME st = { 0 };
GetLocalTime(&st);
st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;

FILETIME ft = { 0 };
SystemTimeToFileTime(&st, &ft);

// Create date item (will fail if today is a weekend or holiday)
DATE_ITEM_HANDLE hDate = NULL;
HRESULT hr = InitializeDateItem(hDateLog, &ft, NULL, &hDate);

if (SUCCEEDED(hr) && hDate != NULL) {
    printf("Successfully created date item for today\n");
    FreeDateItem(hDate);
} else if (hr == ERR_DATE_IS_HOLIDAY) {
    printf("Today is not a market day\n");
} else {
    printf("Error: 0x%08X\n", hr);
}
Example 2: Creating a Date Item from LARGE_INTEGER

// Create a date for a specific day using LARGE_INTEGER
// Windows FILETIME = 100-nanosecond intervals since 1601-01-01
LARGE_INTEGER li = { 0 };

// For example: 132700000000000000 represents a specific date
li.QuadPart = 132700000000000000LL;

DATE_ITEM_HANDLE hDate = NULL;
HRESULT hr = InitializeDateItem(hDateLog, NULL, &li, &hDate);

if (SUCCEEDED(hr) && hDate != NULL) {
    printf("Date item created from LARGE_INTEGER\n");
    FreeDateItem(hDate);
}
Example 3: Handling Holidays Gracefully

// Try to create a date item, retry with next day if it's a holiday
DATE_ITEM_HANDLE hDate = NULL;
LARGE_INTEGER liDate = { 0 };

// Start with a target date
liDate.QuadPart = 132700000000000000LL;

// Attempt creation; if it's a holiday, try the next day
for (int attempts = 0; attempts < 10; attempts++) {
    HRESULT hr = InitializeDateItem(hDateLog, NULL, &liDate, &hDate);
    
    if (SUCCEEDED(hr) && hDate != NULL) {
        printf("Found valid market day\n");
        FreeDateItem(hDate);
        break;
    } else if (hr == ERR_DATE_IS_HOLIDAY) {
        // Skip to next day (86400000000000 = 1 day in 100-nanosecond units)
        liDate.QuadPart += 86400000000000LL;
        printf("Skipping holiday, trying next day\n");
    } else {
        printf("Error creating date item: 0x%08X\n", hr);
        break;
    }
}
Example 4: Validating with Different Handle Types

DATE_ITEM_HANDLE hDate = NULL;
FILETIME ft = { 0 };
SystemTimeToFileTime(&st, &ft);

// Works with DATE_LOG_HANDLE
HRESULT hr1 = InitializeDateItem(hDateLog, &ft, NULL, &hDate);

// Works with DATE_RANGE_HANDLE
HRESULT hr2 = InitializeDateItem(hDateRange, &ft, NULL, &hDate);

// FAILS with HOLIDAYS_HANDLE - returns ERR_INVALID_DATELOG_HANDLE
HRESULT hr3 = InitializeDateItem(hHolidays, &ft, NULL, &hDate);
if (hr3 == ERR_INVALID_DATELOG_HANDLE) {
    printf("Cannot use holidays handle to create date items\n");
}

Notes and Remarks

Thread Safety

InitializeDateItem is thread-safe. It acquires the holidays context mutex internally via IsFiletimeMarketHoliday() to safely access the shared holidays list. Multiple threads can simultaneously call this function on the same date log handle.

Resource Management

On successful return, the caller assumes ownership of the returned DATE_ITEM_HANDLE and must call FreeDateItem(hDate) when done to release memory and resources.

Date Arithmetic

When constructing LARGE_INTEGER dates, remember:

Time Components Ignored

The function ignores all time components (hours, minutes, seconds, milliseconds) from the input. It extracts only the date portion for validation and storage. This ensures that all date items represent "day-level" granularity regardless of input time precision.

Holiday List Currency: The validity of created date items depends on the holiday list being current. If the date log's holiday handle is stale or out of sync with actual market calendars, dates may be incorrectly classified as holidays or valid market days.

Error Precedence

The function checks errors in this priority order:

  1. Handle validation errors (ERROR_INVALID_HANDLE)
  2. Parameter consistency errors (ERROR_INVALID_PARAMETER)
  3. Handle type incompatibility (ERR_INVALID_DATELOG_HANDLE)
  4. Market day validation errors (ERR_DATE_IS_HOLIDAY)
  5. Internal operation errors (ERROR_UNIDENTIFIED_ERROR)
  6. Post-call contract violations (ERROR_INVALID_HANDLE)

Contract Guarantee

The _Success_ SAL annotation documents the contract: hDateItem != NULL && SUCCEEDED(return). This means:

Related Functions