4

How should I convert a non-Gregorian date to other calender types using IntlDateFormatter. I want convert "1392-01-02" from persian to islamic calender. I tried the following code but it does not convert the calendar:

$formatter = IntlDateFormatter::create('en_US@calendar=persian', IntlDateFormatter::FULL,
    IntlDateFormatter::FULL, 'Asia/Tokyo',IntlDateFormatter::TRADITIONAL,'yy-MM-dd');
$formatter->setCalendar(IntlDateFormatter::GREGORIAN);
echo $formatter->format($formatter->parse("1392-2-31"));
Handsome Nerd
  • 17,114
  • 22
  • 95
  • 173
  • Shouldn't you pass the 5th argument as `IntlDateFormatter::TRADITIONAL`? As the input date is in a non-Gregorian calendar. – marekful Jun 04 '14 at 16:38
  • @MarcellFülöp "Non-Gregorian calendars need to be specified in locale. Examples might include locale="hi@calendar=BUDDHIST". It seems that parameter is totally useless. – Handsome Nerd Jun 04 '14 at 16:49

1 Answers1

4

Define the time you're converting as an instance of IntlCalendar and set the date using its set($year,$month,$day) method.

$time = IntlCalendar::createInstance("Asia/Tokyo", "en_US@calendar=persian");
$time->set(1392,2,31);

//alternative way to define time using parse

/**
These constants are used to specify different formats in the constructor for DateType 
and TimeType.

IntlDateFormatter::NONE (integer)
Do not include this element
IntlDateFormatter::FULL (integer)
Completely specified style (Tuesday, April 12, 1952 AD or 3:30:42pm PST)
IntlDateFormatter::LONG (integer)
Long style (January 12, 1952 or 3:30:32pm)
IntlDateFormatter::MEDIUM (integer)
Medium style (Jan 12, 1952)
IntlDateFormatter::SHORT (integer)
Most abbreviated style, only essential data (12/13/52 or 3:30pm)
*/

$fmt = new IntlDateFormatter(
    'en_US@calendar=persian',
    IntlDateFormatter::SHORT, //date format
    IntlDateFormatter::NONE, //time format
    'Asia/Tokyo',
    IntlDateFormatter::TRADITIONAL
);

$time = $fmt->parse('3/31/1392 AP');

$formatter = IntlDateFormatter::create("en_US@calendar=islamic",
  IntlDateFormatter::FULL, 
  IntlDateFormatter::FULL,
  'Asia/Tokyo', 
  IntlDateFormatter::TRADITIONAL);

print $formatter->format($time);
//Friday, Shaʻban 13, 1434 AH at 8:52:23 AM Japan Standard Time
FuzzyTree
  • 32,014
  • 3
  • 54
  • 85
  • Thanks. In your solution I have to pars non-Gregorian date manually. How can I use `parse` method of IntlDateFomatter on non-Gregorian dates? – Handsome Nerd Jun 07 '14 at 03:58
  • @PHPst the `parse` method restricts you to the `FULL`, `LONG`, `MEDIUM`, `SHORT` formats. I've added an example for `SHORT` – FuzzyTree Jun 07 '14 at 04:26
  • `parse` is not restricted to `FULL`,… . Using the `pattern` parameter you can use it for any format. My problem with it is that it seems the `parse` accepts Gregorian input. – Handsome Nerd Jun 13 '14 at 05:19
  • If you want to format using the same timezone, locale and calendar type you used for the `IntlCalendar` object, it's simpler to use `IntlDateFormatter::formatObject()`. – Artefacto Aug 29 '14 at 19:45
  • 1
    Whats the meaning of `AP` in `parse` method? – Mohammad Ali Akbari Aug 22 '17 at 14:49
  • i write a helper method for this functionality , can visit : [this link](https://stackoverflow.com/questions/43332341/php-intl-can-convert-a-gregorian-date-to-other-calendar-type/46275845#46275845) – Honarkhah Sep 18 '17 at 10:57