How to Convert any of the 5 Islamic (Hijri) Calendars’ Dates to any of 18 World Calendars without External Libraries or Complex Astronomical Formulas

An engineer, physicist, and mathematician where on a train rolling through the English countryside, when the engineer looked out the window, and seeing a lone black sheep on the hillside, exclaimed, “Hey, look, England’s got black sheep!” The physicist quickly admonished him, “All we can ascertain is that England has one black sheep.” Whereupon the mathematician admonished them both, proclaiming, “All we can conclude is that England has at least one sheep that’s black on one side…”

My apologies in arrears, as I’m a mathematician…

After some research, I believe the long term answer lies with the ECMAScript proposal dubbed “Temporal” which is currently (as of Thu 24 Feb 2022) in Stage 3 of Active Proposals. The full Stage 3 Draft of the Temporal proposal provides a bit of background on the motivation of the proposal along with the entire technical specification, with the Temporal documentation providing a more understandable purpose and operational use. This latter document is a good place to start…

A couple of notables drawn from the documentation:

  • Temporal.Instant abstracts a point in time without regard to calendar or location. Ie, this is the absolute time which all calendars and time zones must reference to render the date and time in the specified locale.

  • Temporal.Calendar is a representation of a calendar system, which provides the details on the calendar and methods by which to operate on the calendar. A number of prebuilt calendars exist, such as ‘gregory’, ‘islamic’, ‘hebrew’, etc. Additionally, the Temporal proposal also makes it possible to implement your own calendar.

That being said, the CookBook examples all make use of modern time frames, so am actually interested in attempting to implement the Julian calendar from 4AD to 1752AD during which time it was employed. The concept being that contemporaneous dates referencing the Julian calendar can be entered directly as the Julian date and easily manipulated and compared with dates from other calendars, with confidence that the dates are referencing the same underlying Temporal.Instant frame of reference… Eg, what was the Islamic date when William Shakespeare was born?

Being an ECMAScript stage 3 proposal, Temporal is still experimental but encouraged to be exercised in a non production environment, reporting any bugs. As the Temporal.Instant is the underlying point in time regardless of calendar or location, the conversion between calendars becomes a natural consequence of presenting Temporal.Instant via different calendars.

<script type="module">

  import * as TemporalModule from 'https://cdn.jsdelivr.net/npm/@js-temporal/[email protected]/dist/index.umd.js'
  
  const Temporal = temporal.Temporal;

  let islamicDate = Temporal.ZonedDateTime.from( {
    year: 1440,
    monthCode: 'M06',
    day: 2,
    hour:12,
    minute: 45,
    timeZone: 'Asia/Dubai',
    calendar: 'islamic'
  } );
  
  let hebrewDate = Temporal.ZonedDateTime.from( islamicDate ).withCalendar( 'hebrew' );
  
  let gregoryDate = Temporal.ZonedDateTime.from( islamicDate ).withCalendar( 'gregory' );
  
  console.log( `Date in Islamic: ${ islamicDate.toPlainDate().toLocaleString( 'en-US', { calendar: 'islamic' } ) }` );
  console.log( `DateTime in Islamic in Dubai: ${ islamicDate.toLocaleString( 'en-US', { calendar: 'islamic' } ) }` );
  console.log( `DateTime in Islamic in London: ${ islamicDate.toInstant().toZonedDateTimeISO( 'Europe/London' ).toLocaleString('en-US', { calendar: 'islamic' } ) }` );  
  
  console.log( `Date in Hebrew: ${ hebrewDate.toPlainDate().toLocaleString( 'en-US', { calendar: 'hebrew' } ) }` );
  console.log( `DateTime in Hebrew in Dubai: ${ hebrewDate.toLocaleString( 'en-US', { calendar: 'hebrew' } ) }` );
  console.log( `DateTime in Hebrew in London: ${ hebrewDate.toInstant().toZonedDateTimeISO( 'Europe/London' ).toLocaleString('en-US', { calendar: 'hebrew' } ) }` );
  
  console.log( `Date in Gregorian: ${ gregoryDate.toPlainDate().toLocaleString( 'en-US' ) }` );
  console.log( `DateTime in Gregorian: ${ gregoryDate.toLocaleString( 'en-US' ) }` ); 
  
  console.log( `Islamic Date in English (United States) Locale:\n${ islamicDate.toPlainDate().toString() }` );
  console.log( `Islamic DateTime in English (United States) Locale:\n${ islamicDate.toString() }` );
  
</script>

(Updated the Code Snippet to better exemplify the conversion between timeZones and calendars, in addition to various means of displaying the dates.)

Leave a Comment