diff --git a/src/wp-cron.php b/src/wp-cron.php
index acf5ded2d4..d704ceaf84 100644
--- a/src/wp-cron.php
+++ b/src/wp-cron.php
@@ -66,18 +66,11 @@ function _get_cron_lock() {
 	return $value;
 }
 
-if ( false === $crons = _get_cron_array() ) {
+$crons = wp_get_ready_cron_jobs();
+if ( empty( $crons ) ) {
 	die();
 }
 
-$keys     = array_keys( $crons );
-$gmt_time = microtime( true );
-
-if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
-	die();
-}
-
-
 // The cron lock: a unix timestamp from when the cron was spawned.
 $doing_cron_transient = get_transient( 'doing_cron' );
 
diff --git a/src/wp-includes/cron.php b/src/wp-includes/cron.php
index 046c0dca73..16430f1df4 100644
--- a/src/wp-includes/cron.php
+++ b/src/wp-includes/cron.php
@@ -641,8 +641,8 @@ function spawn_cron( $gmt_time = 0 ) {
 	}
 
 	//sanity check
-	$crons = _get_cron_array();
-	if ( ! is_array( $crons ) ) {
+	$crons = wp_get_ready_cron_jobs();
+	if ( empty( $crons ) ) {
 		return false;
 	}
 
@@ -736,8 +736,8 @@ function wp_cron() {
 		return 0;
 	}
 
-	$crons = _get_cron_array();
-	if ( false === $crons ) {
+	$crons = wp_get_ready_cron_jobs();
+	if ( empty( $crons ) ) {
 		return 0;
 	}
 
@@ -854,6 +854,52 @@ function wp_get_schedule( $hook, $args = array() ) {
 	return apply_filters( 'get_schedule', $schedule, $hook, $args );
 }
 
+/**
+ * Retrieve cron jobs ready to be run.
+ *
+ * Returns the results of _get_cron_array() limited to events ready to be run,
+ * ie, with a timestamp in the past.
+ *
+ * @return array Cron jobs ready to be run.
+ */
+function wp_get_ready_cron_jobs() {
+	/**
+	 * Filter to preflight or hijack retrieving ready cron jobs.
+	 *
+	 * Returning an array will short-circuit the normal retrieval of ready
+	 * cron jobs, causing the function to return the filtered value instead.
+	 *
+	 * @param null|array $pre Array of ready cron tasks to return instead. Default null
+	 *                        to continue using results from _get_cron_array().
+	 */
+	$pre = apply_filters( 'pre_get_ready_cron_jobs', null );
+	if ( null !== $pre ) {
+		return $pre;
+	}
+
+	$crons = _get_cron_array();
+
+	if ( false === $crons ) {
+		return array();
+	}
+
+	$gmt_time = microtime( true );
+	$keys     = array_keys( $crons );
+	if ( isset( $keys[0] ) && $keys[0] > $gmt_time ) {
+		return array();
+	}
+
+	$results = array();
+	foreach ( $crons as $timestamp => $cronhooks ) {
+		if ( $timestamp > $gmt_time ) {
+			break;
+		}
+		$results[ $timestamp ] = $cronhooks;
+	}
+
+	return $results;
+}
+
 //
 // Private functions
 //
