Index: src/wp-includes/functions.php
===================================================================
--- src/wp-includes/functions.php	(revision 35637)
+++ src/wp-includes/functions.php	(working copy)
@@ -111,6 +111,7 @@
 	if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
 		$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
 		$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
+		$datemonth_ordinal = $wp_locale->get_month_ordinal( $datefunc( 'm', $i ) );
 		$dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
 		$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
 		$datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
@@ -120,6 +121,7 @@
 		$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
 		$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
 		$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
+		$dateformatstring = preg_replace( "/([^\\\])S/", "\\1" . backslashit( $datemonth_ordinal ), $dateformatstring );
 		$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
 		$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
 
@@ -5161,3 +5163,4 @@
 	// Strip timezone information
 	return preg_replace( '/(?:Z|[+-]\d{2}(?::\d{2})?)$/', '', $formatted );
 }
+
Index: tests/phpunit/tests/functions.php
===================================================================
--- tests/phpunit/tests/functions.php	(revision 35637)
+++ tests/phpunit/tests/functions.php	(working copy)
@@ -717,4 +717,36 @@
 		the_date( 'Y', 'before ', ' after', false );
 		$this->assertEquals( '', ob_get_clean() );
 	}
+
+	/**
+	 * @ticket 22225
+	 */
+	function test_date_i18n_ordinal_suffix() {
+		$wp_locale = new WP_Locale();
+		$this->assertEquals( 'st', $wp_locale->get_month_ordinal( 1 ) );
+		$this->assertEquals( 'nd', $wp_locale->get_month_ordinal( '02' ) );
+		$this->assertEquals( 'rt', $wp_locale->get_month_ordinal( '3' ) );
+		$this->assertEquals( 'th', $wp_locale->get_month_ordinal( 12 ) );
+
+		/**
+		 * Timestamp for 2015-01-15 12:00:00 == 1420113600
+		 */
+		$this->assertEquals( 'st', date_i18n( 'S', 1420113600 ) );
+
+		/**
+		 * Timestamp for 2015-02-15 12:00:00 == 1424001600
+		 */
+		$this->assertEquals( 'nd', date_i18n( 'S', 1424001600 ) );
+
+		/**
+		 * Timestamp for 2015-03-15 12:00:00 == 1426420800
+		 */
+		$this->assertEquals( 'rt', date_i18n( 'S', 1426420800 ) );
+
+		/**
+		 * Timestamp for 2015-11-15 12:00:00 == 1447588800
+		 */
+		$this->assertEquals( 'th', date_i18n( 'S', 1447588800 ) );
+	}
+
 }
Index: src/wp-includes/locale.php
===================================================================
--- src/wp-includes/locale.php	(revision 35637)
+++ src/wp-includes/locale.php	(working copy)
@@ -166,6 +166,20 @@
 		$this->month_genitive['11'] = /* translators: month name, genitive */ _x( 'November', 'genitive' );
 		$this->month_genitive['12'] = /* translators: month name, genitive */ _x( 'December', 'genitive' );
 
+		// The Months, ordinal
+		$this->month_ordinal['01'] = /* translators: month name, ordinal */ _x( 'st', 'January ordinal suffix' );
+		$this->month_ordinal['02'] = /* translators: month name, ordinal */ _x( 'nd', 'February ordinal suffix' );
+		$this->month_ordinal['03'] = /* translators: month name, ordinal */ _x( 'rt', 'March ordinal suffix' );
+		$this->month_ordinal['04'] = /* translators: month name, ordinal */ _x( 'th', 'April ordinal suffix' );
+		$this->month_ordinal['05'] = /* translators: month name, ordinal */ _x( 'th', 'May ordinal suffix' );
+		$this->month_ordinal['06'] = /* translators: month name, ordinal */ _x( 'th', 'June ordinal suffix' );
+		$this->month_ordinal['07'] = /* translators: month name, ordinal */ _x( 'th', 'July ordinal suffix' );
+		$this->month_ordinal['08'] = /* translators: month name, ordinal */ _x( 'th', 'August ordinal suffix' );
+		$this->month_ordinal['09'] = /* translators: month name, ordinal */ _x( 'th', 'September ordinal suffix' );
+		$this->month_ordinal['10'] = /* translators: month name, ordinal */ _x( 'th', 'October ordinal suffix' );
+		$this->month_ordinal['11'] = /* translators: month name, ordinal */ _x( 'th', 'November ordinal suffix' );
+		$this->month_ordinal['12'] = /* translators: month name, ordinal */ _x( 'th', 'October ordinal suffix' );
+
 		// Abbreviations for each month.
 		$this->month_abbrev[ __( 'January' ) ]   = /* translators: three-letter abbreviation of the month */ _x( 'Jan', 'January abbreviation' );
 		$this->month_abbrev[ __( 'February' ) ]  = /* translators: three-letter abbreviation of the month */ _x( 'Feb', 'February abbreviation' );
@@ -307,6 +321,16 @@
 	}
 
 	/**
+	 * Retrieve the English ordinal suffix for the day of the month
+	 * @param string|int $month_number '01' through '12'
+	 *
+	 * @return string
+	 */
+	public function get_month_ordinal( $month_number ) {
+		return $this->month_ordinal[ zeroise( $month_number, 2 ) ];
+	}
+
+	/**
 	 * Retrieve translated version of meridiem string.
 	 *
 	 * The $meridiem parameter is expected to not be translated.
