Coptic Type Calendar Component React Native
Solution 1:
You need to explain what the rules are for adding a Coptic month.
For example, adding a month to dates in months 1 to 11 can be just adding 30 days. For dates in month 12, adding 30 days may push the date beyond the 13th month so into the first month of the following year. In this case, should the date be limited to the last day of month 13? So that adding 1 month to 30/12/1737 (5 Sep 2021) goes to 5/13/1737 rather than 25/01/1738 (30 days later).
Similarly, should adding one month to 1/13/1737 be 1/01/1738 (i.e. same day number in the following month) or 26/01/1738 (30 days later)?
Given a native ECMAScript Date, you can add a Coptic month by:
- Get the equivalent Coptic date
- If the Coptic month is 1 to 11, add 30 days
- If the Coptic month is 12, add 30 days and if the date goes beyond the end of month 13, set it to the last day of month 13
- If the Coptic month is 13, set the date to the same day in the following month
E.g.
// Given a date, return an object with era, year, month
// and day properties and values for the equivalent
// Coptic date
function getCopticDate(date = new Date()) {
return new Intl.DateTimeFormat(
'en-u-ca-coptic', {
year : 'numeric',
month: '2-digit',
day : '2-digit'
}).formatToParts(date).reduce((acc, part) => {
if (part.type != 'literal') {
acc[part.type] = part.value;
}
return acc;
}, Object.create(null));
}
// Given a Date, return a string for the equivalent
// Coptic date
function printCopticDate(date = new Date()) {
let {era, year, month, day} = getCopticDate(date);
return `${day}/${month}/${year} ${era}`;
}
// Given a Date, return a Date with one Coptic month
// added to to the equivalent Coptic date
function addCopticMonth(date) {
let oDate = new Date(date);
let d = getCopticDate(oDate);
// Add 30 days, then deal with months 12 and 13
oDate.setDate(oDate.getDate() + 30)
// If month was 12 and is now not 13, set to
// last day of 13
let e = getCopticDate(oDate);
if (d.month == '12' && e.month != '13') {
oDate.setDate(oDate.getDate() - e.day);
}
// If month was 13, set to same day in next month
if (d.month == '13') {
oDate.setDate(oDate.getDate() - e.day + +d.day)
}
return oDate;
}
// Some tests
// Add 1 month to today
let d = new Date();
console.log('Today is: ' + printCopticDate(d) +
' (' + d.toDateString() + ')');
let e = addCopticMonth(d);
console.log('+1 month: ' + printCopticDate(e) +
' (' + e.toDateString() + ')');
// Add 1 month to 20/12/1737 -> last day of 13th month
let f = new Date(2021, 7, 26);
let g = addCopticMonth(f);
console.log(printCopticDate(f) + ' (' +
f.toDateString() + ') +1 month is\n' +
printCopticDate(g) + ' (' + g.toDateString() + ')');
// Add 1 month to 05/13/1737 -> same day in first month of next year
let h = addCopticMonth(g);
console.log(printCopticDate(g) + ' (' +
g.toDateString() + ') +1 month is\n' +
printCopticDate(h) + ' (' + h.toDateString() + ')');
The above leverages Intl.DateTimeFormat and covers adding a single month, if you want to add more than one or add years, there's more work to do… It's really just to demonstrate an algorithm rather than provide a robust function (e.g. getCopticDate should probably be called getCopticDateParts and the values should be numbers not strings, etc.).
Post a Comment for "Coptic Type Calendar Component React Native"