You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
678 lines
33 KiB
678 lines
33 KiB
<!DOCTYPE html>
|
|
<html lang="fa" dir="rtl">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>راهنمای محاسبه اوقات شرعی - PrayTimes Class</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Tahoma', 'Arial', sans-serif;
|
|
line-height: 1.8;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: #333;
|
|
padding: 20px;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
border-radius: 15px;
|
|
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.header {
|
|
background: linear-gradient(45deg, #2c3e50, #34495e);
|
|
color: white;
|
|
padding: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.header h1 {
|
|
font-size: 2.5em;
|
|
margin-bottom: 10px;
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.header p {
|
|
font-size: 1.2em;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.content {
|
|
padding: 40px;
|
|
}
|
|
|
|
.section {
|
|
margin-bottom: 40px;
|
|
padding: 25px;
|
|
border-radius: 10px;
|
|
border-right: 5px solid #3498db;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.section h2 {
|
|
color: #2c3e50;
|
|
font-size: 1.8em;
|
|
margin-bottom: 20px;
|
|
padding-bottom: 10px;
|
|
border-bottom: 2px solid #ecf0f1;
|
|
}
|
|
|
|
.section h3 {
|
|
color: #34495e;
|
|
font-size: 1.4em;
|
|
margin: 20px 0 15px 0;
|
|
}
|
|
|
|
.code-block {
|
|
background: #2c3e50;
|
|
color: #ecf0f1;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
margin: 15px 0;
|
|
overflow-x: auto;
|
|
font-family: 'Courier New', monospace;
|
|
direction: ltr;
|
|
text-align: left;
|
|
white-space: pre-wrap;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.code-block pre {
|
|
margin: 0;
|
|
padding: 0;
|
|
background: none;
|
|
border: none;
|
|
font-family: inherit;
|
|
font-size: 14px;
|
|
white-space: pre-wrap;
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
.comment {
|
|
color: #95a5a6;
|
|
font-style: italic;
|
|
}
|
|
|
|
.keyword {
|
|
color: #3498db;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.string {
|
|
color: #e74c3c;
|
|
}
|
|
|
|
.number {
|
|
color: #f39c12;
|
|
}
|
|
|
|
.highlight {
|
|
background: #f39c12;
|
|
color: white;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.formula {
|
|
background: #e8f5e8;
|
|
border: 2px solid #27ae60;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
margin: 15px 0;
|
|
font-family: 'Courier New', monospace;
|
|
direction: ltr;
|
|
text-align: center;
|
|
}
|
|
|
|
.step {
|
|
background: #fff3cd;
|
|
border-right: 4px solid #ffc107;
|
|
padding: 15px;
|
|
margin: 15px 0;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.step-number {
|
|
background: #ffc107;
|
|
color: white;
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: bold;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.prayer-times-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 20px 0;
|
|
background: white;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.prayer-times-table th,
|
|
.prayer-times-table td {
|
|
padding: 12px 15px;
|
|
text-align: center;
|
|
border-bottom: 1px solid #ecf0f1;
|
|
}
|
|
|
|
.prayer-times-table th {
|
|
background: #34495e;
|
|
color: white;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.prayer-times-table tr:nth-child(even) {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.note {
|
|
background: #d1ecf1;
|
|
border: 1px solid #bee5eb;
|
|
border-radius: 5px;
|
|
padding: 15px;
|
|
margin: 15px 0;
|
|
}
|
|
|
|
.note::before {
|
|
content: "💡 ";
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
.warning {
|
|
background: #f8d7da;
|
|
border: 1px solid #f5c6cb;
|
|
border-radius: 5px;
|
|
padding: 15px;
|
|
margin: 15px 0;
|
|
}
|
|
|
|
.warning::before {
|
|
content: "⚠️ ";
|
|
font-size: 1.2em;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>راهنمای محاسبه اوقات شرعی</h1>
|
|
<p>تحلیل کامل کلاس PrayTimes و الگوریتمهای محاسبه اوقات اذان</p>
|
|
</div>
|
|
|
|
<div class="content">
|
|
<!-- مرحله اول: معرفی کلی -->
|
|
<div class="section">
|
|
<h2>مرحله اول: معرفی کلی سیستم</h2>
|
|
|
|
<p>کلاس <span class="highlight">PrayTimes</span> یک سیستم پیشرفته برای محاسبه اوقات شرعی است که بر اساس موقعیت جغرافیایی، تاریخ و روشهای مختلف محاسبه عمل میکند.</p>
|
|
|
|
<h3>ویژگیهای کلیدی:</h3>
|
|
<ul>
|
|
<li>محاسبه دقیق بر اساس <strong>Julian Date</strong></li>
|
|
<li>پشتیبانی از روشهای مختلف محاسبه (MWL, ISNA, Karachi و...)</li>
|
|
<li>تنظیم خودکار برای عرضهای جغرافیایی بالا</li>
|
|
<li>خروجی به صورت اعداد اعشاری (ساعت از روز)</li>
|
|
</ul>
|
|
|
|
<div class="code-block">
|
|
<pre><span class="comment">// نمونه ایجاد instance از کلاس PrayTimes</span>
|
|
<span class="keyword">PrayTimes</span> prayTimes = <span class="keyword">PrayTimes</span>(
|
|
calendar: <span class="keyword">DateTime</span>(<span class="number">2024</span>, <span class="number">3</span>, <span class="number">15</span>), <span class="comment">// تاریخ</span>
|
|
coordinates: <span class="keyword">Coordinates</span>( <span class="comment">// موقعیت جغرافیایی</span>
|
|
latitude: <span class="number">35.6892</span>, <span class="comment">// عرض جغرافیایی تهران</span>
|
|
longitude: <span class="number">51.3890</span> <span class="comment">// طول جغرافیایی تهران</span>
|
|
),
|
|
method: <span class="keyword">CalculationMethod</span>.Tehran, <span class="comment">// روش محاسبه</span>
|
|
highLatitudesMethod: <span class="keyword">HighLatitudesMethod</span>.NightMiddle,
|
|
in12Hours: <span class="keyword">false</span> <span class="comment">// فرمت 24 ساعته</span>
|
|
);</pre>
|
|
</div>
|
|
|
|
<div class="note">
|
|
هر زمان اذان به صورت یک عدد اعشاری بین 0 تا 24 نمایش داده میشود که نشاندهنده ساعت از ابتدای روز است.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله دوم: ساختار کلاس و متدهای اصلی -->
|
|
<div class="section">
|
|
<h2>مرحله دوم: ساختار کلاس و متدهای اصلی</h2>
|
|
|
|
<h3>متغیرهای اصلی کلاس:</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">class</span> <span class="keyword">PrayTimes</span> {
|
|
<span class="comment">// اوقات به صورت اعداد اعشاری (0-24)</span>
|
|
<span class="keyword">late double</span> imsak; <span class="comment">// امساک</span>
|
|
<span class="keyword">late double</span> fajr; <span class="comment">// فجر</span>
|
|
<span class="keyword">late double</span> sunrise; <span class="comment">// طلوع آفتاب</span>
|
|
<span class="keyword">late double</span> dhuhr; <span class="comment">// ظهر</span>
|
|
<span class="keyword">late double</span> asr; <span class="comment">// عصر</span>
|
|
<span class="keyword">late double</span> sunset; <span class="comment">// غروب آفتاب</span>
|
|
<span class="keyword">late double</span> maghrib; <span class="comment">// مغرب</span>
|
|
<span class="keyword">late double</span> isha; <span class="comment">// عشا</span>
|
|
<span class="keyword">late double</span> midnight; <span class="comment">// نیمه شب</span>
|
|
|
|
<span class="keyword">List<double></span> allTimes = []; <span class="comment">// لیست تمام اوقات</span>
|
|
<span class="keyword">List<DateTime?></span> allinDateTime = []; <span class="comment">// تبدیل به DateTime</span>
|
|
}</pre>
|
|
</div>
|
|
|
|
<h3>مراحل محاسبه در Constructor:</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-number">1</span>
|
|
<strong>محاسبه Julian Date:</strong>
|
|
<div class="formula">
|
|
jdate = julian(year, month, day) - longitude / (15.0 * 24.0)
|
|
</div>
|
|
<p>Julian Date یک سیستم شمارش روزها از تاریخ مشخصی است که در نجوم استفاده میشود.</p>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-number">2</span>
|
|
<strong>محاسبه اوقات اولیه:</strong>
|
|
<div class="code-block">
|
|
<pre><span class="comment">// محاسبه هر یک از اوقات بر اساس زاویه خورشید</span>
|
|
<span class="keyword">double</span> fajr = sunAngleTime(jdate, method.fajr, _DEFAULT_FAJR, <span class="keyword">true</span>, coordinates);
|
|
<span class="keyword">double</span> sunrise = sunAngleTime(jdate, riseSetAngle(coordinates), _DEFAULT_SUNRISE, <span class="keyword">true</span>, coordinates);
|
|
<span class="keyword">double</span> dhuhr = midDay(jdate, _DEFAULT_DHUHR);
|
|
<span class="keyword">double</span> asr = asrTime(jdate, asrMethod.asrFactor, _DEFAULT_ASR, coordinates);
|
|
<span class="keyword">double</span> sunset = sunAngleTime(jdate, riseSetAngle(coordinates), _DEFAULT_SUNSET, <span class="keyword">false</span>, coordinates);
|
|
<span class="keyword">double</span> maghrib = sunAngleTime(jdate, method.maghrib, _DEFAULT_MAGHRIB, <span class="keyword">false</span>, coordinates);
|
|
<span class="keyword">double</span> isha = sunAngleTime(jdate, method.isha, _DEFAULT_ISHA, <span class="keyword">false</span>, coordinates);</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-number">3</span>
|
|
<strong>تنظیم TimeZone:</strong>
|
|
<div class="code-block">
|
|
<pre><span class="comment">// محاسبه offset برای timezone و longitude</span>
|
|
<span class="keyword">double</span> offset = <span class="keyword">DateTime</span>.now().timeZoneOffset.inMilliseconds / (<span class="number">60</span> * <span class="number">60</span> * <span class="number">1000.0</span>);
|
|
<span class="keyword">double</span> addToAll = offset - coordinates.longitude / <span class="number">15.0</span>;
|
|
|
|
<span class="comment">// اعمال offset به تمام اوقات</span>
|
|
fajr += addToAll;
|
|
sunrise += addToAll;
|
|
dhuhr += addToAll;
|
|
<span class="comment">// ... سایر اوقات</span></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله سوم: الگوریتمهای محاسبه -->
|
|
<div class="section">
|
|
<h2>مرحله سوم: الگوریتمهای محاسبه دقیق</h2>
|
|
|
|
<h3>1. محاسبه موقعیت خورشید (sunPosition):</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">DeclEqt</span> sunPosition(<span class="keyword">double</span> jd) {
|
|
<span class="keyword">double</span> D = jd - <span class="number">2451545.0</span>; <span class="comment">// روزهای گذشته از epoch</span>
|
|
<span class="keyword">double</span> g = (<span class="number">357.529</span> + <span class="number">0.98560028</span> * D) % <span class="number">360</span>; <span class="comment">// Mean anomaly</span>
|
|
<span class="keyword">double</span> q = (<span class="number">280.459</span> + <span class="number">0.98564736</span> * D) % <span class="number">360</span>; <span class="comment">// Mean longitude</span>
|
|
|
|
<span class="comment">// محاسبه True longitude</span>
|
|
<span class="keyword">double</span> L = (q + <span class="number">1.915</span> * sin(dtr(g)) + <span class="number">0.020</span> * sin(dtr(<span class="number">2.0</span> * g))) % <span class="number">360</span>;
|
|
|
|
<span class="keyword">double</span> e = <span class="number">23.439</span> - <span class="number">0.00000036</span> * D; <span class="comment">// Obliquity of ecliptic</span>
|
|
|
|
<span class="comment">// محاسبه Right Ascension و Equation of Time</span>
|
|
<span class="keyword">double</span> RA = rtd(atan2(cos(dtr(e)) * sin(dtr(L)), cos(dtr(L)))) / <span class="number">15.0</span>;
|
|
<span class="keyword">double</span> eqt = q / <span class="number">15.0</span> - fixHour(RA);
|
|
<span class="keyword">double</span> decl = asin(sin(dtr(e)) * sin(dtr(L))); <span class="comment">// Declination</span>
|
|
|
|
<span class="keyword">return</span> <span class="keyword">DeclEqt</span>(decl, eqt);
|
|
}</pre>
|
|
</div>
|
|
|
|
<h3>2. محاسبه زمان بر اساس زاویه خورشید (sunAngleTime):</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">double</span> sunAngleTime(<span class="keyword">double</span> jdate, <span class="keyword">MinuteOrAngleDouble</span> angle, <span class="keyword">double</span> time,
|
|
<span class="keyword">bool</span> ccw, <span class="keyword">Coordinates</span> coordinates) {
|
|
<span class="keyword">double</span> decl = sunPosition(jdate + time).declination;
|
|
<span class="keyword">double</span> noon = dtr(midDay(jdate, time));
|
|
|
|
<span class="comment">// فرمول اصلی محاسبه زمان بر اساس زاویه</span>
|
|
<span class="keyword">double</span> t = acos((-sin(dtr(angle.value)) -
|
|
sin(decl) * sin(dtr(coordinates.latitude))) /
|
|
(cos(decl) * cos(dtr(coordinates.latitude)))) / <span class="number">15.0</span>;
|
|
|
|
<span class="keyword">return</span> rtd(noon + (ccw ? -t : t));
|
|
}</pre>
|
|
</div>
|
|
|
|
<div class="note">
|
|
پارامتر <strong>ccw</strong> (Counter Clock Wise) تعیین میکند که آیا زمان قبل از ظهر (true) یا بعد از ظهر (false) محاسبه شود.
|
|
</div>
|
|
|
|
<h3>3. محاسبه زمان عصر (asrTime):</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">double</span> asrTime(<span class="keyword">double</span> jdate, <span class="keyword">double</span> factor, <span class="keyword">double</span> time, <span class="keyword">Coordinates</span> coordinates) {
|
|
<span class="keyword">double</span> decl = sunPosition(jdate + time).declination;
|
|
|
|
<span class="comment">// محاسبه زاویه بر اساس فاکتور عصر (1 برای استاندارد، 2 برای حنفی)</span>
|
|
<span class="keyword">double</span> angle = -atan(<span class="number">1</span> / (factor + tan(abs(dtr(coordinates.latitude) - decl))));
|
|
|
|
<span class="keyword">return</span> sunAngleTime(jdate, <span class="keyword">MinuteOrAngleDouble</span>.deg(rtd(angle)), time, <span class="keyword">false</span>, coordinates);
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله چهارم: روشهای محاسبه مختلف -->
|
|
<div class="section">
|
|
<h2>مرحله چهارم: روشهای محاسبه مختلف</h2>
|
|
|
|
<p>هر روش محاسبه دارای زوایای مختلفی برای فجر، مغرب و عشا است:</p>
|
|
|
|
<table class="prayer-times-table">
|
|
<thead>
|
|
<tr>
|
|
<th>روش محاسبه</th>
|
|
<th>زاویه فجر</th>
|
|
<th>زاویه عشا</th>
|
|
<th>مغرب</th>
|
|
<th>کاربرد</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>MWL (Muslim World League)</td>
|
|
<td>18°</td>
|
|
<td>17°</td>
|
|
<td>غروب + دقیقه</td>
|
|
<td>اروپا، آمریکا</td>
|
|
</tr>
|
|
<tr>
|
|
<td>ISNA (North America)</td>
|
|
<td>15°</td>
|
|
<td>15°</td>
|
|
<td>غروب + دقیقه</td>
|
|
<td>آمریکای شمالی</td>
|
|
</tr>
|
|
<tr>
|
|
<td>University of Karachi</td>
|
|
<td>18°</td>
|
|
<td>18°</td>
|
|
<td>غروب + دقیقه</td>
|
|
<td>پاکستان، هند</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Umm Al-Qura (مکه)</td>
|
|
<td>18.5°</td>
|
|
<td>90 دقیقه بعد مغرب</td>
|
|
<td>غروب + دقیقه</td>
|
|
<td>عربستان سعودی</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Egyptian Authority</td>
|
|
<td>19.5°</td>
|
|
<td>17.5°</td>
|
|
<td>غروب + دقیقه</td>
|
|
<td>مصر، خاورمیانه</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Institute of Tehran</td>
|
|
<td>17.7°</td>
|
|
<td>14°</td>
|
|
<td>4.5°</td>
|
|
<td>ایران</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Ithna Ashari</td>
|
|
<td>16°</td>
|
|
<td>14°</td>
|
|
<td>4°</td>
|
|
<td>شیعه</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="code-block">
|
|
<pre><span class="comment">// نمونه تعریف روش محاسبه در enum</span>
|
|
<span class="keyword">enum</span> <span class="keyword">CalculationMethod</span> {
|
|
IthnaAshari, <span class="comment">// اثنی عشری</span>
|
|
Karachi, <span class="comment">// کراچی</span>
|
|
NorthAmerica, <span class="comment">// آمریکای شمالی</span>
|
|
MWL, <span class="comment">// رابطه جهانی اسلامی</span>
|
|
UmmAlQura, <span class="comment">// ام القری</span>
|
|
Egyptian, <span class="comment">// مصری</span>
|
|
Tehran, <span class="comment">// تهران</span>
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله پنجم: تنظیمات عرضهای جغرافیایی بالا -->
|
|
<div class="section">
|
|
<h2>مرحله پنجم: تنظیمات عرضهای جغرافیایی بالا</h2>
|
|
|
|
<p>در عرضهای جغرافیایی بالا (بالای 49 درجه)، ممکن است برخی اوقات قابل محاسبه نباشند. برای حل این مشکل از روشهای مختلفی استفاده میشود:</p>
|
|
|
|
<h3>روشهای تنظیم:</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-number">1</span>
|
|
<strong>NightMiddle (وسط شب):</strong>
|
|
<p>فجر و عشا بر اساس نیمه شب محاسبه میشوند.</p>
|
|
<div class="formula">
|
|
portion = 1/2 * nightTime
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-number">2</span>
|
|
<strong>AngleBased (بر اساس زاویه):</strong>
|
|
<p>بر اساس زاویه مشخص شده محاسبه میشود.</p>
|
|
<div class="formula">
|
|
portion = angle/60 * nightTime
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-number">3</span>
|
|
<strong>OneSeventh (یک هفتم شب):</strong>
|
|
<p>یک هفتم از طول شب استفاده میشود.</p>
|
|
<div class="formula">
|
|
portion = 1/7 * nightTime
|
|
</div>
|
|
</div>
|
|
|
|
<div class="code-block">
|
|
<pre><span class="comment">// تنظیم اوقات برای عرضهای جغرافیایی بالا</span>
|
|
<span class="keyword">if</span> (highLatitudesMethod != <span class="keyword">HighLatitudesMethod</span>.None) {
|
|
<span class="keyword">double</span> nightTime = timeDiff(sunset, sunrise);
|
|
|
|
fajr = adjustHLTime(highLatitudesMethod, fajr, sunrise,
|
|
method.fajr.value, nightTime, <span class="keyword">true</span>);
|
|
isha = adjustHLTime(highLatitudesMethod, isha, sunset,
|
|
method.isha.value, nightTime, <span class="keyword">false</span>);
|
|
}</pre>
|
|
</div>
|
|
|
|
<div class="warning">
|
|
در کد پروژه، اگر عرض جغرافیایی کمتر از 49 درجه باشد، به طور خودکار از روش NightMiddle استفاده میشود.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله ششم: تبدیل اعداد اعشاری به زمان -->
|
|
<div class="section">
|
|
<h2>مرحله ششم: تبدیل اعداد اعشاری به زمان</h2>
|
|
|
|
<p>خروجی کلاس PrayTimes اعداد اعشاری هستند که نشاندهنده ساعت از ابتدای روز میباشند. این اعداد باید به فرمت زمان قابل خواندن تبدیل شوند.</p>
|
|
|
|
<h3>نحوه تبدیل:</h3>
|
|
|
|
<div class="step">
|
|
<span class="step-number">1</span>
|
|
<strong>جدا کردن ساعت و دقیقه:</strong>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">String</span> <span class="keyword">get</span> floatToTime24 {
|
|
<span class="keyword">var</span> time = <span class="keyword">this</span>;
|
|
<span class="keyword">if</span> (time == <span class="keyword">null</span> || time.isNaN) <span class="keyword">return</span> <span class="string">"----"</span>;
|
|
|
|
time = _fixHour(time + <span class="number">0.5</span> / <span class="number">60.0</span>); <span class="comment">// اضافه کردن 0.5 دقیقه برای گرد کردن</span>
|
|
<span class="keyword">int</span> hours = (time).floor(); <span class="comment">// بخش صحیح = ساعت</span>
|
|
<span class="keyword">double</span> minutes = ((time - hours) * <span class="number">60.0</span>).floorToDouble(); <span class="comment">// بخش اعشاری × 60 = دقیقه</span>
|
|
|
|
<span class="comment">// فرمت کردن با صفر اضافی</span>
|
|
<span class="keyword">return</span> <span class="string">"${hours.toString().padLeft(2, '0')}:${minutes.round().toString().padLeft(2, '0')}"</span>;
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<span class="step-number">2</span>
|
|
<strong>مثال عملی:</strong>
|
|
<div class="formula">
|
|
اگر fajr = 5.25 باشد:<br>
|
|
ساعت = 5 (بخش صحیح)<br>
|
|
دقیقه = 0.25 × 60 = 15<br>
|
|
نتیجه = "05:15"
|
|
</div>
|
|
</div>
|
|
|
|
<h3>تبدیل به فرمت 12 ساعته:</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">String</span> <span class="keyword">get</span> floatToTime12 {
|
|
<span class="comment">// ... محاسبه ساعت و دقیقه مشابه بالا</span>
|
|
|
|
<span class="keyword">if</span> (hours >= <span class="number">12</span> && hours < <span class="number">24</span>) {
|
|
<span class="keyword">var</span> hourss = hours - <span class="number">12</span>;
|
|
<span class="keyword">if</span> (hourss == <span class="number">0</span>) hourss = <span class="number">12</span>; <span class="comment">// 12 PM نه 0 PM</span>
|
|
<span class="comment">// فرمت کردن...</span>
|
|
} <span class="keyword">else</span> {
|
|
<span class="keyword">var</span> hourss = hours;
|
|
<span class="keyword">if</span> (hourss == <span class="number">0</span>) hourss = <span class="number">12</span>; <span class="comment">// 12 AM نه 0 AM</span>
|
|
<span class="comment">// فرمت کردن...</span>
|
|
}
|
|
}
|
|
|
|
<span class="keyword">String</span> <span class="keyword">get</span> amPm {
|
|
<span class="keyword">int</span> hours = (<span class="keyword">this</span>).floor();
|
|
<span class="keyword">return</span> hours >= <span class="number">12</span> && hours < <span class="number">24</span> ? <span class="string">'PM'</span> : <span class="string">'AM'</span>;
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- مرحله هفتم: نمونه کد کامل -->
|
|
<div class="section">
|
|
<h2>مرحله هفتم: نمونه کد کامل و کاربردی</h2>
|
|
|
|
<h3>نمونه استفاده کامل:</h3>
|
|
<div class="code-block">
|
|
<pre><span class="comment">// تعریف موقعیت جغرافیایی تهران</span>
|
|
<span class="keyword">Coordinates</span> tehranCoords = <span class="keyword">Coordinates</span>(
|
|
latitude: <span class="number">35.6892</span>,
|
|
longitude: <span class="number">51.3890</span>,
|
|
elevation: <span class="number">1200</span> <span class="comment">// ارتفاع از سطح دریا (متر)</span>
|
|
);
|
|
|
|
<span class="comment">// ایجاد instance برای تاریخ امروز</span>
|
|
<span class="keyword">PrayTimes</span> prayTimes = <span class="keyword">PrayTimes</span>(
|
|
calendar: <span class="keyword">DateTime</span>.now(),
|
|
coordinates: tehranCoords,
|
|
method: <span class="keyword">CalculationMethod</span>.Tehran,
|
|
highLatitudesMethod: <span class="keyword">HighLatitudesMethod</span>.NightMiddle,
|
|
in12Hours: <span class="keyword">false</span>
|
|
);
|
|
|
|
<span class="comment">// دریافت اوقات</span>
|
|
print(<span class="string">"فجر: ${prayTimes.fajr.floatToTime24}"</span>); <span class="comment">// مثال: "05:15"</span>
|
|
print(<span class="string">"طلوع: ${prayTimes.sunrise.floatToTime24}"</span>); <span class="comment">// مثال: "06:45"</span>
|
|
print(<span class="string">"ظهر: ${prayTimes.dhuhr.floatToTime24}"</span>); <span class="comment">// مثال: "12:30"</span>
|
|
print(<span class="string">"عصر: ${prayTimes.asr.floatToTime24}"</span>); <span class="comment">// مثال: "15:20"</span>
|
|
print(<span class="string">"مغرب: ${prayTimes.maghrib.floatToTime24}"</span>); <span class="comment">// مثال: "18:15"</span>
|
|
print(<span class="string">"عشا: ${prayTimes.isha.floatToTime24}"</span>); <span class="comment">// مثال: "19:45"</span>
|
|
|
|
<span class="comment">// تبدیل به DateTime برای استفاده در برنامه</span>
|
|
<span class="keyword">DateTime</span> fajrDateTime = <span class="keyword">DateTime</span>(
|
|
prayTimes.calendar.year,
|
|
prayTimes.calendar.month,
|
|
prayTimes.calendar.day
|
|
).add(<span class="keyword">Duration</span>(
|
|
hours: prayTimes.fajr.floor(),
|
|
minutes: ((prayTimes.fajr - prayTimes.fajr.floor()) * <span class="number">60</span>).round()
|
|
));</pre>
|
|
</div>
|
|
|
|
<h3>ایجاد لیست اوقات برای چندین روز:</h3>
|
|
<div class="code-block">
|
|
<pre><span class="keyword">List<PrayTimeModel></span> getPrayTimesForMonth(<span class="keyword">DateTime</span> startDate, <span class="keyword">Coordinates</span> coords) {
|
|
<span class="keyword">List<PrayTimeModel></span> allPrayTimes = [];
|
|
|
|
<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < <span class="number">30</span>; i++) {
|
|
<span class="keyword">DateTime</span> currentDate = startDate.add(<span class="keyword">Duration</span>(days: i));
|
|
|
|
<span class="keyword">PrayTimes</span> pt = <span class="keyword">PrayTimes</span>(
|
|
calendar: currentDate,
|
|
coordinates: coords,
|
|
method: <span class="keyword">CalculationMethod</span>.Tehran,
|
|
highLatitudesMethod: <span class="keyword">HighLatitudesMethod</span>.NightMiddle,
|
|
in12Hours: <span class="keyword">false</span>,
|
|
);
|
|
|
|
<span class="comment">// اضافه کردن هر وقت به لیست</span>
|
|
<span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>; j < pt.allTimes.length; j++) {
|
|
allPrayTimes.add(<span class="keyword">PrayTimeModel</span>(
|
|
enumTime: <span class="keyword">EnumTime</span>.values[j],
|
|
name: <span class="keyword">EnumTime</span>.values[j].name,
|
|
timeInString: pt.allTimes[j].floatToTime24,
|
|
dateTime: currentDate.add(<span class="keyword">Duration</span>(
|
|
hours: pt.allTimes[j].floor(),
|
|
minutes: ((pt.allTimes[j] - pt.allTimes[j].floor()) * <span class="number">60</span>).round()
|
|
)),
|
|
));
|
|
}
|
|
}
|
|
|
|
<span class="keyword">return</span> allPrayTimes;
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- خلاصه و نکات مهم -->
|
|
<div class="section">
|
|
<h2>خلاصه و نکات مهم</h2>
|
|
|
|
<h3>نکات کلیدی:</h3>
|
|
<ul>
|
|
<li><strong>دقت محاسبات:</strong> تمام محاسبات بر اساس فرمولهای نجومی دقیق انجام میشود</li>
|
|
<li><strong>انعطافپذیری:</strong> پشتیبانی از روشهای مختلف محاسبه برای مناطق مختلف جهان</li>
|
|
<li><strong>تنظیم خودکار:</strong> تنظیم خودکار برای عرضهای جغرافیایی بالا</li>
|
|
<li><strong>خروجی استاندارد:</strong> خروجی به صورت اعداد اعشاری قابل تبدیل به هر فرمت</li>
|
|
</ul>
|
|
|
|
<div class="note">
|
|
برای استفاده بهینه، توصیه میشود اوقات را برای چندین روز آینده محاسبه و ذخیره کنید تا از محاسبات مکرر جلوگیری شود.
|
|
</div>
|
|
|
|
<div class="warning">
|
|
دقت کنید که تغییر موقعیت جغرافیایی یا روش محاسبه نیاز به محاسبه مجدد تمام اوقات دارد.
|
|
</div>
|
|
|
|
<h3>منابع و مراجع:</h3>
|
|
<ul>
|
|
<li>الگوریتمهای نجومی برای محاسبه موقعیت خورشید</li>
|
|
<li>استانداردهای بینالمللی اوقات شرعی</li>
|
|
<li>فرمولهای ریاضی برای تبدیل مختصات جغرافیایی</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|