This is not full implementation of features from CLDR. These are missing: - support for other calendars than Gregorian - some data from "dates" tag is not used (fields, timeZoneNames)
See also: http://www.unicode.org/reports/tr35/#Date_Elements
See also: http://www.unicode.org/reports/tr35/#Date_Format_Patterns
 /**
  * Formats dateTime with format string for date and time defined in CLDR for
  * particular locale.
  *
  * First date and time are formatted separately, and then dateTime format
  * from CLDR is used to place date and time in correct order.
  *
  * @param \DateTimeInterface $dateTime PHP object representing particular point in time
  * @param Locale $locale
  * @param string $formatLength One of DatesReader FORMAT_LENGTH constants
  * @return string Formatted date and time
  * @api
  */
 public function formatDateTime(\DateTimeInterface $dateTime, Locale $locale, $formatLength = DatesReader::FORMAT_LENGTH_DEFAULT)
 {
     DatesReader::validateFormatLength($formatLength);
     return $this->doFormattingWithParsedFormat($dateTime, $this->datesReader->parseFormatFromCldr($locale, DatesReader::FORMAT_TYPE_DATETIME, $formatLength), $this->datesReader->getLocalizedLiteralsForLocale($locale));
 }
 /**
  * @test
  */
 public function localizedLiteralsAreCorrectlyReadFromCldr()
 {
     $getRawArrayCallback = function () {
         $args = func_get_args();
         $mockDatesCldrData = (require __DIR__ . '/../../Fixtures/MockDatesParsedCldrData.php');
         $lastPartOfPath = substr($args[0], strrpos($args[0], '/') + 1);
         // Eras have different XML structure than other literals so they have to be handled differently
         if ($lastPartOfPath === 'eras') {
             return $mockDatesCldrData['eras'];
         } else {
             return $mockDatesCldrData[$lastPartOfPath];
         }
     };
     $mockModel = $this->getAccessibleMock(I18n\Cldr\CldrModel::class, ['getRawArray'], [[]]);
     $mockModel->expects($this->exactly(5))->method('getRawArray')->will($this->returnCallback($getRawArrayCallback));
     $mockRepository = $this->createMock(I18n\Cldr\CldrRepository::class);
     $mockRepository->expects($this->once())->method('getModelForLocale')->with($this->sampleLocale)->will($this->returnValue($mockModel));
     $mockCache = $this->getMockBuilder(VariableFrontend::class)->disableOriginalConstructor()->getMock();
     $this->createCacheExpectations($mockCache);
     $reader = new I18n\Cldr\Reader\DatesReader();
     $reader->injectCldrRepository($mockRepository);
     $reader->injectCache($mockCache);
     $reader->initializeObject();
     $result = $reader->getLocalizedLiteralsForLocale($this->sampleLocale);
     $this->assertEquals('January', $result['months']['format']['wide'][1]);
     $this->assertEquals('Sat', $result['days']['format']['abbreviated']['sat']);
     $this->assertEquals('1', $result['quarters']['format']['narrow'][1]);
     $this->assertEquals('a.m.', $result['dayPeriods']['stand-alone']['wide']['am']);
     $this->assertEquals('Anno Domini', $result['eras']['eraNames'][1]);
     $reader->shutdownObject();
 }
 /**
  * Parses dateTime with format string for date and time defined in CLDR for
  * particular locale.
  *
  * @param string $dateAndTimeToParse Date and time to be parsed
  * @param I18n\Locale $locale
  * @param string $formatLength One of: full, long, medium, short, or 'default' in order to use default length from CLDR
  * @param boolean $strictMode Work mode (strict when TRUE, lenient when FALSE)
  * @return mixed Array of parsed date and time elements, FALSE on failure
  */
 public function parseDateAndTime($dateAndTimeToParse, I18n\Locale $locale, $formatLength = DatesReader::FORMAT_LENGTH_DEFAULT, $strictMode = true)
 {
     DatesReader::validateFormatLength($formatLength);
     return $this->doParsingWithParsedFormat($dateAndTimeToParse, $this->datesReader->parseFormatFromCldr($locale, DatesReader::FORMAT_TYPE_DATETIME, $formatLength), $this->datesReader->getLocalizedLiteralsForLocale($locale), $strictMode);
 }