Skip to content
← Back to Functions
Code

Date Range Validator

Validates start/end dates, order, allowed span, timezone, and boundary rules.

Function signature

ogValidateDateRange(start_date, end_date, timezone_name = 'UTC', max_days = 366)

Categories

  • Forms and Validation

Parameters

start_dateStart date or date/time string.end_dateEnd date or date/time string.timezone_nameTimezone identifier, such as America/New_York.max_daysMaximum allowed span in days. Use 0 to disable the span cap.

Return value

Short public-safe status message.

  • start_date
  • end_date
  • days
  • timezone

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Validates a start/end date range with timezone and maximum-span controls.
 *
 * @param string $start_date Start date or date/time string.
 * @param string $end_date End date or date/time string.
 * @param string $timezone_name Timezone identifier, such as America/New_York.
 * @param int $max_days Maximum allowed span in days. Use 0 to disable the span cap.
 * @return array Validation result with normalized ISO dates and span metadata.
 */
function ogValidateDateRange($start_date, $end_date, $timezone_name = 'UTC', $max_days = 366) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$start_date = trim((string)$start_date);
	$end_date = trim((string)$end_date);
	$timezone_name = trim((string)$timezone_name);
	$max_days = (int)$max_days;

	if (empty($start_date)) {
		$result['message'] = 'Missing start date.';
		return $result;
	}

	if (empty($end_date)) {
		$result['message'] = 'Missing end date.';
		return $result;
	}

	try {
		$timezone = new DateTimeZone($timezone_name);
	} catch (Exception $exception) {
		$result['message'] = 'Invalid timezone.';
		return $result;
	}

	try {
		$start = new DateTimeImmutable($start_date, $timezone);
		$end = new DateTimeImmutable($end_date, $timezone);
	} catch (Exception $exception) {
		$result['message'] = 'Invalid date value.';
		return $result;
	}

	if ($end < $start) {
		$result['message'] = 'End date must not be before start date.';
		return $result;
	}

	$span_seconds = $end->getTimestamp() - $start->getTimestamp();
	$span_days = (int)ceil($span_seconds / 86400);
	if ($max_days > 0 && $span_days > $max_days) {
		$result['message'] = 'Date range is too large.';
		return $result;
	}

	$result['success'] = true;
	$result['message'] = 'Date range validated.';
	$result['data'] = array(
		'start_date' => $start->format('Y-m-d H:i:s'),
		'end_date' => $end->format('Y-m-d H:i:s'),
		'timezone' => $timezone->getName(),
		'span_days' => $span_days,
		'span_seconds' => $span_seconds
	);

	return $result;
}