const zodiacSigns = [ "Rat", // Rat "Ox", // Ox "Tiger", // Tiger "Rabbit", // Rabbit "Dragon", // Dragon "Snake", // Snake "Horse", // Horse "Goat", // Goat "Monkey", // Monkey "Rooster", // Rooster "Dog", // Dog "Pig" // Pig ]; var startMonth = ["Jadi/Bozghale", "Delow/Abriz", "Hoot/Mahi", "Hamal/Barre", "Soor/Gav", "Jowza/Do-peykar", "Sarra-taan", "Asad/Shir", "Sonbole/Dooshize ya Khooshe", "Mizan/Tarazo", "Aghrab", "Ghoos/Kamaan"]; const lunarNewYearCycle = [0, 31, 19, 8, 28, 16, 5, 25, 13, 2, 22, 10, 30, 18, 7, 27, 15, 4, 24, 12, 1, 21, 9, 29, 17, 6, 26, 14, 3, 23, 11]; var monthsP = ["Farvardin", "Ordibehesht", "Khordad", "Tir", "Mordad", "Shahrivar", "Mehr", "Aaban", "Aazar", "Dey", "Bahman", "Esfand"]; var monthsH = ["Muharram", "Safar", "Rabi' al-Awwal","Rabi' al-Thani", "Jumada al-Awwal", "Jumada al-Thani","Rajab", "Sha'ban", "Ramazan","Shawwal", "Dhul-Qi'dah", "Dhul-Hijjah"]; var monthsG = ["January", "February", "March","April", "May", "June","July", "August", "September","October", "November", "December"]; var monthsGP = ["January", "February", "March","April", "May", "June","July", "August", "September","October", "November", "December"]; var weekDaysPersian = ["Shanbeh", "Yek-Shanbeh", "Do-Shanbeh", "Se-Shanbeh", "Chahr-Shanbeh", "Panj-Shanbeh", "Joom-e"]; var weekDaysGC = ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]; var weekDaysG = ["SAT", "SUN", "MON", "TUE", "WED", "THU", "FRI"]; var wheelColor =["#f39c12","#f1c40f","#e67e22","#d35400","#e74c3c","#c0392b","#1abc9c","#16a085","#2ecc71","#27ae60","#3498db","#2980b9","#9b59b6","#8e44ad","#34495e","#2c3e50","#000","#7f8c8d","#95a5a6","#cbd0d3","#ecf0f1"]; var eventsPersian = [ ["1/1", "First of Nowruz", 1], ["1/2", "secound of Nowruz", 1], ["1/3", "Third of Nowruz", 1], ["1/4", "Forth Nowruz", 1], ["1/6", "Feast Aabpashan of Aabrizgan", 0], ["1/12", "Day of the Islamic Republic of Iran", 1], ["1/13", "Sizdah be Dar/Nature day", 1], ["1/19", "Feast Farvardin-gaan", 0], ["2/3", "FeastOrdibehesht-gaan", 0], ["3/6", "Feast Khordad-gaan", 0], ["3/14", "Death anniversary of founder of the Islamic Republic", 1], ["3/15", "Anniversary of Uprising 15 Khordad", 1], ["4/1", "Cheleh Tammooz", 0], ["4/6", "Feast Niloofar", 0], ["4/13", "Feast Tirgan", 0], ["5/7", "Feast Amordad-gaan", 0], ["6/4", "Feast Shahrivar-gaan", 0], ["7/10", "Feast Mehr-gaan", 0], ["8/10", "Feast Aban-gaan", 0], ["9/9", "Feast Azar-gaan", 0], ["9/30", "Yalda Night", 0], ["10/1", "Feast Khoram Rooz", 0], ["10/10", "Feast Sadeh", 0], ["11/2", "Feast Bahman-gaan", 0], ["11/22", "Anniversary Islamic revolution", 1], ["12/5", "Feast Sepandarmazd-gaan", 0], ["12/15", "Remember to plant Sabzeh Eid", 0], ["12/29", "Nationalization of the Iranian oil industry", 1] ]; const dynamicHolidays = { // keys formatted as "month,week,day" "1,2,1": { name: "//President's Day", type: 1, country: "US" },//President's Day // "2,1,0": { name: "Daylight Savings Time Begins", type: 1, country: "US" }, "4,2,0": { name: "Mother's Day", type: 1, country: "US" },//Mother's Day "4,-1,1": { name: "Memorial Day", type: 1, country: "US" },//Memorial Day "5,3,0": { name: "Father's Day", type: 1, country: "US" },//Father's Day "8,1,1": { name: "Labor Day", type: 1, country: "US" },//Labor Day "9,2,1": { name: "Columbus Day", type: 1, country: "US" },//Columbus Day // "10,1,0": { name: "Daylight Savings Time Ends", type: 1, country: "US" }, "11,4,4": { name: "Thanksgiving Day", type: 1, country: "US" },//Thanksgiving Day "11,4,5": { name: "Black Friday", type: 0, country: "US" }//Black Friday }; var eventsIslamic = [ ["1/9","Taa-Soo-Aa",1], ["1/10","Aa-Shooraa",1], ["2/20","Arbayin",1], ["2/28","Rehlat Hazrate Mohamad",1], ["2/30","Martyrdom of Emam Reza",1], ["3/8","Martyrdom of Emam Hasan Askari",1], ["3/17","Birth of hazrate Mohamad",1], ["6/3","Martyrdom of hazrate Fateme",1], ["7/13","Birth of Hazrat Ali",1], ["7/27","Revelation of hazrate Mohammad",1], ["8/15","Nime Shaban",1], ["9/21","Martyrdom of Hazrat Ali",1], ["10/1","Eid Fetr",1], ["10/2","Feast of Eid Fetr",1], ["10/25","Martyrdom of Emam Jafar Sadegh",1], ["12/10","Eid Ghorban",1], ["12/18","Eid Ghadir",1] ]; var eventsGregorian = [["1/1","First of January","Global"],["1/3","Baaresh-Shahabi Rab-ee",0,"Global"],["2/14","Valentine's Day",0,"Global"],["8/11","Baaresh-Shahabi Barsavoshi",0,"Global"],["10/21","Baaresh-Shahabi Jabari",0,"Global"],["10/31","Halloween",0,"Global"],["11/17","Baaresh-Shahabi Asadi",0,"Global"],["12/13","Baaresh-Shahabi Jozaayi",0,"Global"],["12/25", "Christmas Day", "Global"]]; var eventsGregorianRef = [["1/1","First of January","Global"],["1/3","Baaresh-Shahabi Rab-ee",0,"Global"],["2/14","Valentine's Day",0,"Global"],["8/11","Baaresh-Shahabi Barsavoshi",0,"Global"],["10/21","Baaresh-Shahabi Jabari",0,"Global"],["10/31","Halloween",0,"Global"],["11/17","Baaresh-Shahabi Asadi",0,"Global"],["12/13","Baaresh-Shahabi Jozaayi",0,"Global"],["12/25", "Christmas Day", "Global"]]; var latitude = [-34.6037, 35.6764, 39.9042, 34.0549, 21.3099, -33.9221, 51.5072, 40.7128, 19.4326, 38.7223, 32.6539, 29.5926, 48.8575,38.0792, 31.8974, 33.8688, 36.2972, 43.6532, 52.5200]; var longitude = [-58.3816, 139.6500, 116.4074, -118.2426 , -157.8581, 18.4231, 0.1276, -74.0060, -99.1332, -9.1393, 51.6660, 52.5836, 2.3514, 46.2887, 54.3569, 151.2093, 59.6067, -79.3832, 13.4050]; var cityName = ['Buenos Aires', 'Tokiyo', ' Beijing', 'Los Angeles' , 'Hono Lulu', 'Cape Town', 'London', 'New York', 'Mexico City', 'Losabon', 'Isfahan', 'Shiraz', 'Paris', 'Tabriz', 'Yazd', 'Sydney', 'Mashad','Toronto', 'Berlin']; const newYearDates = ['1401/1/1 08:12AM', '1402/12/29 12:12PM', '1403/12/29 16:12PM']; var today = new Date(); var todayYear = today.getFullYear(); var todayMonth = today.getMonth() + 1; var todayDay = today.getDate(); // Convert today to Persian var todayWeekDay = today.getDay(); var todayStamp = today.getTime(); calculateEvents(todayYear); var firstDayPersianMonth = calcGregorianToPersian(todayYear, todayMonth,todayDay); var persianMonthOverviewYear = firstDayPersianMonth[0]; var persianMonthOverviewMonth = firstDayPersianMonth[1]; var persianMonthOverviewDay = firstDayPersianMonth[2]; var persianMonthOverviewYearPeriod = firstDayPersianMonth[0]; var persianMonthOverviewMonthPeriod = firstDayPersianMonth[1]; var persianMonthOverviewDayPeriod = firstDayPersianMonth[2]; var todayIslamicDate = calcGregorianToIslamic(todayYear,todayMonth,todayDay); var islamicYear = todayIslamicDate[0]; var islamicMonth = todayIslamicDate[1]; var islamicDay = todayIslamicDate[2]; document.getElementById("calnderOverView1").innerHTML = toFarsiNumber(firstDayPersianMonth[2]) + '
' + monthsP[firstDayPersianMonth[1]-1] + '
' + toFarsiNumber(firstDayPersianMonth[0]); document.getElementById("calnderOverView2").innerHTML = toFarsiNumber(todayDay) + '
' + monthsGP[todayMonth-1] + '
' + toFarsiNumber(todayYear); document.getElementById("calnderOverView3").innerHTML = toFarsiNumber(todayIslamicDate[2]) + '
' + monthsH[todayIslamicDate[1]-1] + '
' + toFarsiNumber(todayIslamicDate[0]); document.getElementById("calnderOverView4").innerHTML = weekDaysGC[todayWeekDay+1]; document.getElementById("calnderOverView5").innerHTML = 'Zodiac sign ' + getZodiac2(today.getMonth()+1, todayDay); document.getElementById("calnderOverView6").innerHTML = ' ' + getChineseZodiac(todayYear,today.getMonth(),todayDay); function calculateEvents(year, country = null) { const localEvents = [...eventsGregorianRef]; // Clone the existing events array //alert(year); // Calculate dynamic holidays and add them to the localEvents array for (const key in dynamicHolidays) { const [month, week, dayOfWeek] = key.split(',').map(Number); const holiday = dynamicHolidays[key]; if (country === null || country === holiday.country || holiday.country === "Global") { const day = calculateNthWeekday(year, month - 1, week, dayOfWeek); if (day !== -1) { const dateStr = `${month}/${day}`; localEvents.push([dateStr, holiday.name, holiday.type, holiday.country]); } } } // Sort the localEvents array by date localEvents.sort((a, b) => { const [monthA, dayA] = a[0].split('/').map(Number); const [monthB, dayB] = b[0].split('/').map(Number); return monthA === monthB ? dayA - dayB : monthA - monthB; }); // Update the global events array eventsGregorian.length = 0; // Clear the original events array eventsGregorian.push(...localEvents); // Update with sorted events } function calculateNthWeekday(year, month, nth, dayOfWeek) { let date = new Date(year, month, 1); // Start at the first day of the month let offset = (7 + dayOfWeek - date.getDay()) % 7; // Adjust to the desired dayOfWeek let day = nth >= 0 ? 1 + offset + (nth - 1) * 7 // Forward calculation for nth week : new Date(year, month + 1, 0).getDate() - ((7 + new Date(year, month + 1, 0).getDay() - dayOfWeek) % 7); // Backward calculation for last week return new Date(year, month, day).getMonth() === month ? day : -1; // Verify the day is within the month } function randomIntFromInterval(min, max) { // min and max included return Math.floor(Math.random() * (max - min + 1) + min); } function convertDateType() { var htmlDay = ''; var htmlMonth = ''; var selectedOption = ''; convertTtpe = document.calenderConvertor.convertType.selectedIndex; // alert(convertTtpe); if(convertTtpe==1) { document.calenderConvertor.year.value = document.calenderConvertor.hidden_year_persian.value; for (i = 1; i <= 31; i++) { if (document.calenderConvertor.hidden_day_persian.value==i) selectedOption = 'selected'; htmlDay = htmlDay + ""; selectedOption = ''; } daySelectID = ''; for (k = 0; k < monthsG.length; k++) { if (document.calenderConvertor.hidden_month_persian.value==k+1) selectedOption = 'selected'; htmlMonth = htmlMonth + ""; selectedOption = ''; } monthSelectID = ''; } else if(convertTtpe==2) { document.calenderConvertor.year.value = document.calenderConvertor.hidden_year_hij.value; for (i = 1; i <= 31; i++) { if (document.calenderConvertor.hidden_day_hij.value==i) selectedOption = 'selected'; htmlDay = htmlDay + ""; selectedOption = ''; } daySelectID = ''; for (k = 0; k < monthsG.length; k++) { if (document.calenderConvertor.hidden_month_hij.value==k+1) selectedOption = 'selected'; htmlMonth = htmlMonth + ""; selectedOption = ''; } monthSelectID = ''; } else { document.calenderConvertor.year.value = document.calenderConvertor.hidden_year_gregorian.value; for (i = 1; i <= 31; i++) { if (document.calenderConvertor.hidden_day_gregorian.value==i) selectedOption = 'selected'; htmlDay = htmlDay + ""; selectedOption = ''; } daySelectID = ''; for (k = 0; k < monthsG.length; k++) { if (document.calenderConvertor.hidden_month_gregorian.value==k+1) selectedOption = 'selected'; htmlMonth = htmlMonth + ""; selectedOption = ''; } monthSelectID = ''; } document.getElementById("daySelectID").innerHTML = daySelectID; document.getElementById("monthSelectID").innerHTML = monthSelectID; } convertDate(); function convertDate() { if(isNumeric(document.calenderConvertor.year.value)) { convertTtpe = document.calenderConvertor.convertType.selectedIndex; if(convertTtpe==1) { calcPersian(); } else if(convertTtpe==2) { calcIslamic(); } else { document.calenderConvertor.hidden_year_gregorian.value = document.calenderConvertor.year.value document.calenderConvertor.hidden_month_gregorian.value = document.calenderConvertor.month.selectedIndex document.calenderConvertor.hidden_day_gregorian.value = document.calenderConvertor.day.value calcGregorian(); } } else { alert('Enter a numeric value for year!'); } } function getZodiac2(month, day){ //bound is zero indexed and returns the day of month where the boundary occurs //ie. bound[0] = 20; means January 20th is the boundary for a zodiac sign var bound = [20,19,20,20,20,21,22,22,21,22,21,21]; //startMonth is zero indexed and returns the zodiac sign of the start of that month //ie. startMonth[0] = "Capricorn"; means start of January is Zodiac Sign "Capricorn" monthIndex = month-1; //so we can use zero indexed arrays if (day <= bound[monthIndex]){ //it's start of month -- before or equal to bound date signMonthIndex = monthIndex; }else{ //it must be later than bound, we use the next month's startMonth signMonthIndex = (monthIndex+1) % 12; //mod 12 to loop around to January index. } return startMonth[signMonthIndex]; //return the Zodiac sign of start Of that month. } // let today = new Date().toLocaleDateString('fa-IR'); //alert(today); //let options = { year: 'numeric', month: 'long', day: 'numeric' }; //let today = new Date().toLocaleDateString('fa-IR', options); function isNumeric(value) { return /^-?\d+$/.test(value); } function calculateNextRamazan() { //Get Server Date via ajax! //https://blog.bitsrc.io/calculate-the-difference-between-two-2-dates-e1d76737c05a //alert(todayYear+'-'+todayMonth+'-'+todayDay); var ramazanIslamicYear = islamicYear; if (todayIslamicDate[1]>=9) ramazanIslamicYear++; var ramazanPersianDate = calcIslamicToPersian(ramazanIslamicYear,9,1); var ramazanGregorianDate = calcIslamicToGregorian(ramazanIslamicYear,9,1); document.getElementById("nextTripPlannerEvents").innerHTML += 'Next Ramazen will be ' + toFarsiNumber(ramazanPersianDate[2]) + ' ' + monthsP[ramazanPersianDate[1]-1] + ' ' + toFarsiNumber(ramazanPersianDate[0])+ ' that '; var ramazanDateStamp = new Date(ramazanGregorianDate[1]+'-'+ramazanGregorianDate[2]+'-'+ramazanGregorianDate[0]); timeDiffRamazan = new Date(ramazanDateStamp - todayStamp); timeDiffRamazanDaysRemain = Number(Math.abs(timeDiffRamazan.getDate()) - 1); timeDiffRamazanMonthsRemain = Number(Math.abs(timeDiffRamazan.getMonth())); timeDiffRamazanTotalDaysRemain = timeDiffRamazanMonthsRemain * 30.417 + timeDiffRamazanDaysRemain; timeDiffRamazanWeeksRemain = ( timeDiffRamazanTotalDaysRemain >= 7 ) ? timeDiffRamazanTotalDaysRemain / 7 : 0; if(timeDiffRamazanMonthsRemain==0) { document.getElementById("nextTripPlannerEvents").innerHTML += ' ' + toFarsiNumber(timeDiffRamazanDaysRemain) + ' day(s) ' + ' remain.'; } else { document.getElementById("nextTripPlannerEvents").innerHTML += ' ' + toFarsiNumber(timeDiffRamazanMonthsRemain) + ' month(s) ' + toFarsiNumber(timeDiffRamazanDaysRemain) + ' day(s) ' + ' remain.'; } } //document.getElementById("tempCalendar").innerHTML=getPersianMonthOverview(1403, 9); getPersianMonthOverview(persianMonthOverviewYear, persianMonthOverviewMonth); function getPersianMonthOverview(persianYear, persianMonth) { var gregorianDate, islamicDate, gregorianDateText, islamicDateText, isFriday, isPersianHoliday, isIslamicHoliday, isToday, eventsPersianValue; var isPersianHoliday, isIslamicHoliday, eventsPersianText; const currentEvents = document.getElementById('currentEvents'); currentEvents.innerHTML = 'Events of ' + monthsP[persianMonth-1] + ' ' + toFarsiNumber(persianYear) + '
'; const calendarDiv = document.getElementById('calendar'); calendarDiv.innerHTML = ''; // Vorherigen Kalender leeren const currentMonthDiv = document.getElementById('current-month'); currentMonthDiv.textContent = monthsP[persianMonth-1] + ' ' + toFarsiNumber(persianYear); weekDaysG.forEach(day => { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'week-day'); dayDiv.textContent = day; calendarDiv.appendChild(dayDiv); }); var firstDayPersianMonthGregorian = calcPersianToGregorian(persianYear, persianMonth, 1); calculateEvents(firstDayPersianMonthGregorian[0]); var firstDayPersianMonth = calcGregorianToPersian(firstDayPersianMonthGregorian[0], firstDayPersianMonthGregorian[1], firstDayPersianMonthGregorian[2]); var daysInPersianMonth = getDaysInPersianMonth(persianYear, persianMonth, firstDayPersianMonth[4]); let firstDayOfMonth = calcPersianToGregorian(persianYear, persianMonth, 1)[3]+1; //const firstDayOfMonth = dayOfWeek; const startOffset = ((firstDayOfMonth) % 7 ); // Montag als erster Tag if(persianMonth==1) { var prevMonth = 12; var prevMonthFirstDay = calcPersianToGregorian(persianYear-1, prevMonth, 1); } else { var prevMonth = persianMonth - 1; var prevMonthFirstDay = calcPersianToGregorian(persianYear, prevMonth, 1); } var firstDayPreviuodPersianMonth = calcGregorianToPersian(prevMonthFirstDay[0], prevMonthFirstDay[1], prevMonthFirstDay[2]); var prevMonthDays = getDaysInPersianMonth(persianYear-1, prevMonth, firstDayPersianMonth[4]); for (let i = startOffset-1 ; i >= 0; i--) { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); //dayDiv.textContent = prevMonthDays - i; calendarDiv.appendChild(dayDiv); //getDayPhase(persianYear, prevMonth, prevMonthDays - i,dayDiv); } for (let day = 1; day <= daysInPersianMonth; day++) { isPersianHoliday = -1; isIslamicHoliday = -1; gregorianDate = calcPersianToGregorian(persianYear, persianMonth, day); islamicDate = calcGregorianToIslamic(gregorianDate[0], gregorianDate[1], gregorianDate[2]); if(day==1) { var gregorianDateMonthFirst= gregorianDate[1]; var islamicDateMonthFirst= islamicDate[1]; } eventsPersianValue = eventsPersian.findIndex(arr => arr.includes(`${persianMonth}/${day}`)); if(eventsPersianValue!=-1) { isPersianHoliday = eventsPersian[eventsPersianValue][2]; currentEvents.innerHTML += '' + toFarsiNumber(day) + ' ' + monthsP[persianMonth-1] + ' ' + eventsPersian[eventsPersianValue][1] + ' (' + gregorianDate[2] + ' ' + monthsG[gregorianDate[1]-1] + ')
'; } eventsIslamicValue = eventsIslamic.findIndex(arr => arr.includes(`${islamicDate[1]}/${islamicDate[2]}`)); if(eventsIslamicValue!=-1) { isIslamicHoliday = eventsIslamic[eventsIslamicValue][2]; currentEvents.innerHTML += '' + toFarsiNumber(day) + ' ' + monthsP[persianMonth-1] + ' ' + eventsIslamic[eventsIslamicValue][1] + ' (' + toFarsiNumber(islamicDate[2]) + ' ' + monthsH[islamicDate[1]-1] + ') (' + gregorianDate[2] + ' ' + monthsG[gregorianDate[1]-1] + ')
'; } eventsGregorianValue = eventsGregorian.findIndex(arr => arr.includes(`${gregorianDate[1]}/${gregorianDate[2]}`)); if(eventsGregorianValue!=-1){ isGregorianHoliday = eventsGregorian[eventsGregorianValue][2]; currentEvents.innerHTML += '' + toFarsiNumber(day) + ' ' + monthsP[persianMonth-1] + ' ' + eventsGregorian[eventsGregorianValue][1] + ' (' + gregorianDate[2] + ' ' + monthsG[gregorianDate[1]-1] + ')
'; } isToday = gregorianDate[0] === todayYear && gregorianDate[1] === todayMonth && gregorianDate[2] === todayDay; const dayDiv = document.createElement('div'); dayDiv.classList.add('day'); if (isToday) dayDiv.innerHTML += ''; dayDiv.innerHTML += ''+toFarsiNumber(day)+''; dayDiv.innerHTML += ''+gregorianDate[2]+''; //dayDiv.innerHTML += ''+toFarsiNumber(islamicDate[2])+''; if(gregorianDate[3]==5)dayDiv.classList.add('dayFirHoliDay'); if( isPersianHoliday==1 || isIslamicHoliday==1) { eventsPersianText = ''; eventsIslamicText = ''; dayDiv.classList.add('dayFirHoliDay'); dayDiv.classList.add('shimmer'); if (isPersianHoliday==1) eventsPersianText = ' ' + eventsPersian[eventsPersianValue][1] + ' '; if (isIslamicHoliday==1) { eventsIslamicText = ' ' + eventsIslamic[eventsIslamicValue][1] + ' '; dayDiv.innerHTML += ''+toFarsiNumber(islamicDate[2])+''; } dayDiv.title = eventsPersianText + eventsIslamicText; //dayDiv.innerHTML += 'x'; } calendarDiv.appendChild(dayDiv); } /* var gregorianDateMonthSecound= gregorianDate[1]; var islamicDateMonthSecound= islamicDate[1]; //currentMonthDiv.innerHTML = currentMonthDiv.innerHTML + '
'; if(islamicDateMonthFirst!=islamicDateMonthSecound) { currentMonthDiv.innerHTML = currentMonthDiv.innerHTML + '
' + monthsH[islamicDateMonthFirst-1] + ' ' + monthsH[islamicDateMonthSecound-1] + ''; } else { currentMonthDiv.innerHTML = currentMonthDiv.innerHTML + '
' + monthsH[islamicDateMonthFirst-1] + ''; } if(gregorianDateMonthFirst!=gregorianDateMonthSecound) { currentMonthDiv.innerHTML = currentMonthDiv.innerHTML + '
' + monthsGP[gregorianDateMonthFirst-1] + ' ' + monthsGP[gregorianDateMonthSecound-1] + ''; } else { currentMonthDiv.innerHTML = currentMonthDiv.innerHTML + '
' + monthsGP[gregorianDateMonthFirst-1] + ''; } */ const endOffset = (7 - ((daysInPersianMonth + startOffset) % 7)) % 7; for (let i = 1; i <= endOffset; i++) { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); //dayDiv.textContent = i; //getDayPhase(persianYear + (persianMonth === 12 ? 1 : 0), (persianMonth % 12) + 1, i, dayDiv); calendarDiv.appendChild(dayDiv); } } function getPersianMonthOverviewForward() { persianMonthOverviewMonth++; if(persianMonthOverviewMonth==13) { persianMonthOverviewMonth = 1; persianMonthOverviewYear++; } getPersianMonthOverview(persianMonthOverviewYear, persianMonthOverviewMonth); } function getPersianMonthOverviewBackward() { persianMonthOverviewMonth--; if(persianMonthOverviewMonth==0) { persianMonthOverviewMonth = 12; persianMonthOverviewYear--; } getPersianMonthOverview(persianMonthOverviewYear, persianMonthOverviewMonth); } function getPersianMonthOverview1yForward() { persianMonthOverviewYear++; getPersianMonthOverview(persianMonthOverviewYear, persianMonthOverviewMonth); } function getPersianMonthOverview1yBackward() { persianMonthOverviewYear--; getPersianMonthOverview(persianMonthOverviewYear, persianMonthOverviewMonth); } function getDaysInPersianMonth(year, month, isLeap) { // 31 days for Farvardin, Ordibehesht, Khordad, Tir, Mehr, Aban, Azar if (month <= 6) return 31; // 30 days for Dey, Bahman, Esfand (not leap), 29 for Esfand (leap) if (month <= 11) return 30; return isLeap ? 30 : 29; } function getNextEvents(eventDates, today, eventCount) { //var myNextEvent = getNextEvents(eventDates, '3/5'); --> alert(myNextEvent[0]['date']); // Parse today's date into month and day const [todayMonth, todayDay] = today.split('/').map(Number); // Function to parse a date string into a comparable object function parseDate(dateStr) { const [month, day] = dateStr.split('/').map(Number); return { month, day }; } // Convert event dates to an array of parsed date objects const parsedEvents = eventDates.map(([date, description, holiday]) => ({ date: parseDate(date), description, holiday })); // Sort events with current date for comparison parsedEvents.sort((a, b) => { if (a.date.month === b.date.month) { return a.date.day - b.date.day; } return a.date.month - b.date.month; }); // Identify today's index for comparison let startIndex = parsedEvents.findIndex(event => { const { month, day } = event.date; return month > todayMonth || (month === todayMonth && day >= todayDay); }); // Handle the case where no future events in the same year are found if (startIndex === -1) { startIndex = 0; // Start from the beginning of the array } // Collect the next two events, accounting for wrap-around var nextEvents; switch (eventCount) { case 2: nextEvents = [parsedEvents[startIndex],parsedEvents[(startIndex + 1) % parsedEvents.length]]; break; case 3: nextEvents = [parsedEvents[startIndex],parsedEvents[(startIndex + 1) % parsedEvents.length],parsedEvents[(startIndex + 2) % parsedEvents.length]]; break; default: nextEvents = [parsedEvents[startIndex]]; } // Format the output return nextEvents.map(event => ({ date: `${event.date.month}/${event.date.day}`, month: event.date.month, day: event.date.day, description: event.description, holiday: event.holiday })); } function findLastTuesday(year, newYearDates) { //alert(findLastTuesday(1402, newYearDates)); // Output: '12/22' if '12/29' is an exception const persianMonth = 12; // Last Persian month const newYearExceptions = newYearDates.map(date => date.split(" ")[0]); // Extract just the date parts j = persian_to_jd(year, 12, 1); perscal = jd_to_persian(j); leap = leap_persian(perscal[0]); let persianMonthDays = leap ? 30 : 29; //color:red; // Start from the last day of the 12th month and move backward for (let day = persianMonthDays; day > 20; day--) { j = persian_to_jd(year, persianMonth, day); weekday = jwday(j); if (weekday === 2) { // 2 = Tuesday dateOfTuesday = `${persianMonth}/${day}`; if (newYearExceptions.includes(dateOfTuesday)) { // If the date is in exceptions, check the previous Tuesday return `${persianMonth}/${day - 7}`; } return dateOfTuesday; // Return valid last Tuesday } } return null; // If no Tuesday is found } function toFarsiNumber(n) { //const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; const farsiDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; return n .toString() .split('') .map(x => farsiDigits[x]) .join(''); } function getRandomColorIndex(colorCount) { return randomIntFromInterval(0,wheelColor.length-colorCount); } var colorIndex = getRandomColorIndex(4); document.getElementById("calnderOverView1").style.backgroundColor = wheelColor[colorIndex]; document.getElementById("calnderOverView2").style.backgroundColor = wheelColor[colorIndex+1]; document.getElementById("calnderOverView3").style.backgroundColor = wheelColor[colorIndex+2]; document.getElementById("calnderOverView4").style.backgroundColor = wheelColor[colorIndex+3]; document.getElementById("calnderOverView5").style.backgroundColor = wheelColor[colorIndex]; document.getElementById("calnderOverView6").style.backgroundColor = wheelColor[colorIndex+2]; const currentMonthNextEvents = document.getElementById('currentMonthNextEvents'); const currentMonthNextGregorianEvents = document.getElementById('currentMonthNextGregorianEvents'); const currentMonthNextIslamicEvents = document.getElementById('currentMonthNextIslamicEvents'); nextEventPersian = getNextEvents(eventsPersian, `${persianMonthOverviewMonth}/${persianMonthOverviewDay}`, 2); nextEventIslamic = getNextEvents(eventsIslamic, `${islamicMonth}/${islamicDay}`, 2); nextEventGregorian = getNextEvents(eventsGregorian, `${todayMonth}/${todayDay}`, 2); for (let i = 0 ; i < nextEventPersian.length; i++) { currentMonthNextEvents.innerHTML += '' + toFarsiNumber(nextEventPersian[i]['day']) + ' ' + monthsP[nextEventPersian[i]['month']-1] + ' ' + nextEventPersian[i]['description'] + '
'; } //currentMonthNextEvents.innerHTML += 'ش.'; for (let i = 0 ; i < nextEventIslamic.length; i++) { var nextIslamicEventPersian = calcIslamicToPersian(islamicYear,nextEventIslamic[i]['month'],nextEventIslamic[i]['day']); currentMonthNextIslamicEvents.innerHTML += '' + toFarsiNumber(nextIslamicEventPersian[2]) + ' ' + monthsP[nextIslamicEventPersian[1]-1] + ' ' + nextEventIslamic[i]['description'] + ' (' + toFarsiNumber(nextEventIslamic[i]['day']) + ' ' + monthsH[nextEventIslamic[i]['month']-1] + ')
'; } //currentMonthNextIslamicEvents.innerHTML += 'ق.'; for (let i = 0 ; i < nextEventGregorian.length; i++) { var nextGregorianEventPersian = calcGregorianToPersian(todayYear,nextEventGregorian[i]['month'],nextEventGregorian[i]['day']); currentMonthNextGregorianEvents.innerHTML += '' + toFarsiNumber(nextGregorianEventPersian[2]) + ' ' + monthsP[nextGregorianEventPersian[1]-1] + ' ' + nextEventGregorian[i]['description'] + ' (' + toFarsiNumber(nextEventGregorian[i]['day']) + ' ' + monthsGP[nextEventGregorian[i]['month']-1] + ')
'; } //currentMonthNextGregorianEvents.innerHTML += 'م.'; currentMonthNextEvents.style.border = "1px solid "+wheelColor[colorIndex]; currentMonthNextGregorianEvents.style.border = "1px solid "+wheelColor[colorIndex+2]; currentMonthNextIslamicEvents.style.border = "1px solid "+wheelColor[colorIndex+1];; calculateNextRamazan(); function populateDateSelectors() { const yearSelect = document.getElementById('yearSelectPeriod'); const monthSelect = document.getElementById('monthSelectPeriod'); const daySelect = document.getElementById('daySelectPeriod'); selectedOption = ''; for (let year = 1403; year <= 1410; year++) { if (year==firstDayPersianMonth[0]) selectedOption = 'selected'; yearSelect.innerHTML += ``; selectedOption = ''; } for (let month = 1; month <= 12; month++) { if (month==persianMonthOverviewMonth) selectedOption = 'selected';//persianMonthOverviewMonth monthSelect.innerHTML += ``; selectedOption = ''; } for (let day = 1; day <= 31; day++) { if (day==persianMonthOverviewDay) selectedOption = 'selected';//persianMonthOverviewDay daySelect.innerHTML += ``; selectedOption = ''; } } function setPeriod() { const year = parseInt(document.getElementById('yearSelectPeriod').value); const month = parseInt(document.getElementById('monthSelectPeriod').value); const day = parseInt(document.getElementById('daySelectPeriod').value); //persianMonthOverviewYear = year; //persianMonthOverviewMonth = month; //persianMonthOverviewDay = day; cycleDuration = parseInt(document.getElementById('cycleDuration').value); cycleStartDay = { year, month, day }; getPersianMonthOverviewPeriod(year, month); document.getElementById('periodButtonsLast').style.display = 'block'; document.getElementById('periodButtonsNext').style.display = 'block'; document.getElementById('calendarHeaderPeriod').style.background = 'darkgray'; document.getElementById('calendarHeaderPeriod2').style.background = 'darkgray'; } function getPersianMonthOverviewPeriod(persianYear, persianMonth) { var isPersianHoliday, isIslamicHoliday, eventsPersianText; const calendarDiv = document.getElementById('calendarPeriod'); calendarDiv.innerHTML = ''; // Vorherigen Kalender leeren const currentMonthDiv = document.getElementById('current-month-period'); currentMonthDiv.textContent = monthsP[persianMonth-1] + ' ' + toFarsiNumber(persianYear); weekDaysG.forEach(day => { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'week-day'); dayDiv.textContent = day; calendarDiv.appendChild(dayDiv); }); var firstDayPersianMonthGregorian = calcPersianToGregorian(persianYear, persianMonth, 1); var firstDayPersianMonth = calcGregorianToPersian(firstDayPersianMonthGregorian[0], firstDayPersianMonthGregorian[1], firstDayPersianMonthGregorian[2]); var daysInPersianMonth = getDaysInPersianMonth(persianYear, persianMonth, firstDayPersianMonth[4]); let firstDayOfMonth = calcPersianToGregorian(persianYear, persianMonth, 1)[3]+1; //const firstDayOfMonth = dayOfWeek; startOffset = (firstDayOfMonth + 7) % 7; // Montag als erster Tag if(persianMonth==1) { var prevMonth = 12; var prevMonthFirstDay = calcPersianToGregorian(persianYear-1, prevMonth, 1); } else { var prevMonth = persianMonth - 1; var prevMonthFirstDay = calcPersianToGregorian(persianYear, prevMonth, 1); } var firstDayPreviuodPersianMonth = calcGregorianToPersian(prevMonthFirstDay[0], prevMonthFirstDay[1], prevMonthFirstDay[2]); var prevMonthDays = getDaysInPersianMonth(persianYear-1, prevMonth, firstDayPersianMonth[4]); for (let i = startOffset - 1; i >= 0; i--) { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); //dayDiv.textContent = prevMonthDays - i; calendarDiv.appendChild(dayDiv); //getDayPhase(persianYear, prevMonth, prevMonthDays - i,dayDiv); } for (let day = 1; day <= daysInPersianMonth; day++) { isPersianHoliday = -1; isIslamicHoliday = -1; gregorianDate = calcPersianToGregorian(persianYear, persianMonth, day); islamicDate = calcPersianToIslamic(persianYear, persianMonth, day); eventsPersianValue = eventsPersian.findIndex(arr => arr.includes(`${persianMonth}/${day}`)); if(eventsPersianValue!=-1) isPersianHoliday = eventsPersian[eventsPersianValue][2]; eventsIslamicValue = eventsIslamic.findIndex(arr => arr.includes(`${islamicDate[1]}/${islamicDate[2]}`)); if(eventsIslamicValue!=-1) isIslamicHoliday = eventsIslamic[eventsIslamicValue][2]; isToday = gregorianDate[0] === todayYear && gregorianDate[1] === todayMonth && gregorianDate[2] === todayDay; const dayDiv = document.createElement('div'); dayDiv.classList.add('day'); if (isToday) dayDiv.innerHTML += ''; dayDiv.innerHTML += ''+toFarsiNumber(day)+''; if(gregorianDate[3]==5)dayDiv.classList.add('dayFirHoliDay'); if( isPersianHoliday==1 || isIslamicHoliday==1) { eventsPersianText = ''; eventsIslamicText = ''; dayDiv.classList.add('dayFirHoliDay'); dayDiv.classList.add('shimmer'); if (isPersianHoliday==1) eventsPersianText = ' ' + eventsPersian[eventsPersianValue][1] + ' '; if (isIslamicHoliday==1) eventsIslamicText = ' ' + eventsIslamic[eventsIslamicValue][1] + ' '; dayDiv.title = eventsPersianText + eventsIslamicText; //dayDiv.innerHTML += 'x'; } getDayPhase(persianYear, persianMonth, day, dayDiv); calendarDiv.appendChild(dayDiv); } endOffset = (7 - ((daysInPersianMonth + startOffset) % 7)) % 7; for (let i = 1; i <= endOffset; i++) { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); //dayDiv.textContent = i; //getDayPhase(persianYear + (persianMonth === 12 ? 1 : 0), (persianMonth % 12) + 1, i, dayDiv); calendarDiv.appendChild(dayDiv); } var persianMonth2 = persianMonth+1; var persianYear2 = persianYear; if(persianMonth2==13) { persianMonth2 = 1; persianYear2++; } const calendarDiv2 = document.getElementById('calendarPeriod2'); calendarDiv2.innerHTML = ''; // Vorherigen Kalender leeren const currentMonthDiv2 = document.getElementById('current-month-period2'); currentMonthDiv2.textContent = monthsP[persianMonth2-1] + ' ' + toFarsiNumber(persianYear2); weekDaysG.forEach(day => { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'week-day'); dayDiv.textContent = day; calendarDiv2.appendChild(dayDiv); }); firstDayPersianMonthGregorian = calcPersianToGregorian(persianYear2, persianMonth2, 1); firstDayPersianMonth = calcGregorianToPersian(firstDayPersianMonthGregorian[0], firstDayPersianMonthGregorian[1], firstDayPersianMonthGregorian[2]); daysInPersianMonth = getDaysInPersianMonth(persianYear2, persianMonth2, firstDayPersianMonth[4]); firstDayOfMonth = calcPersianToGregorian(persianYear2, persianMonth2, 1)[3]+1; //const firstDayOfMonth = dayOfWeek; startOffset = (firstDayOfMonth + 7) % 7; // Montag als erster Tag if(persianMonth2==1) { var prevMonth2 = 12; var prevMonthFirstDay = calcPersianToGregorian(persianYear2-1, prevMonth2, 1); } else { var prevMonth2 = persianMonth2 - 1; var prevMonthFirstDay = calcPersianToGregorian(persianYear2, prevMonth2, 1); } firstDayPreviuodPersianMonth = calcGregorianToPersian(prevMonthFirstDay[0], prevMonthFirstDay[1], prevMonthFirstDay[2]); prevMonthDays = getDaysInPersianMonth(persianYear2-1, prevMonth2, firstDayPersianMonth[4]); for (let i = startOffset - 1; i >= 0; i--) { const dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); calendarDiv2.appendChild(dayDiv); } for (let day = 1; day <= daysInPersianMonth; day++) { isPersianHoliday = -1; isIslamicHoliday = -1; gregorianDate = calcPersianToGregorian(persianYear2, persianMonth2, day); islamicDate = calcPersianToIslamic(persianYear2, persianMonth2, day); eventsPersianValue = eventsPersian.findIndex(arr => arr.includes(`${persianMonth2}/${day}`)); if(eventsPersianValue!=-1) isPersianHoliday = eventsPersian[eventsPersianValue][2]; eventsIslamicValue = eventsIslamic.findIndex(arr => arr.includes(`${islamicDate[1]}/${islamicDate[2]}`)); if(eventsIslamicValue!=-1) isIslamicHoliday = eventsIslamic[eventsIslamicValue][2]; isToday = gregorianDate[0] === todayYear && gregorianDate[1] === todayMonth && gregorianDate[2] === todayDay; dayDiv = document.createElement('div'); dayDiv.classList.add('day'); if (isToday) dayDiv.innerHTML += ''; dayDiv.innerHTML += ''+toFarsiNumber(day)+''; if(gregorianDate[3]==5)dayDiv.classList.add('dayFirHoliDay'); if( isPersianHoliday==1 || isIslamicHoliday==1) { eventsPersianText = ''; eventsIslamicText = ''; dayDiv.classList.add('dayFirHoliDay'); dayDiv.classList.add('shimmer'); if (isPersianHoliday==1) eventsPersianText = ' ' + eventsPersian[eventsPersianValue][1] + ' '; if (isIslamicHoliday==1) eventsIslamicText = ' ' + eventsIslamic[eventsIslamicValue][1] + ' '; dayDiv.title = eventsPersianText + eventsIslamicText; //dayDiv.innerHTML += 'x'; } getDayPhase(persianYear2, persianMonth2, day, dayDiv); calendarDiv2.appendChild(dayDiv); } endOffset = (7 - ((daysInPersianMonth + startOffset) % 7)) % 7; for (let i = 1; i <= endOffset; i++) { dayDiv = document.createElement('div'); dayDiv.classList.add('day', 'prev-next-month'); calendarDiv2.appendChild(dayDiv); } } function calculateDaysBetween(y1, m1, d1, y2, m2, d2) { var persianDate1 = calcPersianToGregorian(y1, m1, d1); var persianDate2 = calcPersianToGregorian(y2, m2, d2); const dateCurrent = new Date(persianDate1[0],persianDate1[1]-1,persianDate1[2]); const dateStart = new Date(persianDate2[0],persianDate2[1]-1,persianDate2[2]); let diffInDays = Math.round((dateCurrent - dateStart) / (1000 * 60 * 60 * 24)); // Correct negative day shifts within the cycle if (diffInDays < 0) { diffInDays = (cycleDuration + (diffInDays % cycleDuration)) % cycleDuration; } return diffInDays; } function getDayPhase(year, month, day, dayDiv) { if (!cycleStartDay) return ''; const daysSinceStart = calculateDaysBetween(year, month, day, cycleStartDay.year, cycleStartDay.month, cycleStartDay.day); const dayInCycle = daysSinceStart % cycleDuration; const phases = calculatePhases(cycleDuration); if (dayInCycle < phases.menstruation) { //dayDiv.classList.add('menstruation'); //dayDiv.innerHTML += '🚽'; dayDiv.innerHTML += '

'; } else if (dayInCycle >= phases.fertileStart && dayInCycle < phases.ovulation) { //dayDiv.classList.add('fertile'); //dayDiv.innerHTML += '💩'; dayDiv.innerHTML += '

'; } else if (dayInCycle === phases.ovulation) { //dayDiv.classList.add('ovulation'); //dayDiv.innerHTML += '💥'; dayDiv.innerHTML += '

'; } else if (dayInCycle > phases.ovulation && dayInCycle <= phases.lutealStart) { //dayDiv.classList.add('implantation'); //dayDiv.innerHTML += '🌳'; dayDiv.innerHTML += '

'; } } function changeMonthPeriod(direction) { persianMonthOverviewMonthPeriod += direction; if (persianMonthOverviewMonthPeriod > 12) { persianMonthOverviewMonthPeriod = 1; persianMonthOverviewYearPeriod++; } else if (persianMonthOverviewMonthPeriod < 1) { persianMonthOverviewMonthPeriod = 12; persianMonthOverviewYearPeriod--; } getPersianMonthOverviewPeriod(persianMonthOverviewYearPeriod, persianMonthOverviewMonthPeriod); } function calculatePhases(cycleLength) { const lutealPhase = 14; const ovulationDay = cycleLength - lutealPhase; const fertileStart = ovulationDay - 5; const menstruationDays = 5; return { menstruation: menstruationDays, fertileStart: fertileStart, ovulation: ovulationDay, lutealStart: ovulationDay + 1, lutealEnd: cycleLength, }; } populateDateSelectors(); var cityIndex = Math.floor(Math.random() * 15) var startLng = longitude[cityIndex]; var startLat = latitude[cityIndex]; updateTimes(); var map = L.map('map').setView([35.6975, 51.3556], 7); L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map); //e.latlng.lat,e.latlng.lng setTimeout(function(){ map.flyTo([latitude[cityIndex], longitude[cityIndex]]); document.getElementById("cityName").innerHTML=cityName[cityIndex]},1); function onMapClick(e) { startLng = e.latlng.lng; startLat = e.latlng.lat; document.getElementById("cityName").innerHTML = ''; var nominatimURL = 'https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat='+startLat+'&lon='+startLng; fetch(nominatimURL) .then(response => response.json()) .then(data => { var cityName = ''; if(data.address.city==null) { if(data.address.town!=null) cityName = data.address.town; } else { cityName = data.address.city; } document.getElementById("cityName").innerHTML = data.address.country + ' -> ' + cityName; }); updateTimes(); //alert(e.latlng.lat + "-" + e.latlng.lng); // map.panTo(new L.LatLng(e.latlng.lat, e.latlng.lng)); //alert(e.latlng.lat + ' ' + e.latlng.lng) map.flyTo([e.latlng.lat, e.latlng.lng]) } const sunposarea_width = 330; const sunposarea_height = 100; const sunposarea_sunSize = 40; const sunposarea_horizonY = sunposarea_height+3;// - sunSize / 2; const sunposarea_leftMargin = 20; const sunposarea_rightMargin = 20; const sunposarea_topMargin = 5; function updateTimes() { var date = new Date(); // today var prayTimes = new PrayTimes(); prayTimes.setMethod('Tehran'); //alert('http://api.timezonedb.com/v2/get-time-zone?key=LI87WADLR5CM&format=json&by=position&lat='+startLat+'&lng='+startLng); var nominatimURL = 'https://api.timezonedb.com/v2/get-time-zone?key=LI87WADLR5CM&format=json&by=position&lat='+startLat+'&lng='+startLng; fetch(nominatimURL).then(response => response.json()).then(data => { var gmtOffset = data.gmtOffset/3600; var formatted = data.formatted; //var locationNameDetails = 'Region:' + data.regionName+'
City : '+data.cityName + '
Zone Name:'+ data.zoneName; //document.getElementById('locationNameDetails').innerHTML = locationNameDetails; var times = prayTimes.getTimes(date, [startLat, startLng], gmtOffset); var list = ['Fajr', 'Sunrise', 'Dhuhr', 'Asr', 'Maghrib', 'Isha', 'Midnight']; var list1 = ['Azan Sobh', 'TolooE Khorshid', 'Azan zohr', '!!', 'Azan Maghrib', '!!', 'Nime Shab']; var html = ''; html += ''; for(var i in list) { if(list1[i]!='!!') { html += ''; html += ''; } if(list1[i]=='TolooE Khorshid') locationsunrise = times[list[i].toLowerCase()]; if(list1[i]=='Azan Maghrib') locationsunset = times[list[i].toLowerCase()]; } html += ''; html += '
'+ formatted + '
'+ list1[i] + ''+ times[list[i].toLowerCase()] + '
Sun
'; document.getElementById('oghatTimeTable').innerHTML = html; const container = document.getElementById('sunContainer'); const sun = document.getElementById('sun'); const currentime = new Date(formatted); var localtodayYear = currentime.getFullYear(); var localtodayMonth = currentime.getMonth() + 1; var localtodayDay = currentime.getDate(); // Convert today to Persian locationsunrise_time = locationsunrise.split(':'); locationsunset_time = locationsunset.split(':'); const sunrise = new Date(localtodayYear,localtodayMonth-1,localtodayDay,locationsunrise_time[0],locationsunrise_time[1]); const sunset = new Date(localtodayYear,localtodayMonth-1,localtodayDay,locationsunset_time[0],locationsunset_time[1]); if (currentime >= sunrise && currentime <= sunset) { container.style.backgroundColor = 'lightblue'; } else { container.style.backgroundColor = 'darkblue'; } const curvePoints = 40; const curveData = []; const midPoint = Math.floor(curvePoints / 2); for (let i = 0; i <= curvePoints; i++) { const x = (i / curvePoints) * (sunposarea_width - sunposarea_leftMargin - sunposarea_rightMargin) + sunposarea_leftMargin; const t = i / curvePoints; const curveHeight = sunposarea_height - sunposarea_topMargin - sunposarea_sunSize / 2; const y = sunposarea_horizonY - Math.sin(Math.PI * t) * curveHeight; curveData.push({x, y}); } curveData.forEach(point => { const dot = document.createElement('div'); dot.className = 'sunLine'; dot.style.left = `${point.x}px`; dot.style.top = `${point.y}px`; container.appendChild(dot); }); let sunX, sunY, imageSrc; if (currentime < sunrise) { sunX = 10; sunY = sunposarea_horizonY-25; imageSrc = '/images/sun-32.png'; } else if (currentime > sunset) { sunX = sunposarea_width - sunposarea_sunSize - 10; sunY = sunposarea_horizonY-25; imageSrc = '/images/sun-32.png'; } else { const dayDuration = sunset - sunrise; const timeSinceSunrise = currentime - sunrise; const progress = timeSinceSunrise / dayDuration; const curveIndex = Math.floor(progress * (curveData.length - 1)); const position = curveData[curveIndex]; sunX = position.x - sunposarea_sunSize / 2; sunY = position.y - sunposarea_sunSize / 2; imageSrc = '/images/sun-32-y.png'; } sun.src = imageSrc; sun.style.left = `${sunX}px`; sun.style.top = `${sunY}px`; if (sunY + sunposarea_sunSize > sunposarea_height) { const overlap = sunY + sunposarea_sunSize - sunposarea_height; sun.style.clipPath = `inset(0 0 ${overlap}px 0)`; } else { sun.style.clipPath = 'inset(0 0 0 0)'; } }) .catch((error) => { alert(error); }); } map.on('click', onMapClick); function getLunarNewYear(year) { const index = (year - 1900) % 30; const lunarDay = lunarNewYearCycle[index]; return new Date(year, 0, lunarDay); } function getChineseZodiac(year, month, day) { const lunarNewYear = getLunarNewYear(year); const inputDate = new Date(year, month - 1, day); // Determine the zodiac year based on whether the date is before or after Lunar New Year const zodiacYear = inputDate < lunarNewYear ? year - 1 : year; // The Chinese zodiac cycle repeats every 12 years. const index = (zodiacYear - 4) % 12; // 4 is the starting point for the Rat in 1900. return zodiacSigns[index >= 0 ? index : index + 12]; } htmlCity = ''; /* for (i = 0; i <= 581; i++) { htmlCity += ""; } document.getElementById("cityListID").innerHTML = '