TL;DR, The requirement is to be able to take a Persian (Jalali) date (also known as Persian Solar Hijri Calendar) like Esfand 19, 1400 (i.e. "12/19/1400" and convert it to other calendars (Gregorian, Islamic, Chinese, Hebrew, etc.) without using external libraries or complex Astronomical Equations. And without using the pending implementation of the new date Temporal API into Javascript.

Javascript built-in method Intl.DateTimeFormat() converts Gregorian Dates into various calendars' dates (18 World Calendars) including the formatting of the output string.

However, as of today (March 2022), Javascript does not provide a built-in method for the reverse operation, i.e. converting the Persian Dates (and other calendars' dates) back into Gregorian Dates or into other calendars. For such purposes, you will need to use External Date Libraries to do the conversion such as 'moment.js' and many others.

My method of doing the date conversion follows as an answer to this question as recommended by StackOverflow here: Can I answer my own question?

2

There are 2 best solutions below

9
On

The short Javascript function below does not use external libraries and provides the facilities to convert a Persian (Jalali) Dates (from Persian year -272,442 AP to +275,139 AP) into any of the following 18 Javascript Calendars with options for formatting the resulting output:

"buddhist", "chinese", "coptic", "dangi", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamic-umalqura", "islamic-tbla", "islamic-civil", "islamic-rgsa", "iso8601", "japanese", "persian", "roc", "islamicc".

The method, also, does not use complex mathematical or astronomical formulas and relies solely on the Javascript built-in calendar conversion algorithms which are in turn based on the ICU code [https://icu.unicode.org/].

This approach ensures that the output is always accurate and fully compliant with the Javascript engine output.

Syntax

persianToCalendars(year, month, day, [options])

In its simplest form, the function defaults to converting the Persian Date into the Gregorian calendar using the ISO Date Format.

Example: Convert the Persian Date Esfand 19, 1400 (i.e. 12/19/1400) to Gregorian.

persianToCalendars(1400,12,19);

output: 2022-03-10T00:00:00.000Z    // default output Gregorian ISO format

To to convert Persian Date to another calendar (say 'Islamic' calendar):

 persianToCalendars(1400,12,19, { toCal: "islamic-umalqura" });

 output: 8/7/1443 AH

To add formatting to the output, use the 'dateStyle' options as in the Javascript Intl.DateTimeFormat() method.

Example: Convert Persian Date to Islamic Date with full dateStyle

 persianToCalendars(1400,12,19, { toCal: "islamic-umalqura", dateStyle: "full" });

 output: Thursday, Shaʻban 7, 1443 AH

Example: Convert a Persian Date into Hebrew with Persian Locale

 persianToCalendars(1400,12,19, { toCal:"hebrew", dateStyle: "full", locale:"fa"})

 output: پنجشنبه ۷ واذار الثانی ۵۷۸۲ تقویم عبری

The above can be done for all other 18 Calendars.

An added feature is the ability to format the Persian Date into any of the available 'dateStyles' and 'locales' without conversion.

To do that specify the 'toCal' to persian

Example: Use Persian Locale to Format a Persian Date

 persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"fa"}));

 output:  ۱۴۰۰ اسفند ۱۹, پنجشنبه         // mind the RTL requirements

Example: Format a Persian Date in the Hindi Locale

 persianToCalendars(1400,12,19,{ toCal : "persian", dateStyle : "full", locale : "hi"}));

 output: AP गुरुवार, 19 ईस्फन्द् 1400

You can use all the options available in the Intl.DateTimeFormat() for formatting the output date.

Invalid Persian Dates

If an invalid Persian Date is passed to the function an error Invalid Persian Date! will be generated.

Invalid Persian Dates are dates that have incorrect days in the month or incorrect days or months.

For example, the Persian Date 1400/12/30 is invalid because month 12 of the Persian Calendar (month "Esfand") is 29 days in the year 1400.

The future Javascript Temporal API will make this task simpler.

/*********************************************************************
* @function  : persianToCalendars(year, month, day, [options])
*
* @purpose   : Converts Persian/Iranian Date (Jalali Date) to the corresponding Gregorian Date.
*              Handles Persian dates from -272,442 AP to +275,139 AP.
*              Uses the 'JS Calendar Conversion by Target Approximation' Method.
*              No external libraries or complex mathematical/astronautical formulas.
*
* @version   : 1.00
* @author    : Mohsen Alyafei
* @date      : 17 Feb 2022
* @licence   : MIT
* @param     : year  : (numeric) Persian year  (-272442 to 275139)
* @param     : month : (numeric) Persian month (1 to 12) note: months is standard 1 based
* @param     : day   : (numeric) Persian day   (1 to 31)
* @param     : options: Object with the following optional parameters:
*
*              'toCal' : Specifies the the type of output Calendar to convert to with 18 Calendars:
*                        - "gregory" : (default)
*                        - "buddhist", "chinese", "coptic", "dangi", "ethioaa", "ethiopic",
*                          "hebrew", "indian", "islamic", "islamic-umalqura", "islamic-tbla",
*                          "islamic-civil", "islamic-rgsa", "iso8601", "japanese", "persian", "roc".
*
*               'dateStyle' Same as used in the Intl.DateTimeFormat() constructor.
*                           If not stated, default output is in Gregorian ISO Format: YYYY:MM:DDTHH:mm:ss.sssZ
*
*               'locale' The BCP 47 language tag for formatting (default is 'en'). If the 'locale'
*                        is given then no date conversion happens and the Persian date is formatted
*                        based on the specified 'dateStyle' and 'locale'.
*
*               Other options: As used in the Intl.DateTimeFormat() constructor.
*
* @returns   : Return the date in the calendar and format of the specified 'options'
**********************************************************************/




//==========================================================
function persianToCalendars(year, month, day, op={}) {
const formatOut= gD=> "toCal"in op?(op.calendar=op.toCal,new Intl.DateTimeFormat(op.locale??"en",op).format(gD)):gD,
      dFormat  = new Intl.DateTimeFormat('en-u-ca-persian',{dateStyle:'short',timeZone:"UTC"});
let   gD       = new Date(Date.UTC(2000,month,day));
      gD       = new Date(gD.setUTCDate(gD.getUTCDate() + 226867));
const gY       = gD.getUTCFullYear()-2000+year;
      gD       = new Date(((gY<0)?"-":"+")+("00000"+Math.abs(gY)).slice(-6)+"-"+("0"+(gD.getUTCMonth()+1)).slice(-2)+"-"+("0"+(gD.getUTCDate())).slice(-2));
let [pM,pD,pY] = [...dFormat.format(gD).split("/")], i=0;
      gD       = new Date(gD.setUTCDate(gD.getUTCDate() +
                 ~~(year*365.25+month*30.44+day-(pY.split(" ")[0]*365.25+pM*30.44+pD*1))-2));
while (i < 4) {
    [pM,pD,pY]=[...dFormat.format(gD).split("/")];
    if (pD==day && pM==month && pY.split(" ")[0]==year) return formatOut(gD);
    gD = new Date(gD.setUTCDate(gD.getUTCDate()+1));i++;
}
throw new Error('Invalid Persian Date!');
}
//==========================================================










//==========================================================
// Test Units
//==========================================================
console.log("-".repeat(55));
console.log("Convert the Persian Date '1400-12-19' to other calendars:");
console.log("input to function: persianToCalendars(1400,12,19, options)");
console.log("-".repeat(55));

console.log("Default (Gregory) ISO format   : ",persianToCalendars(1400,12,19)); // convert to default gregorian date
console.log("Gregory 'full' format          : ",persianToCalendars(1400,12,19,{toCal:"gregory",dateStyle:"full"}));
console.log("Islamic 'full' format          : ",persianToCalendars(1400,12,19,{toCal:"islamic",dateStyle:"full"}));
console.log("Islamic-Umaalqura 'short'format: ",persianToCalendars(1400,12,19,{toCal:"islamic-umalqura"}));
console.log("Islamic-Umaalqura 'full' format: ",persianToCalendars(1400,12,19,{toCal:"islamic-umalqura",dateStyle:"full"}));
console.log("Islamic-civil 'full' format    : ",persianToCalendars(1400,12,19,{toCal:"islamic-civil",dateStyle:"full"}));
console.log("Islamic-tbla 'full' format     : ",persianToCalendars(1400,12,19,{toCal:"islamic-tbla",dateStyle:"full"}));
console.log("Islamic-rgsa 'full' format     : ",persianToCalendars(1400,12,19,{toCal:"islamic-rgsa",dateStyle:"full"}));
console.log("Hebrew 'full' format           : ",persianToCalendars(1400,12,19,{toCal:"hebrew",dateStyle:"full"}));
console.log("Indian 'full' format           : ",persianToCalendars(1400,12,19,{toCal:"indian",dateStyle:"full"}));
console.log("Buddhist 'full' format         : ",persianToCalendars(1400,12,19,{toCal:"buddhist",dateStyle:"full"}));
console.log("Chinese 'full' format          : ",persianToCalendars(1400,12,19,{toCal:"chinese",dateStyle:"full"}));
console.log("Dangi (Korean) 'full' format   : ",persianToCalendars(1400,12,19,{toCal:"dangi",dateStyle:"full"}));
console.log("R.O.C. (Minguo) 'full' format  : ",persianToCalendars(1400,12,19,{toCal:"roc",dateStyle:"full"}));
console.log("Japanese 'full' format         : ",persianToCalendars(1400,12,19,{toCal:"japanese",dateStyle:"full"}));
console.log("Coptic 'full' format           : ",persianToCalendars(1400,12,19,{toCal:"coptic",dateStyle:"full"}));
console.log("Ethioaa 'full' format          : ",persianToCalendars(1400,12,19,{toCal:"ethioaa",dateStyle:"full"}));
console.log("Ethiopic 'full' format         : ",persianToCalendars(1400,12,19,{toCal:"ethiopic",dateStyle:"full"}));
console.log("-".repeat(55));
console.log("Format the input Persian Date without conversion:");
console.log("-".repeat(55));
console.log("Persian 'full' format        : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full"}));
console.log("Persian 'medium' format      : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"medium"}));
console.log("Persian 'short' format       : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"short"}));
console.log("Persian 'ar' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"ar"}));
console.log("Persian 'fa' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"fa"}));
console.log("Persian 'hi' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"hi"}));
console.log("Persian 'ur' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"ur"}));
console.log("Persian 'ps-AF' locale       : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"ps-AF"}));
console.log("Persian 'id' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"id"}));
console.log("Persian 'pa' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"pa"}));
console.log("Persian 'ma' locale          : ",persianToCalendars(1400,12,19,{toCal:"persian",dateStyle:"full", locale:"ma"}));

console.log("-".repeat(55));
console.log("Convert Max Negative and Max Positive Persian Dates to Gregorian");
console.log("-".repeat(55));
console.log(persianToCalendars(-272442,12,29)); // max negative Persian date
console.log(persianToCalendars(275139,6,23));   // max positive Persian date

console.log("-".repeat(55));

1
On

Just one line of code.

new Date(Date.UTC(2022,11,12)).toLocaleDateString('fa-IR') // ۱۴۰۱/۹/۲۱

for more information check MDN doc