nanakshahi-ical
Version:
Nanakshahi calendar iCal generator using official SGPC Jantri data with enhanced accuracy for Sikh religious observances.
250 lines (223 loc) • 8.02 kB
JavaScript
/**
* API Compatibility Layer
* Provides nanakshahi-js compatible API for easy migration
*/
const dateConversion = require('./date-conversion')
const gurpurabData = require('./gurpurab-data')
const movableGurpurabs = require('./movable-gurpurabs')
const calendarData = require('./calendar-data')
/**
* Get Nanakshahi date (compatible with nanakshahi-js.getNanakshahiDate)
* @param {Date} gregorianDate - JavaScript Date object
* @returns {Object} Nanakshahi date in English and Punjabi
*/
function getNanakshahiDate (gregorianDate = new Date()) {
const nanakshahiDate = dateConversion.getNanakshahiDate(gregorianDate)
if (!nanakshahiDate) {
return null
}
// Format to match nanakshahi-js structure
return {
gregorianDate,
englishDate: {
month: nanakshahiDate.englishDate.month,
monthName: nanakshahiDate.englishDate.monthName,
date: nanakshahiDate.englishDate.date,
year: nanakshahiDate.englishDate.year,
day: nanakshahiDate.englishDate.day,
dayShort: nanakshahiDate.englishDate.day.substring(0, 3)
},
punjabiDate: {
month: toGurmukhiNum(nanakshahiDate.englishDate.month),
monthName: nanakshahiDate.punjabiDate.monthName,
date: toGurmukhiNum(nanakshahiDate.englishDate.date),
year: toGurmukhiNum(nanakshahiDate.englishDate.year),
day: nanakshahiDate.punjabiDate.day,
dayShort: nanakshahiDate.punjabiDate.day.substring(0, 3)
},
leapYear: calendarData.getDaysInYear(nanakshahiDate.englishDate.year) === 366,
sgpcCompliant: true // Our special addition
}
}
/**
* Get Gregorian date from Nanakshahi date (compatible with nanakshahi-js.getDateFromNanakshahi)
* @param {number} nanakshahiDate - Nanakshahi date
* @param {number} nanakshahiMonth - Nanakshahi month (1-12)
* @param {number} nanakshahiYear - Nanakshahi year
* @returns {Date} Gregorian date
*/
function getDateFromNanakshahi (nanakshahiDate, nanakshahiMonth, nanakshahiYear) {
return dateConversion.getGregorianDate(nanakshahiYear, nanakshahiMonth, nanakshahiDate)
}
/**
* Get Gurpurabs for a specific day (compatible with nanakshahi-js.getGurpurabsForDay)
* @param {Date} gregorianDate - JavaScript Date object
* @returns {Array} Array of Gurpurabs for the day
*/
function getGurpurabsForDay (gregorianDate = new Date()) {
const fixedGurpurabs = gurpurabData.getGurpurabsForDay(gregorianDate)
const movableGurpurabsForDate = movableGurpurabs.getMovableGurpurabsForDate(gregorianDate)
// Combine fixed and movable Gurpurabs
const allGurpurabs = [...fixedGurpurabs, ...movableGurpurabsForDate]
// Format to match nanakshahi-js structure
return allGurpurabs.map(gurpurab => ({
en: gurpurab.en || gurpurab.name?.en || gurpurab.name,
pa: gurpurab.pa || gurpurab.name?.pa || gurpurab.nameGurmukhi,
type: gurpurab.type,
movable: gurpurab.movable || false,
sgpcCorrected: gurpurab.sgpcCorrected || false
}))
}
/**
* Get Gurpurabs for a specific month (compatible with nanakshahi-js.getGurpurabsForMonth)
* @param {number} nanakshahiMonth - Nanakshahi month (1-12)
* @param {number} nanakshahiYear - Nanakshahi year
* @returns {Array} Array of Gurpurabs for the month
*/
function getGurpurabsForMonth (nanakshahiMonth, nanakshahiYear) {
// Get all gurpurabs for the year and filter by month
const allGurpurabs = gurpurabData.getAllGurpurabsForYear(nanakshahiYear)
const monthGurpurabs = allGurpurabs.filter(gurpurab => gurpurab.nanakshahiDate.month === nanakshahiMonth)
// Add movable Gurpurabs that fall in this month
const gregorianYear = nanakshahiYear + 1468
const movableGurpurabsForYear = movableGurpurabs.getMovableGurpurabsForYear(gregorianYear)
const movableInMonth = movableGurpurabsForYear.filter(gurpurab => {
const nanakshahiDate = dateConversion.getNanakshahiDate(gurpurab.gregorianDate)
return nanakshahiDate && nanakshahiDate.englishDate.month === nanakshahiMonth
})
return [...monthGurpurabs, ...movableInMonth].map(gurpurab => ({
date: gurpurab.nanakshahiDate?.day || gurpurab.date,
gurpurabs: [{
en: gurpurab.en || gurpurab.name?.en || gurpurab.name,
pa: gurpurab.pa || gurpurab.name?.pa || gurpurab.nameGurmukhi,
type: gurpurab.type,
movable: gurpurab.movable || false,
sgpcCorrected: gurpurab.sgpcCorrected || false
}]
}))
}
/**
* Find movable Gurpurab (compatible with nanakshahi-js.findMovableGurpurab)
* @param {string} gurpurab - Gurpurab name
* @param {number} year - Gregorian year
* @returns {Object} Gurpurab information
*/
function findMovableGurpurab (gurpurab, year = new Date().getFullYear()) {
const movableGurpurab = movableGurpurabs.findMovableGurpurab(gurpurab, year)
// Format to match nanakshahi-js structure
return {
gregorianDate: movableGurpurab.gregorianDate,
name: {
en: `${movableGurpurab.name.en} (${year})`,
pa: `${movableGurpurab.name.pa} (${year})`,
type: movableGurpurab.name.type,
movable: true,
sgpcSource: true // Our special addition
}
}
}
/**
* Convert number to Gurmukhi numerals
* @param {number} num - Number to convert
* @returns {string} Gurmukhi numeral
*/
function toGurmukhiNum (num) {
const gurmukhiNumerals = ['੦', '੧', '੨', '੩', '੪', '੫', '੬', '੭', '੮', '੯']
return num.toString().split('').map(digit => gurmukhiNumerals[parseInt(digit)]).join('')
}
/**
* Enhanced API functions (not in nanakshahi-js)
*/
/**
* Get SGPC compliance status
* @returns {Object} SGPC compliance information
*/
function getSGPCComplianceStatus () {
const currentYear = new Date().getFullYear()
const nanakshahiYear = currentYear - 1468
return {
sgpcCompliant: true,
version: '2.0-sgpc',
supportedYears: '2024-2035',
currentYear: nanakshahiYear,
corrections: {
july5Fixed: true,
jethLengthCorrected: true,
movableGurpurabs: true
},
features: {
accurateCalendar: true,
movableGurpurabs: true,
communityDriven: true,
sgpcCompliant: true
}
}
}
/**
* Get calendar data for a specific year
* @param {number} nanakshahiYear - Nanakshahi year
* @returns {Object} Calendar data
*/
function getCalendarData (nanakshahiYear) {
const monthLengths = calendarData.getMonthLengths(nanakshahiYear)
const allGurpurabs = gurpurabData.getAllGurpurabsForYear(nanakshahiYear)
return {
year: nanakshahiYear,
monthLengths,
totalDays: calendarData.getDaysInYear(nanakshahiYear),
status: calendarData.checkCalendarDataStatus(nanakshahiYear),
months: calendarData.NANAKSHAHI_MONTHS.en.map((month, index) => ({
name: month,
days: monthLengths[index],
index: index + 1
})),
gurpurabs: allGurpurabs
}
}
/**
* Validate date against SGPC calendar
* @param {Date} gregorianDate - Date to validate
* @returns {Object} Validation results
*/
function validateDate (gregorianDate) {
const nanakshahiDate = dateConversion.getNanakshahiDate(gregorianDate)
return {
valid: nanakshahiDate !== null,
nanakshahiDate,
sgpcCompliant: true,
corrections: []
}
}
/**
* Get migration helper for nanakshahi-js users
* @returns {Object} Migration information
*/
function getMigrationGuide () {
return {
from: 'nanakshahi-js',
to: 'sgpc-nanakshahi',
message: 'Successfully migrated to SGPC-compliant Nanakshahi calendar',
changes: [
'July 5th now correctly shows Miri Piri Divas',
'Jeth 2025 correctly has 32 days',
'All dates validated against SGPC calendar',
'Enhanced API with SGPC compliance information'
],
compatibility: 'Full API compatibility with nanakshahi-js maintained'
}
}
module.exports = {
// Compatible API functions
getNanakshahiDate,
getDateFromNanakshahi,
getGurpurabsForDay,
getGurpurabsForMonth,
findMovableGurpurab,
// Enhanced API functions
getSGPCComplianceStatus,
getCalendarData,
validateDate,
getMigrationGuide,
// Utility functions
toGurmukhiNum
}