بهترین راه برای افزایش مهارت در یک زبان برنامه نویسی، حل مسائل مختلف است. با تمرین زیاد می توان الگوریتم های فراوان آموخته و توانایی حل مسئله ی خود را نیز افزایش دهیم. در این پروژه که با Javascript و Html نوشته شده است و در ظاهر آن هم Bootstrap به کار رفته است، با انتخاب مناطق زمانی دلخواه، ساعت آنالوگ آن منطقه نمایش داده می شود. در ادامه به بررسی توابع استفاده شده در این پروژه می پردازیم.

<head> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.3/css/all.css" integrity="sha384-SZXxX4whJ79/gErwcOYf+zWLeJdY/qpuqC4cAa9rOGUstPomtqpuNWT9wdPEn2fk" crossorigin="anonymous"> </head>
بعد از افزودن لینک های bootstrap و font awesome که برای زیباتر شدن پروژه استفاده شده است، قسمت body را مطابق کد زیر اضافه می کنیم.
<body> <div class="container"> <div class="row"> <div class="col-md-8"> <div class="input-group mb-3"> <select id="Timezone" class="form-select" aria-label="Default select example"> <option value="0" selected>منطقه زمانی مورد نظر را اضافه کنید</option> </select> <button onclick="deleteAllElementInEveryWhere()" class="btn btn-outline-danger" type="button" id="button-addon2">حذف همه</button> <button onclick="addItem()" class="btn btn-outline-success" type="button" id="button-addon2">افزودن</button> </div> </div> </div> <div id="MainElement" class="row"> </div> </div> </body>

و در نهایت این اسکریپت را اضافه می کنیم.
<script> var dropDownElement = document.getElementById("Timezone"); var timezoneList = ["Africa/Abidjan", "Africa/Accra", "Africa/Algiers", "Africa/Bissau", "Africa/Cairo", "Africa/Casablanca", "Africa/Ceuta", "Africa/El_Aaiun", "Africa/Johannesburg", "Africa/Juba", "Africa/Khartoum", "Africa/Lagos", "Africa/Maputo", "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Sao_Tome", "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", "America/Adak", "America/Anchorage", "America/Araguaina", "America/Argentina/Buenos_Aires", "America/Argentina/Catamarca", "America/Argentina/Cordoba", "America/Argentina/Jujuy", "America/Argentina/La_Rioja", "America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", "America/Argentina/San_Juan", "America/Argentina/San_Luis", "America/Argentina/Tucuman", "America/Argentina/Ushuaia", "America/Asuncion", "America/Atikokan", "America/Bahia", "America/Bahia_Banderas", "America/Barbados", "America/Belem", "America/Belize", "America/Blanc-Sablon", "America/Boa_Vista", "America/Bogota", "America/Boise", "America/Cambridge_Bay", "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Cayenne", "America/Chicago", "America/Chihuahua", "America/Costa_Rica", "America/Creston", "America/Cuiaba", "America/Curacao", "America/Danmarkshavn", "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", "America/Edmonton", "America/Eirunepe", "America/El_Salvador", "America/Fort_Nelson", "America/Fortaleza", "America/Glace_Bay", "America/Goose_Bay", "America/Grand_Turk", "America/Guatemala", "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", "America/Hermosillo", "America/Indiana/Indianapolis", "America/Indiana/Knox", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Inuvik", "America/Iqaluit", "America/Jamaica", "America/Juneau", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Maceio", "America/Managua", "America/Manaus", "America/Martinique", "America/Matamoros", "America/Mazatlan", "America/Menominee", "America/Merida", "America/Metlakatla", "America/Mexico_City", "America/Miquelon", "America/Moncton", "America/Monterrey", "America/Montevideo", "America/Nassau", "America/New_York", "America/Nipigon", "America/Nome", "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/Nuuk", "America/Ojinaga", "America/Panama", "America/Pangnirtung", "America/Paramaribo", "America/Phoenix", "America/Port-au-Prince", "America/Port_of_Spain", "America/Porto_Velho", "America/Puerto_Rico", "America/Punta_Arenas", "America/Rainy_River", "America/Rankin_Inlet", "America/Recife", "America/Regina", "America/Resolute", "America/Rio_Branco", "America/Santarem", "America/Santiago", "America/Santo_Domingo", "America/Sao_Paulo", "America/Scoresbysund", "America/Sitka", "America/St_Johns", "America/Swift_Current", "America/Tegucigalpa", "America/Thule", "America/Thunder_Bay", "America/Tijuana", "America/Toronto", "America/Vancouver", "America/Whitehorse", "America/Winnipeg", "America/Yakutat", "America/Yellowknife", "Antarctica/Casey", "Antarctica/Davis", "Antarctica/DumontDUrville", "Antarctica/Macquarie", "Antarctica/Mawson", "Antarctica/Palmer", "Antarctica/Rothera", "Antarctica/Syowa", "Antarctica/Troll", "Antarctica/Vostok", "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", "Asia/Ashgabat", "Asia/Atyrau", "Asia/Baghdad", "Asia/Baku", "Asia/Bangkok", "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Brunei", "Asia/Chita", "Asia/Choibalsan", "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Hebron", "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", "Asia/Kamchatka", "Asia/Karachi", "Asia/Kathmandu", "Asia/Khandyga", "Asia/Kolkata", "Asia/Krasnoyarsk", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Macau", "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Nicosia", "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qostanay", "Asia/Qyzylorda", "Asia/Riyadh", "Asia/Sakhalin", "Asia/Samarkand", "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Thimphu", "Asia/Tokyo", "Asia/Tomsk", "Asia/Ulaanbaatar", "Asia/Urumqi", "Asia/Ust-Nera", "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yangon", "Asia/Yekaterinburg", "Asia/Yerevan", "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", "Atlantic/Cape_Verde", "Atlantic/Faroe", "Atlantic/Madeira", "Atlantic/Reykjavik", "Atlantic/South_Georgia", "Atlantic/Stanley", "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", "Australia/Perth", "Australia/Sydney", "CET", "CST6CDT", "EET", "EST", "EST5EDT", "Etc/GMT", "Etc/GMT+1", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12", "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", "Etc/GMT+5", "Etc/GMT+6", "Etc/GMT+7", "Etc/GMT+8", "Etc/GMT+9", "Etc/GMT-1", "Etc/GMT-10", "Etc/GMT-11", "Etc/GMT-12", "Etc/GMT-13", "Etc/GMT-14", "Etc/GMT-2", "Etc/GMT-3", "Etc/GMT-4", "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", "Etc/GMT-8", "Etc/GMT-9", "Etc/UTC", "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belgrade", "Europe/Berlin", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", "Europe/Chisinau", "Europe/Copenhagen", "Europe/Dublin", "Europe/Gibraltar", "Europe/Helsinki", "Europe/Istanbul", "Europe/Kaliningrad", "Europe/Kiev", "Europe/Kirov", "Europe/Lisbon", "Europe/London", "Europe/Luxembourg", "Europe/Madrid", "Europe/Malta", "Europe/Minsk", "Europe/Monaco", "Europe/Moscow", "Europe/Oslo", "Europe/Paris", "Europe/Prague", "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/Saratov", "Europe/Simferopol", "Europe/Sofia", "Europe/Stockholm", "Europe/Tallinn", "Europe/Tirane", "Europe/Ulyanovsk", "Europe/Uzhgorod", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", "Europe/Warsaw", "Europe/Zaporozhye", "Europe/Zurich", "HST", "Indian/Chagos", "Indian/Christmas", "Indian/Cocos", "Indian/Kerguelen", "Indian/Mahe", "Indian/Maldives", "Indian/Mauritius", "Indian/Reunion", "MET", "MST", "MST7MDT", "PST8PDT", "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", "Pacific/Chatham", "Pacific/Chuuk", "Pacific/Easter", "Pacific/Efate", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Fiji", "Pacific/Funafuti", "Pacific/Galapagos", "Pacific/Gambier", "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", "Pacific/Majuro", "Pacific/Marquesas", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", "Pacific/Pohnpei", "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Tahiti", "Pacific/Tarawa", "Pacific/Tongatapu", "Pacific/Wake", "Pacific/Wallis", "WET"]; var ctxArray = []; var radiusArray = []; var timezoneArray = []; var index = 0; var count = 0; initialTimezonesDrp(); addAllClockInLocalStorageToBody(); function initialTimezonesDrp() { this.timezoneList.forEach(addOptionTSelect); } function addOptionTSelect(item, index) { var option = document.createElement("option"); option.setAttribute("value", ++index); var text = document.createTextNode(item); option.appendChild(text); this.dropDownElement.appendChild(option); } function addItem() { var select = document.getElementById("Timezone"); var selectedValue = select.value; var selectedText = select.options[select.selectedIndex].text; if (selectedValue === "0") { alert('لطفا منطقه زمانی مورد نظرتان را انتخاب نمیید') } else { var e = document.getElementById("ddlViewBy"); var timezoneStoraged = localStorage.getItem("timezoneList"); var str = selectedText; if (timezoneStoraged != null) str = timezoneStoraged + "," + selectedText; localStorage.setItem("timezoneList", str) deleteAllElement(); createElement(selectedText); } } function deleteAllElement() { var main = document.getElementById("MainElement").innerHTML = ""; } function deleteAllElementInEveryWhere() { var main = document.getElementById("MainElement").innerHTML = ""; localStorage.setItem("timezoneList", ""); } function createElement() { addAllClockInLocalStorageToBody(); } function addAllClockInLocalStorageToBody() { var timezoneList = localStorage.getItem("timezoneList"); var items = timezoneList.split(","); for (var timezone of items) { if (timezone != "") { var mainElement = document.getElementById("MainElement"); var cardBodyDiv = document.createElement("div"); cardBodyDiv.setAttribute("class", "card-body"); var cardTitleH5 = document.createElement("span"); cardTitleH5.setAttribute("class", "card-title"); var title = document.createTextNode(timezone); cardTitleH5.appendChild(title); var btnDiv = document.createElement("button"); var text = document.createTextNode("حذف"); btnDiv.appendChild(text); btnDiv.setAttribute("class", "btn btn-danger"); btnDiv.setAttribute("data-timezone", timezone); btnDiv.addEventListener("click", onDeleteTimezone); //btnDiv.onclick = mmmmmmm(timezone); cardBodyDiv.appendChild(cardTitleH5); var i = document.createElement("i"); i.setAttribute("class", timezone + " status"); var cardTextp = document.createElement("p"); cardTextp.setAttribute("class", "card-text"); cardTextp.appendChild(i); cardBodyDiv.appendChild(cardTextp); cardBodyDiv.appendChild(btnDiv); var canvas = document.createElement("canvas"); canvas.setAttribute('class', "card-img-top clock"); canvas.setAttribute('width', 150); canvas.setAttribute('height', 150); canvas.setAttribute('data-timezone', timezone); var cardDiv = document.createElement("div"); cardDiv.setAttribute("class", "card"); var colmd = document.createElement("div"); colmd.setAttribute("class", "col-md-3"); colmd.setAttribute("data-main-timezone", timezone); cardDiv.appendChild(canvas); cardDiv.appendChild(cardBodyDiv); colmd.appendChild(cardDiv); mainElement.appendChild(colmd); } } initial(); } function onDeleteTimezone(timezone) { var currentTimezone = timezone.target.attributes["data-timezone"].value; removeFromLocalStorage(currentTimezone); var e = document.querySelectorAll('[data-main-timezone="' + currentTimezone + '"]'); e[0].remove() } function removeFromLocalStorage(str) { var timezoneList = localStorage.getItem("timezoneList"); var newString = timezoneList.replace(str, ''); var timezoneList = localStorage.setItem("timezoneList", newString); } function initial() { var elements = document.getElementsByClassName("clock"); if (elements.length > 0) { window.count = elements.length; for (i = 0; i < elements.length; i++) { window.ctxArray[i] = elements[i].getContext("2d"); window.radiusArray[i] = elements[i].height / 2; window.ctxArray[i].translate(window.radiusArray[i], window.radiusArray[i]); window.radiusArray[i] = window.radiusArray[i] * 0.90; window.timezoneArray[i] = elements[i].dataset.timezone; } setInterval(drawClock, 1000); } } function drawClock() { for (i = 0; i < window.count; i++) { window.index = i; drawFace(); drawNumbers(); drawTime(); } } function drawFace() { var grad; window.ctxArray[index].beginPath(); window.ctxArray[index].arc(0, 0, window.radiusArray[index], 0, 2 * Math.PI); window.ctxArray[index].fillStyle = 'white'; window.ctxArray[index].fill(); grad = window.ctxArray[index].createRadialGradient(0, 0, window.radiusArray[index] * 0.95, 0, 0, window.radiusArray[index] * 1.05); grad.addColorStop(0, '#333'); grad.addColorStop(0.5, 'white'); grad.addColorStop(1, '#333'); window.ctxArray[index].strokeStyle = grad; window.ctxArray[index].lineWidth = window.radiusArray[index] * 0.1; window.ctxArray[index].stroke(); window.ctxArray[index].beginPath(); window.ctxArray[index].arc(0, 0, window.radiusArray[index] * 0.1, 0, 2 * Math.PI); window.ctxArray[index].fillStyle = '#333'; window.ctxArray[index].fill(); } function drawNumbers() { var ang; var num; window.ctxArray[index].font = window.radiusArray[index] * 0.15 + "px arial"; window.ctxArray[index].textBaseline = "middle"; window.ctxArray[index].textAlign = "center"; for (num = 1; num < 13; num++) { ang = num * Math.PI / 6; window.ctxArray[index].rotate(ang); window.ctxArray[index].translate(0, -window.radiusArray[index] * 0.85); window.ctxArray[index].rotate(-ang); window.ctxArray[index].fillText(num.toString(), 0, 0); window.ctxArray[index].rotate(ang); window.ctxArray[index].translate(0, window.radiusArray[index] * 0.85); window.ctxArray[index].rotate(-ang); } } function setStatusIcon(timezone, status) { //debugger; var classString = timezone + " status"; var el = document.getElementsByClassName(classString); if (el[0] != undefined) { el[0].classList.remove["bi"]; el[0].classList.remove["bi-moon-fill"]; el[0].classList.remove["bi-sun-fill"]; el[0].classList.remove[classString]; if (status == "PM") el[0].setAttribute("class", classString + " fa fa-moon"); else el[0].setAttribute("class", classString + " fa fa-sun"); } } function drawTime() { var now = new Date().toLocaleTimeString("en-US", { timeZone: window.timezoneArray[index] }); var splited = now.split(" "); var splited1 = splited[0].split(":") var hour = parseInt(splited1[0]); setStatusIcon(window.timezoneArray[index], splited[1]); if (splited[1] === "PM") hour = parseInt(splited1[0]) + 12; var minute = parseInt(splited1[1]); var second = parseInt(splited1[2]); hour = hour % 12; hour = (hour * Math.PI / 6) + (minute * Math.PI / (6 * 60)) + (second * Math.PI / (360 * 60)); drawHand(window.ctxArray[index], hour, window.radiusArray[index] * 0.5, window.radiusArray[index] * 0.07); minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60)); drawHand(window.ctxArray[index], minute, window.radiusArray[index] * 0.8, window.radiusArray[index] * 0.07); second = (second * Math.PI / 30); drawHand(window.ctxArray[index], second, window.radiusArray[index] * 0.9, window.radiusArray[index] * 0.02); } function drawHand(ctx, pos, length, width) { ctx.beginPath(); ctx.lineWidth = width; ctx.lineCap = "round"; ctx.moveTo(0, 0); ctx.rotate(pos); ctx.lineTo(0, -length); ctx.stroke(); ctx.rotate(-pos); } </script>
عالی دست شما درد نکنه بسیار کاربری بود