Index: src/wp-includes/cron.php
===================================================================
--- src/wp-includes/cron.php	(revision 36330)
+++ src/wp-includes/cron.php	(working copy)
@@ -232,6 +232,33 @@
 }
 
 /**
+ * Check whether an action hook is scheduled to fire.
+ *
+ * Unlike {@see wp_next_scheduled()}, this checks only whether a hook is
+ * scheduled with cron, not whether it will pass given arguments or when.
+ *
+ * @since x.y.z
+ *
+ * @param string $hook Hook to look for.
+ * @return bool Whether the hook is scheduled.
+ */
+function wp_is_scheduled_hook( $hook ) {
+	$crons = _get_cron_array();
+
+	if ( empty( $crons ) ) {
+		return false;
+	}
+
+	foreach ( $crons as $cron ) {
+		if ( isset( $cron[ $hook ] ) ) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
  * Sends a request to run cron through HTTP request that doesn't halt page loading.
  *
  * @since 2.1.0
Index: tests/phpunit/tests/cron.php
===================================================================
--- tests/phpunit/tests/cron.php	(revision 36330)
+++ tests/phpunit/tests/cron.php	(working copy)
@@ -85,6 +85,27 @@
 
 	}
 
+	function test_is_scheduled_hook() {
+		$hook = rand_str();
+		$ts1 = strtotime( '+30 minutes' );
+		$ts2 = strtotime( '+2 hours' );
+
+		wp_schedule_event( $ts1, 'hourly', $hook, array( 'foo' ) );
+		wp_schedule_event( $ts2, 'daily', $hook, 'bar' );
+		wp_schedule_event( $ts2, 'twicedaily', $hook, array( 'baz' ) );
+
+		$this->assertTrue( wp_is_scheduled_hook( $hook ) );
+
+		wp_unschedule_event( $ts1, $hook, array( 'foo' ) );
+		$this->assertTrue( wp_is_scheduled_hook( $hook ) );
+
+		wp_unschedule_event( $ts2, $hook, 'bar' );
+		$this->assertTrue( wp_is_scheduled_hook( $hook ) );
+
+		wp_unschedule_event( $ts2, $hook, array( 'baz' ) );
+		$this->assertFalse( wp_is_scheduled_hook( $hook ) );
+	}
+
 	function test_unschedule_event() {
 		// schedule an event and make sure it's returned by wp_next_scheduled
 		$hook = rand_str();
