Closed dr3 closed 5 years ago
~Blocked on https://github.com/bbc/simorgh/issues/637~
We're now using MomentJS.
Our previous Jalali implementation used the npm package jalaali-js
which appears to be a dependency of the moment-jalaali
package suggested in the description.
Below is the implementation in moment-ws
using jalaali-js
https://github.com/bbc/moment-ws/blob/master/src/helpers/jalali.js
var moment = require('moment-timezone/moment-timezone'),
jalali = require('jalaali-js');
function getJalaliString(gregorianMoment, jalaliMonths) {
var jalaliDate = jalali.toJalaali(gregorianMoment.year(), gregorianMoment.month()+1, gregorianMoment.date());
var output = jalaliDate.jd + ' ' + jalaliMonths[jalaliDate.jm-1] + ' ' + jalaliDate.jy;
return output;
}
function addJalaliDate(locale, jalaliMonths, jalaliFormats, gregorianString) {
var gregorianMoment = moment(gregorianString, jalaliFormats, locale, true);
// gregorianString must be in one of jalaliFormats, and return an isValid moment for
// Jalali calendar to be applied to - e.g this will exclude timeago timestamps
if (gregorianMoment.isValid() && jalaliMonths.length === 12) {
return gregorianString + ' - ' + getJalaliString(gregorianMoment, jalaliMonths);
} else {
return gregorianString;
}
};
exports.addJalaliDate = addJalaliDate;
We should evaluate each package based on their API and consistency with the rest of the timestamp code.
On implementation ensure that the package we choose to use is only loaded in the persian bundle. And the pashto in the future.
https://bundlephobia.com/result?p=moment-jalaali@0.8.3 = 69.7KB MINIFIED + GZIPPED (assuming this has all the timezone logic included, and should have moment as a peerDep)
https://bundlephobia.com/result?p=jalaali-js@1.1.0 = 989B MINIFIED + GZIPPED
The current shows Gregorian date is relying on psammead-timestamp-container here https://github.com/bbc/psammead/tree/latest/packages/containers/psammead-timestamp-container and this container component is build the markup for the Gregorian stamps in only Persian / Pashto languages like shown ۱ اوت ۲۰۱۸ which means 1st August 2018
The required is to show the corresponding date based on the Jalali calendar like ۱ اوت ۲۰۱۸ - ۱۰ مرداد ۱۳۹۷ منتشر شده
const JD = require('jalali-date');
const jdate = new JD(); // today Jalali Date
console.log("gregorian date:",jdate._d); //2019-08-07T13:50:54.369Z
// defining sample gregorian date from JD Date Object. var gD = new Date();
console.log(JD.toJalali(gD)) ; // the Jalali_date from gregorian [] [ 1397, 10, 3 ]
// get the Jalali conversion from Gregorian one var jD = new JD(JD.toJalali(gD));
console.log(jD.format("dddd DD MMMM YYYY")); // چهارشنبه 16 امرداد 1398 // persian day | month | year
- **the library** is easy to use gregorian to Jalali and vice versa but it doesn't support Pashto Jalali calendar month names
#### Solution
- Option 1: The mapping of the Gregorian stamps to jalali ones should be added to the **psammead-timestamp-container** based on locale passed and build new custom locals for Persin and Phasto and in this case we will not use the library **Jalali-date** and rely only on these custom defined locals like one used on WS here : https://github.com/bbc/moment-ws/tree/master/src/locale
- Option2 : to extend the **Jalali-date** to support Pashto dates the same way the library supports Persian
is there anyway this can be done that allows services that dont use Jalali to not include the to Jalali
logic? would require importing stuff into their service bundle
Relying on the approach used by WS to support calendar conversion from gregorian
to jalali
here is the implementation of Persian locale fa
. The Calendar conversions is done inside jalaliHelper
based on the locale passed. This means we back to use the implementation of moment-ws
var jalaliHelper = require('../../helpers/jalali');
; (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('moment-timezone/moment-timezone')) :
typeof define === 'function' && define.amd ? define(['moment'], factory) :
factory(global.moment)
}(this, function (moment) {
'use strict';
var LOCALE_CODE = 'fa',
LL_FORMAT = 'D MMMM YYYY';
// adding gregorian months in Persian language
var gregorianMonths = [
'ژانویه',
'فوریه',
'مارس',
'آوریل',
'ممکن است',
'ژوئن',
'جولای',
'اوت',
'سپتامبر',
'اکتبر',
'نوامبر',
'دسامبر'
];
var jalaliMonths = [
'فروردین',
'اردیبهشت',
'خرداد',
'تیر',
'مرداد',
'شهریور',
'مهر',
'آبان',
'آذر',
'دی',
'بهمن',
'اسفند'
];
var jalaliFormats = [
LL_FORMAT
];
// Ensure base Persian locale data is loaded
moment().locale(LOCALE_CODE);
moment.defineLocale(LOCALE_CODE, {
months: gregorianMonths,
longDateFormat: { LL: LL_FORMAT },
postformat: jalaliHelper.addJalaliDate.bind(null, LOCALE_CODE, jalaliMonths, jalaliFormats)
});
}));
// test data
var inputtedDates = [
new Date (2019, 7, 9, 1, 1, 1, 1),
new Date (2010, 1, 14, 15, 25, 50, 125),
new Date (2018, 2, 20, 1, 1, 1, 1),
new Date (2018, 2, 21, 1, 1, 1, 1),
new Date (2021, 2, 20, 1, 1, 1, 1),
new Date (2021, 2, 21, 1, 1, 1, 1)
];
/*
Gregorian and the corresponding Persian calendar month
'9 اوت 2019 - 18 مرداد 1398',
'14 فوریه 2010 - 25 بهمن 1388',
'20 مارس 2018 - 29 اسفند 1396',
'21 مارس 2018 - 1 فروردین 1397',
'20 مارس 2021 - 30 اسفند 1399',
'21 مارس 2021 - 1 فروردین 1400'
]*/
@ibMadbouly the moment implementation looks good. Could we do it like https://github.com/bbc/psammead/blob/latest/packages/utilities/psammead-locales/moment/yo.js where we use the default fa
locale in psammead-locales/moment/fa.js
, extend it, and use that in simorgh?
Summarising the decision on this:
moment-ws
and add our locale changes to psammead-locales
including Jalali month namesmoment-ws
JS code and tests (with updates/improvements)jalaali-js
again for calendar conversion unless we come across issues with itClosing this investigation issue and will create separate issues to implement.
Is your feature request related to a problem? Please describe. Following https://github.com/bbc/simorgh/issues/637 we need to add support for non-Gregorian datestamps, namely the Persian (Jalali/Khorshidi/Shamsi) Calendar. This calendar is required for both Persian and Pashto articles.
Describe the solution you'd like Add support to the timestamp container to allow the ability to toggle/extend the Gregorian date to include the Persian date for both Persian and Pashto.
If we decide to continue using MomentJs, we should aim to use a open source library such as https://www.npmjs.com/package/moment-jalaali, contributing to its repository if needed. If we go for a time stamp library without a popular Persian calendar library we should create one in a similar way, to ensure most possible reuse.
This should be paired on
Testing notes
Dev insight: Unit tests with snapshots, storybook and manual testing with persian speakers
Additional context Add any other context or screenshots about the feature request here.