Index: tests/phpunit/tests/date/query.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- tests/phpunit/tests/date/query.php	(revision 31255)
+++ tests/phpunit/tests/date/query.php	(revision )
@@ -645,6 +645,7 @@
 				'day'  => 8,
 				'year' => 2014,
 			),
+			'21 June 1987',
 		);
 
 		foreach ( $valid_args as $args ) {
@@ -669,6 +670,11 @@
 			array(
 				'week' => 54,
 			),
+			'I am a valid date string!',
+			false,
+			true,
+			3.14159265359
+
 		);
 
 		foreach ( $invalid_args as $args ) {
Index: src/wp-includes/date.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/wp-includes/date.php	(revision 31255)
+++ src/wp-includes/date.php	(revision )
@@ -291,12 +291,12 @@
 		 * validation routine continue to be sure that all invalid
 		 * values generate errors too.
 		 */
-		if ( array_key_exists( 'before', $date_query ) && is_array( $date_query['before'] ) ){
-			$valid = $this->validate_date_values( $date_query['before'] );
+		if ( array_key_exists( 'before', $date_query ) ) {
+			$valid = $this->validate_before_after_args( $date_query[ 'before' ], 'before' );
 		}
 
-		if ( array_key_exists( 'after', $date_query ) && is_array( $date_query['after'] ) ){
-			$valid = $this->validate_date_values( $date_query['after'] );
+		if ( array_key_exists( 'after', $date_query ) ) {
+			$valid = $this->validate_before_after_args( $date_query[ 'after' ], 'after' );
 		}
 
 		// Array containing all min-max checks.
@@ -394,9 +394,9 @@
 			foreach ( (array) $date_query[ $key ] as $_value ) {
 				$is_between = $_value >= $check['min'] && $_value <= $check['max'];
 
-				if ( ! is_numeric( $_value ) || ! $is_between ) {
+				if ( ! $is_between ) {
 					$error = sprintf(
-						/* translators: Date query invalid date message: 1: invalid value, 2: type of value, 3: minimum valid value, 4: maximum valid value */
+					/* translators: Date query invalid date message: 1: invalid value, 2: type of value, 3: minimum valid value, 4: maximum valid value */
 						__( 'Invalid value %1$s for %2$s. Expected value should be between %3$s and %4$s.' ),
 						'<code>' . esc_html( $_value ) . '</code>',
 						'<code>' . esc_html( $key ) . '</code>',
@@ -458,6 +458,48 @@
 		}
 
 		return $valid;
+	}
+
+	/**
+	 * Validates the before/after date-query args.
+	 *
+	 * @since 4.1.1
+	 *
+	 * @param string|array $args    the date-query args for before/after
+	 * @param string $type          the type "before" or "after"
+	 *
+	 * @return bool true|false
+	 */
+	public function validate_before_after_args( $args, $type ) {
+
+		if ( is_array( $args ) ) {
+			return $this->validate_date_values( $args );
+		}
+
+		if ( is_string( $args ) ) {
+			$valid = ! ! strtotime( $args );
+
+			if ( ! $valid ) {
+				$error = sprintf(
+					_x( 'Invalid time string %1$s for %2$s.', '1: time-string, 2: "before" or "after"' ),
+					'<code>' . $args . '</code>',
+					$type
+				);
+				_doing_it_wrong( __CLASS__, $error, '4.1.1' );
+			}
+
+			return $valid;
+		}
+
+		$error = sprintf(
+			_x( 'Invalid type %1$s for %2$s. Excepted string or array', '1: argument type, 2: "before" or "after"' ),
+			'<code>' . gettype( $args ) . '</code>',
+			'<strong>' . $type . '</strong>'
+		);
+
+		_doing_it_wrong( __CLASS__, $error, '4.1.1' );
+
+		return false;
 	}

