mihrab-methods 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/certification.json +23 -0
- package/data/corrections/turkiyetakvimi.json +120 -0
- package/dist/cjs/authorities/turkiyeTakvimi.d.ts +3 -0
- package/dist/cjs/authorities/turkiyeTakvimi.js +59 -0
- package/dist/cjs/core/compute.js +6 -2
- package/dist/cjs/core/types.d.ts +3 -1
- package/dist/cjs/core/types.js +1 -1
- package/dist/cjs/data/generated/turkiyeTakvimiCities.d.ts +8 -0
- package/dist/cjs/data/generated/turkiyeTakvimiCities.js +5 -0
- package/dist/cjs/data/generated/turkiyetakvimiCertification.d.ts +3 -0
- package/dist/cjs/data/generated/turkiyetakvimiCertification.js +4 -0
- package/dist/cjs/data/generated/turkiyetakvimiCorrections.d.ts +3 -0
- package/dist/cjs/data/generated/turkiyetakvimiCorrections.js +4 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/methods/revisions.d.ts +1 -0
- package/dist/cjs/methods/revisions.js +1 -0
- package/dist/cjs/methods/turkiyeTakvimi.d.ts +42 -0
- package/dist/cjs/methods/turkiyeTakvimi.js +166 -0
- package/dist/cjs/turkiyetakvimi.d.ts +4 -0
- package/dist/cjs/turkiyetakvimi.js +22 -0
- package/dist/esm/authorities/turkiyeTakvimi.d.ts +3 -0
- package/dist/esm/authorities/turkiyeTakvimi.js +53 -0
- package/dist/esm/core/compute.js +6 -2
- package/dist/esm/core/types.d.ts +3 -1
- package/dist/esm/core/types.js +1 -1
- package/dist/esm/data/generated/turkiyeTakvimiCities.d.ts +8 -0
- package/dist/esm/data/generated/turkiyeTakvimiCities.js +3 -0
- package/dist/esm/data/generated/turkiyetakvimiCertification.d.ts +3 -0
- package/dist/esm/data/generated/turkiyetakvimiCertification.js +2 -0
- package/dist/esm/data/generated/turkiyetakvimiCorrections.d.ts +3 -0
- package/dist/esm/data/generated/turkiyetakvimiCorrections.js +2 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/methods/revisions.d.ts +1 -0
- package/dist/esm/methods/revisions.js +1 -0
- package/dist/esm/methods/turkiyeTakvimi.d.ts +42 -0
- package/dist/esm/methods/turkiyeTakvimi.js +159 -0
- package/dist/esm/turkiyetakvimi.d.ts +4 -0
- package/dist/esm/turkiyetakvimi.js +4 -0
- package/docs/methods.md +39 -0
- package/package.json +17 -2
- package/schemas/certification.schema.json +2 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
**Prayer times that match the published timetable to the printed minute.**
|
|
10
10
|
Each national authority's own calculation method, worked out again from its
|
|
11
11
|
published times and checked day by day against its timetables: <!--fig:total.off-->0<!--/fig--> of
|
|
12
|
-
<!--fig:total.times-->73,
|
|
12
|
+
<!--fig:total.times-->73,824,302<!--/fig--> times off the printed minute. Free for any app, site or
|
|
13
13
|
mosque to use.
|
|
14
14
|
|
|
15
15
|
[](#usage)
|
|
@@ -43,8 +43,9 @@ The full API, the HTTP server and the per-authority imports are in
|
|
|
43
43
|
| **Morocco** | Habous | 164 | 94,350 | **0** | 99.879 % | 114 | 27 Aug 2026 → 30 Nov 2026 |
|
|
44
44
|
| **Algeria** | Ministry of Religious Affairs | 68 | 101,184 | **0** | 99.365 % | 642 | 1 Oct 2026 → 5 Jun 2027 |
|
|
45
45
|
| **Indonesia** | Kemenag | 517 | 362,934 | **0** | 99.935 % | 234 | 7 Oct 2026 → 31 Jan 2027 |
|
|
46
|
+
| **Türkiye Takvimi** | its cities’ years | 81 | 178,848 | **0** | 99.970 % | 52 | 31 Dec 2025 → 2 Jan 2027 |
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
6 of 6 methods certified; 0 of 73,824,302 times off the printed minute. Last checked 9 November 2026. Generated from [`certification.json`](certification.json) by `scripts/readme.mjs`.
|
|
48
49
|
<!-- certification-table:end -->
|
|
49
50
|
|
|
50
51
|
"By the method alone" is the formula without its correction list. The list
|
package/certification.json
CHANGED
|
@@ -127,5 +127,28 @@
|
|
|
127
127
|
"sha256": "a3f1c30576ddddbfda6cadabe442e1bcf3fb476b018b269d7d4783edd4e39d03"
|
|
128
128
|
},
|
|
129
129
|
"revision": 2
|
|
130
|
+
},
|
|
131
|
+
"turkiyetakvimi": {
|
|
132
|
+
"certified": true,
|
|
133
|
+
"checkedAt": "2026-11-11",
|
|
134
|
+
"places": 81,
|
|
135
|
+
"checks": [
|
|
136
|
+
{
|
|
137
|
+
"tables": "Türkiye Takvimi — its cities’ years",
|
|
138
|
+
"places": 81,
|
|
139
|
+
"times": 178848,
|
|
140
|
+
"off": 0,
|
|
141
|
+
"offWithoutCorrections": 52,
|
|
142
|
+
"from": "2025-12-31",
|
|
143
|
+
"to": "2027-01-02"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"corrections": {
|
|
147
|
+
"from": "2025-12-31",
|
|
148
|
+
"to": "2027-01-02",
|
|
149
|
+
"entries": 52,
|
|
150
|
+
"sha256": "a3059fd5aae0b0f8ddee10a2aaaf93e982ded12e652f6aa21d0a3d347a082b41"
|
|
151
|
+
},
|
|
152
|
+
"revision": 1
|
|
130
153
|
}
|
|
131
154
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"from": "2025-12-31",
|
|
3
|
+
"to": "2027-01-02",
|
|
4
|
+
"points": {
|
|
5
|
+
"36.999,35.316": [
|
|
6
|
+
"2026-01-07 fajr -1"
|
|
7
|
+
],
|
|
8
|
+
"37.184,33.216": [
|
|
9
|
+
"2026-01-20 fajr -1",
|
|
10
|
+
"2026-01-27 fajr -1"
|
|
11
|
+
],
|
|
12
|
+
"37.217,28.366": [
|
|
13
|
+
"2026-11-18 sunrise +1"
|
|
14
|
+
],
|
|
15
|
+
"37.767,30.550": [
|
|
16
|
+
"2026-05-26 isha -1"
|
|
17
|
+
],
|
|
18
|
+
"37.850,27.850": [
|
|
19
|
+
"2026-03-06 dhuhr -1"
|
|
20
|
+
],
|
|
21
|
+
"37.866,32.483": [
|
|
22
|
+
"2026-06-08 maghrib +1"
|
|
23
|
+
],
|
|
24
|
+
"37.917,40.233": [
|
|
25
|
+
"2026-11-16 dhuhr +1"
|
|
26
|
+
],
|
|
27
|
+
"38.367,34.033": [
|
|
28
|
+
"2026-04-16 isha -1"
|
|
29
|
+
],
|
|
30
|
+
"38.383,42.099": [
|
|
31
|
+
"2026-03-26 maghrib -1"
|
|
32
|
+
],
|
|
33
|
+
"38.633,34.717": [
|
|
34
|
+
"2026-05-31 asr +1",
|
|
35
|
+
"2026-07-02 asr +1"
|
|
36
|
+
],
|
|
37
|
+
"38.733,35.483": [
|
|
38
|
+
"2026-05-04 isha +1"
|
|
39
|
+
],
|
|
40
|
+
"38.883,40.483": [
|
|
41
|
+
"2026-03-25 sunrise -1"
|
|
42
|
+
],
|
|
43
|
+
"39.716,43.050": [
|
|
44
|
+
"2026-02-01 isha -1",
|
|
45
|
+
"2026-02-20 fajr -1",
|
|
46
|
+
"2026-03-04 maghrib -1"
|
|
47
|
+
],
|
|
48
|
+
"39.750,39.500": [
|
|
49
|
+
"2026-01-17 isha -1",
|
|
50
|
+
"2026-02-22 dhuhr -1"
|
|
51
|
+
],
|
|
52
|
+
"39.933,32.849": [
|
|
53
|
+
"2026-02-22 isha -1"
|
|
54
|
+
],
|
|
55
|
+
"40.316,36.550": [
|
|
56
|
+
"2026-02-01 dhuhr -1"
|
|
57
|
+
],
|
|
58
|
+
"40.599,43.083": [
|
|
59
|
+
"2026-05-06 dhuhr +1"
|
|
60
|
+
],
|
|
61
|
+
"40.650,29.266": [
|
|
62
|
+
"2026-01-26 asr -1"
|
|
63
|
+
],
|
|
64
|
+
"40.650,35.833": [
|
|
65
|
+
"2026-10-03 fajr +1"
|
|
66
|
+
],
|
|
67
|
+
"40.733,31.616": [
|
|
68
|
+
"2026-03-24 maghrib +1",
|
|
69
|
+
"2026-09-08 dhuhr +1"
|
|
70
|
+
],
|
|
71
|
+
"40.767,29.950": [
|
|
72
|
+
"2026-03-05 maghrib -1",
|
|
73
|
+
"2026-04-14 sunrise -1"
|
|
74
|
+
],
|
|
75
|
+
"40.850,31.150": [
|
|
76
|
+
"2026-07-19 sunrise -1"
|
|
77
|
+
],
|
|
78
|
+
"40.983,27.516": [
|
|
79
|
+
"2026-07-03 dhuhr +1",
|
|
80
|
+
"2026-11-26 dhuhr +1",
|
|
81
|
+
"2026-12-23 asr +1"
|
|
82
|
+
],
|
|
83
|
+
"41.000,29.000": [
|
|
84
|
+
"2026-03-31 sunrise -1",
|
|
85
|
+
"2026-12-15 maghrib -1",
|
|
86
|
+
"2026-12-16 maghrib -1",
|
|
87
|
+
"2026-12-17 maghrib -1",
|
|
88
|
+
"2026-12-17 sunrise -1",
|
|
89
|
+
"2026-12-18 maghrib -1",
|
|
90
|
+
"2026-12-21 maghrib -1",
|
|
91
|
+
"2026-12-24 sunrise -1",
|
|
92
|
+
"2026-12-27 sunrise -1",
|
|
93
|
+
"2026-12-31 sunrise -1"
|
|
94
|
+
],
|
|
95
|
+
"41.033,40.517": [
|
|
96
|
+
"2026-04-19 maghrib +1"
|
|
97
|
+
],
|
|
98
|
+
"41.200,32.632": [
|
|
99
|
+
"2026-02-20 dhuhr -1",
|
|
100
|
+
"2026-03-21 fajr -1"
|
|
101
|
+
],
|
|
102
|
+
"41.367,33.783": [
|
|
103
|
+
"2026-04-05 asr -1"
|
|
104
|
+
],
|
|
105
|
+
"41.450,31.800": [
|
|
106
|
+
"2026-05-22 sunrise -1",
|
|
107
|
+
"2026-08-09 asr +1"
|
|
108
|
+
],
|
|
109
|
+
"41.666,26.567": [
|
|
110
|
+
"2026-04-23 isha +1"
|
|
111
|
+
],
|
|
112
|
+
"41.733,27.217": [
|
|
113
|
+
"2026-06-28 fajr +1",
|
|
114
|
+
"2026-09-19 isha -1"
|
|
115
|
+
],
|
|
116
|
+
"42.033,35.150": [
|
|
117
|
+
"2026-10-11 maghrib +1"
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.places = exports.turkiyeTakvimi = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Türkiye Takvimi — the calendar's cities, each at the point and with the
|
|
9
|
+
* temkin its published year is computed with. The first list is Türkiye's
|
|
10
|
+
* 81 province centres.
|
|
11
|
+
*/
|
|
12
|
+
const turkiyeTakvimiCities_js_1 = __importDefault(require("../data/generated/turkiyeTakvimiCities.js"));
|
|
13
|
+
const turkiyetakvimiCorrections_js_1 = __importDefault(require("../data/generated/turkiyetakvimiCorrections.js"));
|
|
14
|
+
const turkiyetakvimiCertification_js_1 = __importDefault(require("../data/generated/turkiyetakvimiCertification.js"));
|
|
15
|
+
const revisions_js_1 = require("../methods/revisions.js");
|
|
16
|
+
const registry_js_1 = require("../core/registry.js");
|
|
17
|
+
const AUTHORITY = 'turkiyetakvimi';
|
|
18
|
+
function buildPlaces() {
|
|
19
|
+
return turkiyeTakvimiCities_js_1.default.map(c => {
|
|
20
|
+
const key = String(c.id);
|
|
21
|
+
return {
|
|
22
|
+
authority: AUTHORITY,
|
|
23
|
+
id: `${AUTHORITY}:${key}`,
|
|
24
|
+
key,
|
|
25
|
+
name: c.name,
|
|
26
|
+
country: 'TR',
|
|
27
|
+
lat: c.lat,
|
|
28
|
+
lon: c.lon,
|
|
29
|
+
tz: 'Europe/Istanbul',
|
|
30
|
+
temkin: c.temkin,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.turkiyeTakvimi = (0, registry_js_1.registerAuthority)({
|
|
35
|
+
authority: AUTHORITY,
|
|
36
|
+
revision: revisions_js_1.METHOD_REVISION.turkiyetakvimi,
|
|
37
|
+
places: buildPlaces(),
|
|
38
|
+
corrections: turkiyetakvimiCorrections_js_1.default,
|
|
39
|
+
certification: turkiyetakvimiCertification_js_1.default,
|
|
40
|
+
description: {
|
|
41
|
+
name: 'Türkiye Takvimi',
|
|
42
|
+
method: 'The precise apparent sun at each event’s own moment, and a temkin T per city (the time the sun takes on the summer solstice from the level horizon to the city’s own). Fajr is the calendar’s Sabâh, the sun 18° below the horizon with no temkin; sunrise the sun’s centre on the level horizon less T and two minutes; Dhuhr the transit plus T; Asr (the noon shadow taken at the declination of local noon) and Isha (17°) plus T; Maghrib the level horizon plus T and two minutes; every time rounded up to the minute.',
|
|
43
|
+
countries: ['TR'],
|
|
44
|
+
parameters: {
|
|
45
|
+
fajrAngle: 18,
|
|
46
|
+
ishaAngle: 17,
|
|
47
|
+
sunriseAltitude: 0,
|
|
48
|
+
asrShadow: 1,
|
|
49
|
+
asrNoonShadow: 'tan|φ − δ| at the declination of local noon',
|
|
50
|
+
temkin: 'per city, minutes: on Dhuhr, Asr, Maghrib and Isha, and before sunrise',
|
|
51
|
+
horizonMarginMinutes: 2,
|
|
52
|
+
rounding: 'up to the minute',
|
|
53
|
+
sun: 'precise apparent sun (VSOP87, IAU 2006 precession, IAU 2000B nutation), iterated at each event',
|
|
54
|
+
},
|
|
55
|
+
sources: [{ title: 'Türkiye Takvimi — namaz vakitleri', url: 'https://www.namazvakti.com/' }],
|
|
56
|
+
spec: 'docs/methods.md#türkiye-takvimi',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
exports.places = exports.turkiyeTakvimi.places;
|
package/dist/cjs/core/compute.js
CHANGED
|
@@ -11,6 +11,7 @@ const sweden_js_1 = require("../methods/sweden.js");
|
|
|
11
11
|
const morocco_js_1 = require("../methods/morocco.js");
|
|
12
12
|
const algeria_js_1 = require("../methods/algeria.js");
|
|
13
13
|
const indonesia_js_1 = require("../methods/indonesia.js");
|
|
14
|
+
const turkiyeTakvimi_js_1 = require("../methods/turkiyeTakvimi.js");
|
|
14
15
|
const registry_js_1 = require("./registry.js");
|
|
15
16
|
const clock_js_1 = require("./clock.js");
|
|
16
17
|
/**
|
|
@@ -33,12 +34,15 @@ function candidateInstants(place, year, month, day, asrShadow = 1, opts = {}) {
|
|
|
33
34
|
}
|
|
34
35
|
case 'morocco':
|
|
35
36
|
case 'algeria':
|
|
36
|
-
case 'indonesia':
|
|
37
|
+
case 'indonesia':
|
|
38
|
+
case 'turkiyetakvimi': {
|
|
37
39
|
const t = place.authority === 'morocco'
|
|
38
40
|
? (0, morocco_js_1.moroccoTimes)(place.lat, place.lon, year, month, day, place.dipDeg, asrShadow, place.dipMaghribDeg)
|
|
39
41
|
: place.authority === 'algeria'
|
|
40
42
|
? (0, algeria_js_1.algeriaTimes)(place.lat, place.lon, year, month, day, asrShadow)
|
|
41
|
-
:
|
|
43
|
+
: place.authority === 'turkiyetakvimi'
|
|
44
|
+
? (0, turkiyeTakvimi_js_1.takvimTimes)(place.lat, place.lon, year, month, day, place.temkin, asrShadow)
|
|
45
|
+
: (0, indonesia_js_1.kemenagTimes)(place.lat, place.lon, year, month, day, { highland: place.highland, twilightDip: place.twilightDip, asrShadow, afternoon: place.afternoon });
|
|
42
46
|
// the correction list: the authority's few times on the other side of a minute (the standard Asr only)
|
|
43
47
|
const c = !t || !fix ? undefined : fix.correction(place.lat, place.lon, year, month, day);
|
|
44
48
|
if (!t || !c)
|
package/dist/cjs/core/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shapes the library speaks in. Nothing here computes anything.
|
|
3
3
|
*/
|
|
4
|
-
export type Authority = 'sweden' | 'diyanet' | 'morocco' | 'algeria' | 'indonesia';
|
|
4
|
+
export type Authority = 'sweden' | 'diyanet' | 'morocco' | 'algeria' | 'indonesia' | 'turkiyetakvimi';
|
|
5
5
|
export declare const AUTHORITIES: readonly Authority[];
|
|
6
6
|
export type PrayerKey = 'fajr' | 'sunrise' | 'dhuhr' | 'asr' | 'maghrib' | 'isha';
|
|
7
7
|
export declare const PRAYER_KEYS: readonly PrayerKey[];
|
|
@@ -34,6 +34,8 @@ export type Place = {
|
|
|
34
34
|
twilightDip?: boolean;
|
|
35
35
|
/** Indonesia: where the ministry computes the regency's Asr, Maghrib and Isha, when not at its point. */
|
|
36
36
|
afternoon?: readonly [number, number];
|
|
37
|
+
/** Türkiye Takvimi: the city's temkin as its table shows it, minutes with their fraction. */
|
|
38
|
+
temkin?: number;
|
|
37
39
|
/** Diyanet: Isha's depression, 16° or 17° by country. */
|
|
38
40
|
ishaDeg?: number;
|
|
39
41
|
/**
|
package/dist/cjs/core/types.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.UncertifiedMethodError = exports.PRAYER_KEYS = exports.AUTHORITIES = void 0;
|
|
7
|
-
exports.AUTHORITIES = ['sweden', 'diyanet', 'morocco', 'algeria', 'indonesia'];
|
|
7
|
+
exports.AUTHORITIES = ['sweden', 'diyanet', 'morocco', 'algeria', 'indonesia', 'turkiyetakvimi'];
|
|
8
8
|
exports.PRAYER_KEYS = ['fajr', 'sunrise', 'dhuhr', 'asr', 'maghrib', 'isha'];
|
|
9
9
|
/** The method has not reproduced its authority's tables to the minute (or not for this date). */
|
|
10
10
|
class UncertifiedMethodError extends Error {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Generated by scripts/embed.mjs — do not edit; edit the JSON under data/ instead.
|
|
4
|
+
const data = [{ "id": 16702, "name": "Adana", "lat": 36.9995, "lon": 35.316075, "temkin": 10.0151 }, { "id": 16703, "name": "Adapazarı", "lat": 40.7833, "lon": 30.399875, "temkin": 10.7698 }, { "id": 16704, "name": "Adıyaman", "lat": 37.7667, "lon": 38.2828, "temkin": 10.1563 }, { "id": 16705, "name": "Afyonkarahisar", "lat": 38.750167, "lon": 30.549625, "temkin": 10.3374 }, { "id": 16706, "name": "Ağrı", "lat": 39.7162, "lon": 43.0495, "temkin": 10.5387 }, { "id": 16707, "name": "Aksaray", "lat": 38.3667, "lon": 34.0328, "temkin": 10.2665 }, { "id": 16708, "name": "Amasya", "lat": 40.65, "lon": 35.8333, "temkin": 10.7413 }, { "id": 16709, "name": "Ankara", "lat": 39.9333, "lon": 32.849063, "temkin": 10.5818 }, { "id": 16710, "name": "Antakya", "lat": 36.1833, "lon": 36.166263, "temkin": 9.8655 }, { "id": 16711, "name": "Antalya", "lat": 36.8838, "lon": 30.6995, "temkin": 9.9937 }, { "id": 16712, "name": "Ardahan", "lat": 41.1167, "lon": 42.7, "temkin": 10.8344 }, { "id": 16713, "name": "Artvin", "lat": 41.1833, "lon": 41.816575, "temkin": 10.8446 }, { "id": 16714, "name": "Aydın", "lat": 37.849833, "lon": 27.849625, "temkin": 10.1726 }, { "id": 16715, "name": "Balıkesir", "lat": 39.65, "lon": 27.882362, "temkin": 10.5209 }, { "id": 16716, "name": "Bartın", "lat": 41.633133, "lon": 32.333175, "temkin": 10.9118 }, { "id": 16717, "name": "Batman", "lat": 37.8662, "lon": 41.116325, "temkin": 10.1742 }, { "id": 16718, "name": "Bayburt", "lat": 40.2505, "lon": 40.232175, "temkin": 10.6513 }, { "id": 16719, "name": "Bilecik", "lat": 40.149833, "lon": 29.9828, "temkin": 10.6312 }, { "id": 16720, "name": "Bingöl", "lat": 38.883133, "lon": 40.48305, "temkin": 10.3613 }, { "id": 16721, "name": "Bitlis", "lat": 38.3828, "lon": 42.099375, "temkin": 10.2697 }, { "id": 16722, "name": "Bolu", "lat": 40.733133, "lon": 31.61645, "temkin": 10.7573 }, { "id": 16723, "name": "Burdur", "lat": 37.7162, "lon": 30.283425, "temkin": 10.149 }, { "id": 16724, "name": "Bursa", "lat": 40.200333, "lon": 29.066325, "temkin": 10.6428 }, { "id": 16725, "name": "Çanakkale", "lat": 40.15, "lon": 26.416012, "temkin": 10.6307 }, { "id": 16726, "name": "Çankırı", "lat": 40.6, "lon": 33.6167, "temkin": 10.7299 }, { "id": 16727, "name": "Çorum", "lat": 40.55, "lon": 34.949625, "temkin": 10.7186 }, { "id": 16728, "name": "Denizli", "lat": 37.7833, "lon": 29.083175, "temkin": 10.1605 }, { "id": 16729, "name": "Diyarbakır", "lat": 37.9167, "lon": 40.232675, "temkin": 10.1822 }, { "id": 16730, "name": "Edirne", "lat": 41.666367, "lon": 26.566575, "temkin": 10.9169 }, { "id": 16731, "name": "Elazığ", "lat": 38.683467, "lon": 39.23305, "temkin": 10.3245 }, { "id": 16732, "name": "Erzincan", "lat": 39.75, "lon": 39.499875, "temkin": 10.5473 }, { "id": 16733, "name": "Erzurum", "lat": 39.916533, "lon": 41.266325, "temkin": 10.5817 }, { "id": 16734, "name": "Eskişehir", "lat": 39.782133, "lon": 30.51595, "temkin": 10.553 }, { "id": 16735, "name": "Gaziantep", "lat": 37.066367, "lon": 37.38305, "temkin": 10.0276 }, { "id": 16736, "name": "Giresun", "lat": 40.916367, "lon": 38.399875, "temkin": 10.7996 }, { "id": 16737, "name": "Gümüşhane", "lat": 40.449, "lon": 39.482925, "temkin": 10.696 }, { "id": 16738, "name": "Hakkâri", "lat": 37.5833, "lon": 43.733238, "temkin": 10.1245 }, { "id": 16739, "name": "Iğdır", "lat": 39.916533, "lon": 44.032987, "temkin": 10.5817 }, { "id": 16740, "name": "Isparta", "lat": 37.767033, "lon": 30.549625, "temkin": 10.1573 }, { "id": 16741, "name": "İstanbul", "lat": 41.000167, "lon": 28.999625, "temkin": 10.815 }, { "id": 16742, "name": "İzmir", "lat": 38.416367, "lon": 27.132987, "temkin": 10.2768 }, { "id": 16743, "name": "Kahramanmaraş", "lat": 37.5833, "lon": 36.932925, "temkin": 10.1225 }, { "id": 16744, "name": "Karabük", "lat": 41.199833, "lon": 32.632425, "temkin": 10.8451 }, { "id": 16745, "name": "Karaman", "lat": 37.183633, "lon": 33.21595, "temkin": 10.0491 }, { "id": 16746, "name": "Kars", "lat": 40.5995, "lon": 43.083175, "temkin": 10.7284 }, { "id": 16747, "name": "Kastamonu", "lat": 41.366533, "lon": 33.78305, "temkin": 10.8723 }, { "id": 16748, "name": "Kayseri", "lat": 38.732967, "lon": 35.48305, "temkin": 10.3331 }, { "id": 16749, "name": "Kilis", "lat": 36.716867, "lon": 37.116325, "temkin": 9.9638 }, { "id": 16750, "name": "Kırıkkale", "lat": 39.8495, "lon": 33.499625, "temkin": 10.5663 }, { "id": 16751, "name": "Kırklareli", "lat": 41.733467, "lon": 27.216575, "temkin": 10.9278 }, { "id": 16752, "name": "Kırşehir", "lat": 39.149167, "lon": 34.166075, "temkin": 10.4142 }, { "id": 16753, "name": "Konya", "lat": 37.866033, "lon": 32.48305, "temkin": 10.1762 }, { "id": 16754, "name": "Kütahya", "lat": 39.4167, "lon": 29.982675, "temkin": 10.4721 }, { "id": 16755, "name": "Malatya", "lat": 38.349667, "lon": 38.315575, "temkin": 10.2622 }, { "id": 16756, "name": "Manisa", "lat": 38.599833, "lon": 27.4328, "temkin": 10.3105 }, { "id": 16757, "name": "Mardin", "lat": 37.3, "lon": 40.7333, "temkin": 10.0723 }, { "id": 16758, "name": "Mersin", "lat": 36.800167, "lon": 34.633237, "temkin": 9.9795 }, { "id": 16759, "name": "Muğla", "lat": 37.2167, "lon": 28.36645, "temkin": 10.0572 }, { "id": 16760, "name": "Muş", "lat": 38.733633, "lon": 41.4995, "temkin": 10.3326 }, { "id": 16761, "name": "Nevşehir", "lat": 38.632967, "lon": 34.716575, "temkin": 10.3156 }, { "id": 16762, "name": "Niğde", "lat": 37.9667, "lon": 34.6828, "temkin": 10.1917 }, { "id": 16763, "name": "Ordu", "lat": 40.982967, "lon": 37.8828, "temkin": 10.8126 }, { "id": 16764, "name": "Osmaniye", "lat": 37.066033, "lon": 36.249375, "temkin": 10.0281 }, { "id": 16765, "name": "Rize", "lat": 41.032967, "lon": 40.516575, "temkin": 10.8218 }, { "id": 16766, "name": "Samsun", "lat": 41.2833, "lon": 36.33305, "temkin": 10.8589 }, { "id": 16767, "name": "Siirt", "lat": 37.9328, "lon": 41.94975, "temkin": 10.1869 }, { "id": 16768, "name": "Sinop", "lat": 42.033133, "lon": 35.14975, "temkin": 10.9773 }, { "id": 16769, "name": "Sivas", "lat": 39.7495, "lon": 37.01645, "temkin": 10.5443 }, { "id": 16770, "name": "Şanlıurfa", "lat": 37.1505, "lon": 38.7995, "temkin": 10.0431 }, { "id": 16771, "name": "Şırnak", "lat": 37.5167, "lon": 42.466825, "temkin": 10.1122 }, { "id": 16772, "name": "Tekirdağ", "lat": 40.9833, "lon": 27.51645, "temkin": 10.8131 }, { "id": 16773, "name": "Tokat", "lat": 40.316367, "lon": 36.549625, "temkin": 10.6687 }, { "id": 16774, "name": "Trabzon", "lat": 41, "lon": 39.7162, "temkin": 10.815 }, { "id": 16775, "name": "Tunceli", "lat": 39.116533, "lon": 39.532925, "temkin": 10.4079 }, { "id": 18138, "name": "Uşak", "lat": 38.682467, "lon": 29.399875, "temkin": 10.3235 }, { "id": 18159, "name": "Van", "lat": 38.498833, "lon": 43.3828, "temkin": 10.2907 }, { "id": 18161, "name": "Yalova", "lat": 40.65, "lon": 29.266075, "temkin": 10.7413 }, { "id": 18180, "name": "Yozgat", "lat": 39.816867, "lon": 34.7995, "temkin": 10.5606 }, { "id": 18196, "name": "Zonguldak", "lat": 41.450167, "lon": 31.799563, "temkin": 10.8828 }, { "id": 18197, "name": "Düzce", "lat": 40.849667, "lon": 31.149875, "temkin": 10.7827 }, { "id": 62353, "name": "İzmit", "lat": 40.766533, "lon": 29.949625, "temkin": 10.766 }];
|
|
5
|
+
exports.default = data;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const data = { "certified": true, "checkedAt": "2026-11-11", "places": 81, "checks": [{ "tables": "Türkiye Takvimi — its cities’ years", "places": 81, "times": 178848, "off": 0, "offWithoutCorrections": 52, "from": "2025-12-31", "to": "2027-01-02" }], "corrections": { "from": "2025-12-31", "to": "2027-01-02", "entries": 52, "sha256": "a3059fd5aae0b0f8ddee10a2aaaf93e982ded12e652f6aa21d0a3d347a082b41" }, "revision": 1 };
|
|
4
|
+
exports.default = data;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const data = { "from": "2025-12-31", "to": "2027-01-02", "points": { "36.999,35.316": ["2026-01-07 fajr -1"], "37.184,33.216": ["2026-01-20 fajr -1", "2026-01-27 fajr -1"], "37.217,28.366": ["2026-11-18 sunrise +1"], "37.767,30.550": ["2026-05-26 isha -1"], "37.850,27.850": ["2026-03-06 dhuhr -1"], "37.866,32.483": ["2026-06-08 maghrib +1"], "37.917,40.233": ["2026-11-16 dhuhr +1"], "38.367,34.033": ["2026-04-16 isha -1"], "38.383,42.099": ["2026-03-26 maghrib -1"], "38.633,34.717": ["2026-05-31 asr +1", "2026-07-02 asr +1"], "38.733,35.483": ["2026-05-04 isha +1"], "38.883,40.483": ["2026-03-25 sunrise -1"], "39.716,43.050": ["2026-02-01 isha -1", "2026-02-20 fajr -1", "2026-03-04 maghrib -1"], "39.750,39.500": ["2026-01-17 isha -1", "2026-02-22 dhuhr -1"], "39.933,32.849": ["2026-02-22 isha -1"], "40.316,36.550": ["2026-02-01 dhuhr -1"], "40.599,43.083": ["2026-05-06 dhuhr +1"], "40.650,29.266": ["2026-01-26 asr -1"], "40.650,35.833": ["2026-10-03 fajr +1"], "40.733,31.616": ["2026-03-24 maghrib +1", "2026-09-08 dhuhr +1"], "40.767,29.950": ["2026-03-05 maghrib -1", "2026-04-14 sunrise -1"], "40.850,31.150": ["2026-07-19 sunrise -1"], "40.983,27.516": ["2026-07-03 dhuhr +1", "2026-11-26 dhuhr +1", "2026-12-23 asr +1"], "41.000,29.000": ["2026-03-31 sunrise -1", "2026-12-15 maghrib -1", "2026-12-16 maghrib -1", "2026-12-17 maghrib -1", "2026-12-17 sunrise -1", "2026-12-18 maghrib -1", "2026-12-21 maghrib -1", "2026-12-24 sunrise -1", "2026-12-27 sunrise -1", "2026-12-31 sunrise -1"], "41.033,40.517": ["2026-04-19 maghrib +1"], "41.200,32.632": ["2026-02-20 dhuhr -1", "2026-03-21 fajr -1"], "41.367,33.783": ["2026-04-05 asr -1"], "41.450,31.800": ["2026-05-22 sunrise -1", "2026-08-09 asr +1"], "41.666,26.567": ["2026-04-23 isha +1"], "41.733,27.217": ["2026-06-28 fajr +1", "2026-09-19 isha -1"], "42.033,35.150": ["2026-10-11 maghrib +1"] } };
|
|
4
|
+
exports.default = data;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -15,5 +15,6 @@ import './authorities/diyanet.js';
|
|
|
15
15
|
import './authorities/morocco.js';
|
|
16
16
|
import './authorities/algeria.js';
|
|
17
17
|
import './authorities/indonesia.js';
|
|
18
|
+
import './authorities/turkiyeTakvimi.js';
|
|
18
19
|
export * from './core/index.js';
|
|
19
20
|
export { diyanetCountry } from './authorities/diyanet.js';
|
package/dist/cjs/index.js
CHANGED
|
@@ -32,6 +32,7 @@ require("./authorities/diyanet.js");
|
|
|
32
32
|
require("./authorities/morocco.js");
|
|
33
33
|
require("./authorities/algeria.js");
|
|
34
34
|
require("./authorities/indonesia.js");
|
|
35
|
+
require("./authorities/turkiyeTakvimi.js");
|
|
35
36
|
__exportStar(require("./core/index.js"), exports);
|
|
36
37
|
var diyanet_js_1 = require("./authorities/diyanet.js");
|
|
37
38
|
Object.defineProperty(exports, "diyanetCountry", { enumerable: true, get: function () { return diyanet_js_1.diyanetCountry; } });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type TakvimInstants = {
|
|
2
|
+
fajr: Date;
|
|
3
|
+
sunrise: Date;
|
|
4
|
+
dhuhr: Date;
|
|
5
|
+
asr: Date;
|
|
6
|
+
maghrib: Date;
|
|
7
|
+
isha: Date;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The calendar's temkin by its formula, minutes: the time the sun takes on
|
|
11
|
+
* the summer solstice at this latitude to go from the level horizon to the
|
|
12
|
+
* city's own. A listed place carries its own (`Place.temkin`), which strays
|
|
13
|
+
* from this by a few hundredths of a minute.
|
|
14
|
+
*/
|
|
15
|
+
export declare function takvimTemkin(latitude: number, heightM?: number): number;
|
|
16
|
+
/** The day whose night times stand for this one: itself, or the last before it whose night reached 19°. */
|
|
17
|
+
export declare function heldNight(latitude: number, longitude: number, key: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* The calendar's times before rounding, minutes past 00:00 UT of the date
|
|
20
|
+
* (month 0-based): the six the library gives, and İmsâk. A held night's
|
|
21
|
+
* times are that night's time of day, on this date.
|
|
22
|
+
*/
|
|
23
|
+
export declare function takvimRawMinutes(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number, asrShadow?: number): {
|
|
24
|
+
imsak: number;
|
|
25
|
+
fajr: number;
|
|
26
|
+
sunrise: number;
|
|
27
|
+
dhuhr: number;
|
|
28
|
+
asr: number;
|
|
29
|
+
maghrib: number;
|
|
30
|
+
isha: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The calendar's İmsâk for the date, on the minute (rounded down), or null
|
|
34
|
+
* where it does not form. Not one of the six times the library certifies.
|
|
35
|
+
*/
|
|
36
|
+
export declare function takvimImsak(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number): Date | null;
|
|
37
|
+
/**
|
|
38
|
+
* Türkiye Takvimi's times for the civil date (month 0-based) at the point,
|
|
39
|
+
* each on the minute the calendar prints; Fajr is its Sabâh. Null where a
|
|
40
|
+
* time does not form.
|
|
41
|
+
*/
|
|
42
|
+
export declare function takvimTimes(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number, asrShadow?: number): TakvimInstants | null;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.takvimTemkin = takvimTemkin;
|
|
4
|
+
exports.heldNight = heldNight;
|
|
5
|
+
exports.takvimRawMinutes = takvimRawMinutes;
|
|
6
|
+
exports.takvimImsak = takvimImsak;
|
|
7
|
+
exports.takvimTimes = takvimTimes;
|
|
8
|
+
/**
|
|
9
|
+
* Türkiye Takvimi — the calendar's method, as the year it publishes for a
|
|
10
|
+
* city is computed (namazvakti.com).
|
|
11
|
+
*
|
|
12
|
+
* Read off the calendar's own years (cities from 42°S to 60°N):
|
|
13
|
+
*
|
|
14
|
+
* • the precise apparent sun, taken at each event's own moment (iterated);
|
|
15
|
+
* • a temkin T per city, in minutes with its fraction: the time the sun
|
|
16
|
+
* takes on the summer solstice (declination 23.38°) to go from the
|
|
17
|
+
* level horizon down to the city's own, which depends on the height the
|
|
18
|
+
* calendar gives the city (250 m or 500 m). A place carries the T its
|
|
19
|
+
* table shows (`Place.temkin`); `takvimTemkin` is the formula;
|
|
20
|
+
* • İmsâk the sun 19° below the horizon, less T, rounded DOWN;
|
|
21
|
+
* • Sabâh — the time the calendar prints for the Fajr prayer — the sun at
|
|
22
|
+
* 18°, with no temkin;
|
|
23
|
+
* • sunrise the sun's centre on the level horizon (0°, no refraction),
|
|
24
|
+
* less T and two minutes;
|
|
25
|
+
* • Dhuhr the transit plus T; Asr and Isha (17°) plus T;
|
|
26
|
+
* • Asr's shadow the object's length plus the noon shadow at the
|
|
27
|
+
* declination of local noon, the hour angle from the sun at Asr itself;
|
|
28
|
+
* • Maghrib the sun's centre on the level horizon, plus T and two minutes;
|
|
29
|
+
* • everything but İmsâk rounded UP to the minute.
|
|
30
|
+
*
|
|
31
|
+
* Where the sun no longer gets 19° below the horizon (north of about 47.5°
|
|
32
|
+
* in summer) the calendar holds İmsâk, Sabâh and Isha at the times of the
|
|
33
|
+
* last night it did; `heldNight` is that rule. No place of the certified
|
|
34
|
+
* list is that far north, so the list does not hold the rule to a table.
|
|
35
|
+
*
|
|
36
|
+
* The calendar's files give a city's point to the whole arc-minute and the
|
|
37
|
+
* calendar computes at a finer one; each place is at the point its year
|
|
38
|
+
* shows (data/places/turkiyeTakvimiCities.json).
|
|
39
|
+
*/
|
|
40
|
+
const preciseSun_js_1 = require("../sun/preciseSun.js");
|
|
41
|
+
const RAD = Math.PI / 180;
|
|
42
|
+
const DAY_MS = 86_400_000;
|
|
43
|
+
/** The declination the temkin's solstice is taken at, degrees. */
|
|
44
|
+
const SOLSTICE_DECLINATION = 23.38;
|
|
45
|
+
/** Minutes on sunrise and Maghrib beyond the temkin. */
|
|
46
|
+
const HORIZON_MARGIN = 2;
|
|
47
|
+
/** Days to look back for a night that reached 19°. */
|
|
48
|
+
const HOLD_SEARCH_DAYS = 200;
|
|
49
|
+
/** The depression of a city's horizon below the level one, degrees, for the calendar's height of the city. */
|
|
50
|
+
function horizonDepth(heightM) {
|
|
51
|
+
return 0.8416 + 0.03924 * Math.sqrt(Math.max(0, heightM));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The calendar's temkin by its formula, minutes: the time the sun takes on
|
|
55
|
+
* the summer solstice at this latitude to go from the level horizon to the
|
|
56
|
+
* city's own. A listed place carries its own (`Place.temkin`), which strays
|
|
57
|
+
* from this by a few hundredths of a minute.
|
|
58
|
+
*/
|
|
59
|
+
function takvimTemkin(latitude, heightM = 250) {
|
|
60
|
+
const phi = Math.min(Math.abs(latitude), 62) * RAD;
|
|
61
|
+
const dec = SOLSTICE_DECLINATION * RAD;
|
|
62
|
+
const hourAngle = (alt) => Math.acos(Math.max(-1, Math.min(1, (Math.sin(alt * RAD) - Math.sin(phi) * Math.sin(dec)) / (Math.cos(phi) * Math.cos(dec)))));
|
|
63
|
+
return ((hourAngle(-horizonDepth(heightM)) - hourAngle(0)) / RAD) * 4;
|
|
64
|
+
}
|
|
65
|
+
/** Whole days since 1970-01-01 of a civil date (month 0-based). */
|
|
66
|
+
const dayKeyOf = (year, month, day) => Math.round(Date.UTC(year, month, day) / DAY_MS);
|
|
67
|
+
/** Days from J2000.0 (noon) of a day's 00:00 UT. */
|
|
68
|
+
const d0Of = (key) => key - 10957 - 0.5;
|
|
69
|
+
/** The sun's events of a day at a point, minutes past the day's 00:00 UT; NaN where one does not happen. */
|
|
70
|
+
function events(latitude, longitude, key) {
|
|
71
|
+
const d0 = d0Of(key);
|
|
72
|
+
const at = (t) => (0, preciseSun_js_1.preciseApparentSun)(d0 + t / 1440);
|
|
73
|
+
let noon = 720 - 4 * longitude;
|
|
74
|
+
for (let i = 0; i < 3; i++)
|
|
75
|
+
noon = 720 - 4 * longitude - at(noon).eot;
|
|
76
|
+
const noonDec = at(noon).dec;
|
|
77
|
+
const sp = Math.sin(latitude * RAD);
|
|
78
|
+
const cp = Math.cos(latitude * RAD);
|
|
79
|
+
const event = (alt, sign, start) => {
|
|
80
|
+
let t = start;
|
|
81
|
+
for (let i = 0; i < 3; i++) {
|
|
82
|
+
const { dec, eot } = at(t);
|
|
83
|
+
const c = (Math.sin(alt * RAD) - sp * Math.sin(dec)) / (cp * Math.cos(dec));
|
|
84
|
+
if (!(Math.abs(c) <= 1))
|
|
85
|
+
return NaN;
|
|
86
|
+
t = 720 - 4 * longitude - eot + (sign * 4 * Math.acos(c)) / RAD;
|
|
87
|
+
}
|
|
88
|
+
return t;
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
noon,
|
|
92
|
+
at19: () => event(-19, -1, noon - 420),
|
|
93
|
+
at18: () => event(-18, -1, noon - 420),
|
|
94
|
+
sunrise: () => event(0, -1, noon - 360),
|
|
95
|
+
asr: (shadow) => event(Math.atan(1 / (shadow + Math.tan(Math.abs(latitude * RAD - noonDec)))) / RAD, 1, noon + 200),
|
|
96
|
+
sunset: () => event(0, 1, noon + 360),
|
|
97
|
+
at17: () => event(-17, 1, noon + 420),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Does the sun get 19° below the horizon in the night that ends on the
|
|
102
|
+
* morning of the day? The calendar counts it as reaching when its lowest
|
|
103
|
+
* point does at the declination of either of two moments: the local solar
|
|
104
|
+
* midnight that begins the day, or 12:00 UT of the day.
|
|
105
|
+
*/
|
|
106
|
+
function reaches19(latitude, longitude, key) {
|
|
107
|
+
const d0 = d0Of(key);
|
|
108
|
+
const lowest = (d) => Math.abs(latitude + (0, preciseSun_js_1.preciseApparentSun)(d).dec / RAD) - 90;
|
|
109
|
+
return Math.min(lowest(d0 - longitude / 360), lowest(d0 + 0.5)) <= -19;
|
|
110
|
+
}
|
|
111
|
+
/** The day whose night times stand for this one: itself, or the last before it whose night reached 19°. */
|
|
112
|
+
function heldNight(latitude, longitude, key) {
|
|
113
|
+
for (let i = 0; i <= HOLD_SEARCH_DAYS; i++)
|
|
114
|
+
if (reaches19(latitude, longitude, key - i))
|
|
115
|
+
return key - i;
|
|
116
|
+
return key;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The calendar's times before rounding, minutes past 00:00 UT of the date
|
|
120
|
+
* (month 0-based): the six the library gives, and İmsâk. A held night's
|
|
121
|
+
* times are that night's time of day, on this date.
|
|
122
|
+
*/
|
|
123
|
+
function takvimRawMinutes(latitude, longitude, year, month, day, temkin = takvimTemkin(latitude), asrShadow = 1) {
|
|
124
|
+
const key = dayKeyOf(year, month, day);
|
|
125
|
+
const today = events(latitude, longitude, key);
|
|
126
|
+
const night = heldNight(latitude, longitude, key);
|
|
127
|
+
const nightSun = night === key ? today : events(latitude, longitude, night);
|
|
128
|
+
// Isha belongs to the night that begins this evening: it is tomorrow's night that decides,
|
|
129
|
+
// and a held Isha is that of the evening before the last night that reached 19°.
|
|
130
|
+
const ishaNight = heldNight(latitude, longitude, key + 1);
|
|
131
|
+
const ishaDay = ishaNight === key + 1 ? key : ishaNight - 1;
|
|
132
|
+
const ishaSun = ishaDay === key ? today : events(latitude, longitude, ishaDay);
|
|
133
|
+
return {
|
|
134
|
+
imsak: nightSun.at19() - temkin,
|
|
135
|
+
fajr: nightSun.at18(),
|
|
136
|
+
sunrise: today.sunrise() - temkin - HORIZON_MARGIN,
|
|
137
|
+
dhuhr: today.noon + temkin,
|
|
138
|
+
asr: today.asr(asrShadow) + temkin,
|
|
139
|
+
maghrib: today.sunset() + temkin + HORIZON_MARGIN,
|
|
140
|
+
isha: ishaSun.at17() + temkin,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/** Up to the minute, as the calendar rounds everything but İmsâk. */
|
|
144
|
+
const up = (m) => Math.ceil(m - 1e-9);
|
|
145
|
+
/**
|
|
146
|
+
* The calendar's İmsâk for the date, on the minute (rounded down), or null
|
|
147
|
+
* where it does not form. Not one of the six times the library certifies.
|
|
148
|
+
*/
|
|
149
|
+
function takvimImsak(latitude, longitude, year, month, day, temkin) {
|
|
150
|
+
const m = takvimRawMinutes(latitude, longitude, year, month, day, temkin).imsak;
|
|
151
|
+
return Number.isFinite(m) ? new Date(Date.UTC(year, month, day) + Math.floor(m + 1e-9) * 60_000) : null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Türkiye Takvimi's times for the civil date (month 0-based) at the point,
|
|
155
|
+
* each on the minute the calendar prints; Fajr is its Sabâh. Null where a
|
|
156
|
+
* time does not form.
|
|
157
|
+
*/
|
|
158
|
+
function takvimTimes(latitude, longitude, year, month, day, temkin, asrShadow = 1) {
|
|
159
|
+
const r = takvimRawMinutes(latitude, longitude, year, month, day, temkin, asrShadow);
|
|
160
|
+
const all = [r.fajr, r.sunrise, r.dhuhr, r.asr, r.maghrib, r.isha];
|
|
161
|
+
if (!all.every(Number.isFinite))
|
|
162
|
+
return null;
|
|
163
|
+
const start = Date.UTC(year, month, day);
|
|
164
|
+
const at = (m) => new Date(start + up(m) * 60_000);
|
|
165
|
+
return { fajr: at(r.fajr), sunrise: at(r.sunrise), dhuhr: at(r.dhuhr), asr: at(r.asr), maghrib: at(r.maghrib), isha: at(r.isha) };
|
|
166
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.places = void 0;
|
|
18
|
+
/** mihrab-methods/turkiyetakvimi — the Türkiye Takvimi method with its places and correction list, and nothing else's. */
|
|
19
|
+
require("./authorities/turkiyeTakvimi.js");
|
|
20
|
+
__exportStar(require("./core/index.js"), exports);
|
|
21
|
+
var turkiyeTakvimi_js_1 = require("./authorities/turkiyeTakvimi.js");
|
|
22
|
+
Object.defineProperty(exports, "places", { enumerable: true, get: function () { return turkiyeTakvimi_js_1.places; } });
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Türkiye Takvimi — the calendar's cities, each at the point and with the
|
|
3
|
+
* temkin its published year is computed with. The first list is Türkiye's
|
|
4
|
+
* 81 province centres.
|
|
5
|
+
*/
|
|
6
|
+
import cities from '../data/generated/turkiyeTakvimiCities.js';
|
|
7
|
+
import corrections from '../data/generated/turkiyetakvimiCorrections.js';
|
|
8
|
+
import certification from '../data/generated/turkiyetakvimiCertification.js';
|
|
9
|
+
import { METHOD_REVISION } from '../methods/revisions.js';
|
|
10
|
+
import { registerAuthority } from '../core/registry.js';
|
|
11
|
+
const AUTHORITY = 'turkiyetakvimi';
|
|
12
|
+
function buildPlaces() {
|
|
13
|
+
return cities.map(c => {
|
|
14
|
+
const key = String(c.id);
|
|
15
|
+
return {
|
|
16
|
+
authority: AUTHORITY,
|
|
17
|
+
id: `${AUTHORITY}:${key}`,
|
|
18
|
+
key,
|
|
19
|
+
name: c.name,
|
|
20
|
+
country: 'TR',
|
|
21
|
+
lat: c.lat,
|
|
22
|
+
lon: c.lon,
|
|
23
|
+
tz: 'Europe/Istanbul',
|
|
24
|
+
temkin: c.temkin,
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export const turkiyeTakvimi = registerAuthority({
|
|
29
|
+
authority: AUTHORITY,
|
|
30
|
+
revision: METHOD_REVISION.turkiyetakvimi,
|
|
31
|
+
places: buildPlaces(),
|
|
32
|
+
corrections,
|
|
33
|
+
certification,
|
|
34
|
+
description: {
|
|
35
|
+
name: 'Türkiye Takvimi',
|
|
36
|
+
method: 'The precise apparent sun at each event’s own moment, and a temkin T per city (the time the sun takes on the summer solstice from the level horizon to the city’s own). Fajr is the calendar’s Sabâh, the sun 18° below the horizon with no temkin; sunrise the sun’s centre on the level horizon less T and two minutes; Dhuhr the transit plus T; Asr (the noon shadow taken at the declination of local noon) and Isha (17°) plus T; Maghrib the level horizon plus T and two minutes; every time rounded up to the minute.',
|
|
37
|
+
countries: ['TR'],
|
|
38
|
+
parameters: {
|
|
39
|
+
fajrAngle: 18,
|
|
40
|
+
ishaAngle: 17,
|
|
41
|
+
sunriseAltitude: 0,
|
|
42
|
+
asrShadow: 1,
|
|
43
|
+
asrNoonShadow: 'tan|φ − δ| at the declination of local noon',
|
|
44
|
+
temkin: 'per city, minutes: on Dhuhr, Asr, Maghrib and Isha, and before sunrise',
|
|
45
|
+
horizonMarginMinutes: 2,
|
|
46
|
+
rounding: 'up to the minute',
|
|
47
|
+
sun: 'precise apparent sun (VSOP87, IAU 2006 precession, IAU 2000B nutation), iterated at each event',
|
|
48
|
+
},
|
|
49
|
+
sources: [{ title: 'Türkiye Takvimi — namaz vakitleri', url: 'https://www.namazvakti.com/' }],
|
|
50
|
+
spec: 'docs/methods.md#türkiye-takvimi',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
export const places = turkiyeTakvimi.places;
|
package/dist/esm/core/compute.js
CHANGED
|
@@ -8,6 +8,7 @@ import { congressTimes } from '../methods/sweden.js';
|
|
|
8
8
|
import { moroccoTimes } from '../methods/morocco.js';
|
|
9
9
|
import { algeriaTimes } from '../methods/algeria.js';
|
|
10
10
|
import { kemenagTimes } from '../methods/indonesia.js';
|
|
11
|
+
import { takvimTimes } from '../methods/turkiyeTakvimi.js';
|
|
11
12
|
import { authorityData } from './registry.js';
|
|
12
13
|
import { placeClockAt } from './clock.js';
|
|
13
14
|
/**
|
|
@@ -30,12 +31,15 @@ export function candidateInstants(place, year, month, day, asrShadow = 1, opts =
|
|
|
30
31
|
}
|
|
31
32
|
case 'morocco':
|
|
32
33
|
case 'algeria':
|
|
33
|
-
case 'indonesia':
|
|
34
|
+
case 'indonesia':
|
|
35
|
+
case 'turkiyetakvimi': {
|
|
34
36
|
const t = place.authority === 'morocco'
|
|
35
37
|
? moroccoTimes(place.lat, place.lon, year, month, day, place.dipDeg, asrShadow, place.dipMaghribDeg)
|
|
36
38
|
: place.authority === 'algeria'
|
|
37
39
|
? algeriaTimes(place.lat, place.lon, year, month, day, asrShadow)
|
|
38
|
-
:
|
|
40
|
+
: place.authority === 'turkiyetakvimi'
|
|
41
|
+
? takvimTimes(place.lat, place.lon, year, month, day, place.temkin, asrShadow)
|
|
42
|
+
: kemenagTimes(place.lat, place.lon, year, month, day, { highland: place.highland, twilightDip: place.twilightDip, asrShadow, afternoon: place.afternoon });
|
|
39
43
|
// the correction list: the authority's few times on the other side of a minute (the standard Asr only)
|
|
40
44
|
const c = !t || !fix ? undefined : fix.correction(place.lat, place.lon, year, month, day);
|
|
41
45
|
if (!t || !c)
|
package/dist/esm/core/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shapes the library speaks in. Nothing here computes anything.
|
|
3
3
|
*/
|
|
4
|
-
export type Authority = 'sweden' | 'diyanet' | 'morocco' | 'algeria' | 'indonesia';
|
|
4
|
+
export type Authority = 'sweden' | 'diyanet' | 'morocco' | 'algeria' | 'indonesia' | 'turkiyetakvimi';
|
|
5
5
|
export declare const AUTHORITIES: readonly Authority[];
|
|
6
6
|
export type PrayerKey = 'fajr' | 'sunrise' | 'dhuhr' | 'asr' | 'maghrib' | 'isha';
|
|
7
7
|
export declare const PRAYER_KEYS: readonly PrayerKey[];
|
|
@@ -34,6 +34,8 @@ export type Place = {
|
|
|
34
34
|
twilightDip?: boolean;
|
|
35
35
|
/** Indonesia: where the ministry computes the regency's Asr, Maghrib and Isha, when not at its point. */
|
|
36
36
|
afternoon?: readonly [number, number];
|
|
37
|
+
/** Türkiye Takvimi: the city's temkin as its table shows it, minutes with their fraction. */
|
|
38
|
+
temkin?: number;
|
|
37
39
|
/** Diyanet: Isha's depression, 16° or 17° by country. */
|
|
38
40
|
ishaDeg?: number;
|
|
39
41
|
/**
|
package/dist/esm/core/types.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shapes the library speaks in. Nothing here computes anything.
|
|
3
3
|
*/
|
|
4
|
-
export const AUTHORITIES = ['sweden', 'diyanet', 'morocco', 'algeria', 'indonesia'];
|
|
4
|
+
export const AUTHORITIES = ['sweden', 'diyanet', 'morocco', 'algeria', 'indonesia', 'turkiyetakvimi'];
|
|
5
5
|
export const PRAYER_KEYS = ['fajr', 'sunrise', 'dhuhr', 'asr', 'maghrib', 'isha'];
|
|
6
6
|
/** The method has not reproduced its authority's tables to the minute (or not for this date). */
|
|
7
7
|
export class UncertifiedMethodError extends Error {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Generated by scripts/embed.mjs — do not edit; edit the JSON under data/ instead.
|
|
2
|
+
const data = [{ "id": 16702, "name": "Adana", "lat": 36.9995, "lon": 35.316075, "temkin": 10.0151 }, { "id": 16703, "name": "Adapazarı", "lat": 40.7833, "lon": 30.399875, "temkin": 10.7698 }, { "id": 16704, "name": "Adıyaman", "lat": 37.7667, "lon": 38.2828, "temkin": 10.1563 }, { "id": 16705, "name": "Afyonkarahisar", "lat": 38.750167, "lon": 30.549625, "temkin": 10.3374 }, { "id": 16706, "name": "Ağrı", "lat": 39.7162, "lon": 43.0495, "temkin": 10.5387 }, { "id": 16707, "name": "Aksaray", "lat": 38.3667, "lon": 34.0328, "temkin": 10.2665 }, { "id": 16708, "name": "Amasya", "lat": 40.65, "lon": 35.8333, "temkin": 10.7413 }, { "id": 16709, "name": "Ankara", "lat": 39.9333, "lon": 32.849063, "temkin": 10.5818 }, { "id": 16710, "name": "Antakya", "lat": 36.1833, "lon": 36.166263, "temkin": 9.8655 }, { "id": 16711, "name": "Antalya", "lat": 36.8838, "lon": 30.6995, "temkin": 9.9937 }, { "id": 16712, "name": "Ardahan", "lat": 41.1167, "lon": 42.7, "temkin": 10.8344 }, { "id": 16713, "name": "Artvin", "lat": 41.1833, "lon": 41.816575, "temkin": 10.8446 }, { "id": 16714, "name": "Aydın", "lat": 37.849833, "lon": 27.849625, "temkin": 10.1726 }, { "id": 16715, "name": "Balıkesir", "lat": 39.65, "lon": 27.882362, "temkin": 10.5209 }, { "id": 16716, "name": "Bartın", "lat": 41.633133, "lon": 32.333175, "temkin": 10.9118 }, { "id": 16717, "name": "Batman", "lat": 37.8662, "lon": 41.116325, "temkin": 10.1742 }, { "id": 16718, "name": "Bayburt", "lat": 40.2505, "lon": 40.232175, "temkin": 10.6513 }, { "id": 16719, "name": "Bilecik", "lat": 40.149833, "lon": 29.9828, "temkin": 10.6312 }, { "id": 16720, "name": "Bingöl", "lat": 38.883133, "lon": 40.48305, "temkin": 10.3613 }, { "id": 16721, "name": "Bitlis", "lat": 38.3828, "lon": 42.099375, "temkin": 10.2697 }, { "id": 16722, "name": "Bolu", "lat": 40.733133, "lon": 31.61645, "temkin": 10.7573 }, { "id": 16723, "name": "Burdur", "lat": 37.7162, "lon": 30.283425, "temkin": 10.149 }, { "id": 16724, "name": "Bursa", "lat": 40.200333, "lon": 29.066325, "temkin": 10.6428 }, { "id": 16725, "name": "Çanakkale", "lat": 40.15, "lon": 26.416012, "temkin": 10.6307 }, { "id": 16726, "name": "Çankırı", "lat": 40.6, "lon": 33.6167, "temkin": 10.7299 }, { "id": 16727, "name": "Çorum", "lat": 40.55, "lon": 34.949625, "temkin": 10.7186 }, { "id": 16728, "name": "Denizli", "lat": 37.7833, "lon": 29.083175, "temkin": 10.1605 }, { "id": 16729, "name": "Diyarbakır", "lat": 37.9167, "lon": 40.232675, "temkin": 10.1822 }, { "id": 16730, "name": "Edirne", "lat": 41.666367, "lon": 26.566575, "temkin": 10.9169 }, { "id": 16731, "name": "Elazığ", "lat": 38.683467, "lon": 39.23305, "temkin": 10.3245 }, { "id": 16732, "name": "Erzincan", "lat": 39.75, "lon": 39.499875, "temkin": 10.5473 }, { "id": 16733, "name": "Erzurum", "lat": 39.916533, "lon": 41.266325, "temkin": 10.5817 }, { "id": 16734, "name": "Eskişehir", "lat": 39.782133, "lon": 30.51595, "temkin": 10.553 }, { "id": 16735, "name": "Gaziantep", "lat": 37.066367, "lon": 37.38305, "temkin": 10.0276 }, { "id": 16736, "name": "Giresun", "lat": 40.916367, "lon": 38.399875, "temkin": 10.7996 }, { "id": 16737, "name": "Gümüşhane", "lat": 40.449, "lon": 39.482925, "temkin": 10.696 }, { "id": 16738, "name": "Hakkâri", "lat": 37.5833, "lon": 43.733238, "temkin": 10.1245 }, { "id": 16739, "name": "Iğdır", "lat": 39.916533, "lon": 44.032987, "temkin": 10.5817 }, { "id": 16740, "name": "Isparta", "lat": 37.767033, "lon": 30.549625, "temkin": 10.1573 }, { "id": 16741, "name": "İstanbul", "lat": 41.000167, "lon": 28.999625, "temkin": 10.815 }, { "id": 16742, "name": "İzmir", "lat": 38.416367, "lon": 27.132987, "temkin": 10.2768 }, { "id": 16743, "name": "Kahramanmaraş", "lat": 37.5833, "lon": 36.932925, "temkin": 10.1225 }, { "id": 16744, "name": "Karabük", "lat": 41.199833, "lon": 32.632425, "temkin": 10.8451 }, { "id": 16745, "name": "Karaman", "lat": 37.183633, "lon": 33.21595, "temkin": 10.0491 }, { "id": 16746, "name": "Kars", "lat": 40.5995, "lon": 43.083175, "temkin": 10.7284 }, { "id": 16747, "name": "Kastamonu", "lat": 41.366533, "lon": 33.78305, "temkin": 10.8723 }, { "id": 16748, "name": "Kayseri", "lat": 38.732967, "lon": 35.48305, "temkin": 10.3331 }, { "id": 16749, "name": "Kilis", "lat": 36.716867, "lon": 37.116325, "temkin": 9.9638 }, { "id": 16750, "name": "Kırıkkale", "lat": 39.8495, "lon": 33.499625, "temkin": 10.5663 }, { "id": 16751, "name": "Kırklareli", "lat": 41.733467, "lon": 27.216575, "temkin": 10.9278 }, { "id": 16752, "name": "Kırşehir", "lat": 39.149167, "lon": 34.166075, "temkin": 10.4142 }, { "id": 16753, "name": "Konya", "lat": 37.866033, "lon": 32.48305, "temkin": 10.1762 }, { "id": 16754, "name": "Kütahya", "lat": 39.4167, "lon": 29.982675, "temkin": 10.4721 }, { "id": 16755, "name": "Malatya", "lat": 38.349667, "lon": 38.315575, "temkin": 10.2622 }, { "id": 16756, "name": "Manisa", "lat": 38.599833, "lon": 27.4328, "temkin": 10.3105 }, { "id": 16757, "name": "Mardin", "lat": 37.3, "lon": 40.7333, "temkin": 10.0723 }, { "id": 16758, "name": "Mersin", "lat": 36.800167, "lon": 34.633237, "temkin": 9.9795 }, { "id": 16759, "name": "Muğla", "lat": 37.2167, "lon": 28.36645, "temkin": 10.0572 }, { "id": 16760, "name": "Muş", "lat": 38.733633, "lon": 41.4995, "temkin": 10.3326 }, { "id": 16761, "name": "Nevşehir", "lat": 38.632967, "lon": 34.716575, "temkin": 10.3156 }, { "id": 16762, "name": "Niğde", "lat": 37.9667, "lon": 34.6828, "temkin": 10.1917 }, { "id": 16763, "name": "Ordu", "lat": 40.982967, "lon": 37.8828, "temkin": 10.8126 }, { "id": 16764, "name": "Osmaniye", "lat": 37.066033, "lon": 36.249375, "temkin": 10.0281 }, { "id": 16765, "name": "Rize", "lat": 41.032967, "lon": 40.516575, "temkin": 10.8218 }, { "id": 16766, "name": "Samsun", "lat": 41.2833, "lon": 36.33305, "temkin": 10.8589 }, { "id": 16767, "name": "Siirt", "lat": 37.9328, "lon": 41.94975, "temkin": 10.1869 }, { "id": 16768, "name": "Sinop", "lat": 42.033133, "lon": 35.14975, "temkin": 10.9773 }, { "id": 16769, "name": "Sivas", "lat": 39.7495, "lon": 37.01645, "temkin": 10.5443 }, { "id": 16770, "name": "Şanlıurfa", "lat": 37.1505, "lon": 38.7995, "temkin": 10.0431 }, { "id": 16771, "name": "Şırnak", "lat": 37.5167, "lon": 42.466825, "temkin": 10.1122 }, { "id": 16772, "name": "Tekirdağ", "lat": 40.9833, "lon": 27.51645, "temkin": 10.8131 }, { "id": 16773, "name": "Tokat", "lat": 40.316367, "lon": 36.549625, "temkin": 10.6687 }, { "id": 16774, "name": "Trabzon", "lat": 41, "lon": 39.7162, "temkin": 10.815 }, { "id": 16775, "name": "Tunceli", "lat": 39.116533, "lon": 39.532925, "temkin": 10.4079 }, { "id": 18138, "name": "Uşak", "lat": 38.682467, "lon": 29.399875, "temkin": 10.3235 }, { "id": 18159, "name": "Van", "lat": 38.498833, "lon": 43.3828, "temkin": 10.2907 }, { "id": 18161, "name": "Yalova", "lat": 40.65, "lon": 29.266075, "temkin": 10.7413 }, { "id": 18180, "name": "Yozgat", "lat": 39.816867, "lon": 34.7995, "temkin": 10.5606 }, { "id": 18196, "name": "Zonguldak", "lat": 41.450167, "lon": 31.799563, "temkin": 10.8828 }, { "id": 18197, "name": "Düzce", "lat": 40.849667, "lon": 31.149875, "temkin": 10.7827 }, { "id": 62353, "name": "İzmit", "lat": 40.766533, "lon": 29.949625, "temkin": 10.766 }];
|
|
3
|
+
export default data;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const data = { "certified": true, "checkedAt": "2026-11-11", "places": 81, "checks": [{ "tables": "Türkiye Takvimi — its cities’ years", "places": 81, "times": 178848, "off": 0, "offWithoutCorrections": 52, "from": "2025-12-31", "to": "2027-01-02" }], "corrections": { "from": "2025-12-31", "to": "2027-01-02", "entries": 52, "sha256": "a3059fd5aae0b0f8ddee10a2aaaf93e982ded12e652f6aa21d0a3d347a082b41" }, "revision": 1 };
|
|
2
|
+
export default data;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const data = { "from": "2025-12-31", "to": "2027-01-02", "points": { "36.999,35.316": ["2026-01-07 fajr -1"], "37.184,33.216": ["2026-01-20 fajr -1", "2026-01-27 fajr -1"], "37.217,28.366": ["2026-11-18 sunrise +1"], "37.767,30.550": ["2026-05-26 isha -1"], "37.850,27.850": ["2026-03-06 dhuhr -1"], "37.866,32.483": ["2026-06-08 maghrib +1"], "37.917,40.233": ["2026-11-16 dhuhr +1"], "38.367,34.033": ["2026-04-16 isha -1"], "38.383,42.099": ["2026-03-26 maghrib -1"], "38.633,34.717": ["2026-05-31 asr +1", "2026-07-02 asr +1"], "38.733,35.483": ["2026-05-04 isha +1"], "38.883,40.483": ["2026-03-25 sunrise -1"], "39.716,43.050": ["2026-02-01 isha -1", "2026-02-20 fajr -1", "2026-03-04 maghrib -1"], "39.750,39.500": ["2026-01-17 isha -1", "2026-02-22 dhuhr -1"], "39.933,32.849": ["2026-02-22 isha -1"], "40.316,36.550": ["2026-02-01 dhuhr -1"], "40.599,43.083": ["2026-05-06 dhuhr +1"], "40.650,29.266": ["2026-01-26 asr -1"], "40.650,35.833": ["2026-10-03 fajr +1"], "40.733,31.616": ["2026-03-24 maghrib +1", "2026-09-08 dhuhr +1"], "40.767,29.950": ["2026-03-05 maghrib -1", "2026-04-14 sunrise -1"], "40.850,31.150": ["2026-07-19 sunrise -1"], "40.983,27.516": ["2026-07-03 dhuhr +1", "2026-11-26 dhuhr +1", "2026-12-23 asr +1"], "41.000,29.000": ["2026-03-31 sunrise -1", "2026-12-15 maghrib -1", "2026-12-16 maghrib -1", "2026-12-17 maghrib -1", "2026-12-17 sunrise -1", "2026-12-18 maghrib -1", "2026-12-21 maghrib -1", "2026-12-24 sunrise -1", "2026-12-27 sunrise -1", "2026-12-31 sunrise -1"], "41.033,40.517": ["2026-04-19 maghrib +1"], "41.200,32.632": ["2026-02-20 dhuhr -1", "2026-03-21 fajr -1"], "41.367,33.783": ["2026-04-05 asr -1"], "41.450,31.800": ["2026-05-22 sunrise -1", "2026-08-09 asr +1"], "41.666,26.567": ["2026-04-23 isha +1"], "41.733,27.217": ["2026-06-28 fajr +1", "2026-09-19 isha -1"], "42.033,35.150": ["2026-10-11 maghrib +1"] } };
|
|
2
|
+
export default data;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -15,5 +15,6 @@ import './authorities/diyanet.js';
|
|
|
15
15
|
import './authorities/morocco.js';
|
|
16
16
|
import './authorities/algeria.js';
|
|
17
17
|
import './authorities/indonesia.js';
|
|
18
|
+
import './authorities/turkiyeTakvimi.js';
|
|
18
19
|
export * from './core/index.js';
|
|
19
20
|
export { diyanetCountry } from './authorities/diyanet.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -15,5 +15,6 @@ import './authorities/diyanet.js';
|
|
|
15
15
|
import './authorities/morocco.js';
|
|
16
16
|
import './authorities/algeria.js';
|
|
17
17
|
import './authorities/indonesia.js';
|
|
18
|
+
import './authorities/turkiyeTakvimi.js';
|
|
18
19
|
export * from './core/index.js';
|
|
19
20
|
export { diyanetCountry } from './authorities/diyanet.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type TakvimInstants = {
|
|
2
|
+
fajr: Date;
|
|
3
|
+
sunrise: Date;
|
|
4
|
+
dhuhr: Date;
|
|
5
|
+
asr: Date;
|
|
6
|
+
maghrib: Date;
|
|
7
|
+
isha: Date;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The calendar's temkin by its formula, minutes: the time the sun takes on
|
|
11
|
+
* the summer solstice at this latitude to go from the level horizon to the
|
|
12
|
+
* city's own. A listed place carries its own (`Place.temkin`), which strays
|
|
13
|
+
* from this by a few hundredths of a minute.
|
|
14
|
+
*/
|
|
15
|
+
export declare function takvimTemkin(latitude: number, heightM?: number): number;
|
|
16
|
+
/** The day whose night times stand for this one: itself, or the last before it whose night reached 19°. */
|
|
17
|
+
export declare function heldNight(latitude: number, longitude: number, key: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* The calendar's times before rounding, minutes past 00:00 UT of the date
|
|
20
|
+
* (month 0-based): the six the library gives, and İmsâk. A held night's
|
|
21
|
+
* times are that night's time of day, on this date.
|
|
22
|
+
*/
|
|
23
|
+
export declare function takvimRawMinutes(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number, asrShadow?: number): {
|
|
24
|
+
imsak: number;
|
|
25
|
+
fajr: number;
|
|
26
|
+
sunrise: number;
|
|
27
|
+
dhuhr: number;
|
|
28
|
+
asr: number;
|
|
29
|
+
maghrib: number;
|
|
30
|
+
isha: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The calendar's İmsâk for the date, on the minute (rounded down), or null
|
|
34
|
+
* where it does not form. Not one of the six times the library certifies.
|
|
35
|
+
*/
|
|
36
|
+
export declare function takvimImsak(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number): Date | null;
|
|
37
|
+
/**
|
|
38
|
+
* Türkiye Takvimi's times for the civil date (month 0-based) at the point,
|
|
39
|
+
* each on the minute the calendar prints; Fajr is its Sabâh. Null where a
|
|
40
|
+
* time does not form.
|
|
41
|
+
*/
|
|
42
|
+
export declare function takvimTimes(latitude: number, longitude: number, year: number, month: number, day: number, temkin?: number, asrShadow?: number): TakvimInstants | null;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Türkiye Takvimi — the calendar's method, as the year it publishes for a
|
|
3
|
+
* city is computed (namazvakti.com).
|
|
4
|
+
*
|
|
5
|
+
* Read off the calendar's own years (cities from 42°S to 60°N):
|
|
6
|
+
*
|
|
7
|
+
* • the precise apparent sun, taken at each event's own moment (iterated);
|
|
8
|
+
* • a temkin T per city, in minutes with its fraction: the time the sun
|
|
9
|
+
* takes on the summer solstice (declination 23.38°) to go from the
|
|
10
|
+
* level horizon down to the city's own, which depends on the height the
|
|
11
|
+
* calendar gives the city (250 m or 500 m). A place carries the T its
|
|
12
|
+
* table shows (`Place.temkin`); `takvimTemkin` is the formula;
|
|
13
|
+
* • İmsâk the sun 19° below the horizon, less T, rounded DOWN;
|
|
14
|
+
* • Sabâh — the time the calendar prints for the Fajr prayer — the sun at
|
|
15
|
+
* 18°, with no temkin;
|
|
16
|
+
* • sunrise the sun's centre on the level horizon (0°, no refraction),
|
|
17
|
+
* less T and two minutes;
|
|
18
|
+
* • Dhuhr the transit plus T; Asr and Isha (17°) plus T;
|
|
19
|
+
* • Asr's shadow the object's length plus the noon shadow at the
|
|
20
|
+
* declination of local noon, the hour angle from the sun at Asr itself;
|
|
21
|
+
* • Maghrib the sun's centre on the level horizon, plus T and two minutes;
|
|
22
|
+
* • everything but İmsâk rounded UP to the minute.
|
|
23
|
+
*
|
|
24
|
+
* Where the sun no longer gets 19° below the horizon (north of about 47.5°
|
|
25
|
+
* in summer) the calendar holds İmsâk, Sabâh and Isha at the times of the
|
|
26
|
+
* last night it did; `heldNight` is that rule. No place of the certified
|
|
27
|
+
* list is that far north, so the list does not hold the rule to a table.
|
|
28
|
+
*
|
|
29
|
+
* The calendar's files give a city's point to the whole arc-minute and the
|
|
30
|
+
* calendar computes at a finer one; each place is at the point its year
|
|
31
|
+
* shows (data/places/turkiyeTakvimiCities.json).
|
|
32
|
+
*/
|
|
33
|
+
import { preciseApparentSun } from '../sun/preciseSun.js';
|
|
34
|
+
const RAD = Math.PI / 180;
|
|
35
|
+
const DAY_MS = 86_400_000;
|
|
36
|
+
/** The declination the temkin's solstice is taken at, degrees. */
|
|
37
|
+
const SOLSTICE_DECLINATION = 23.38;
|
|
38
|
+
/** Minutes on sunrise and Maghrib beyond the temkin. */
|
|
39
|
+
const HORIZON_MARGIN = 2;
|
|
40
|
+
/** Days to look back for a night that reached 19°. */
|
|
41
|
+
const HOLD_SEARCH_DAYS = 200;
|
|
42
|
+
/** The depression of a city's horizon below the level one, degrees, for the calendar's height of the city. */
|
|
43
|
+
function horizonDepth(heightM) {
|
|
44
|
+
return 0.8416 + 0.03924 * Math.sqrt(Math.max(0, heightM));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The calendar's temkin by its formula, minutes: the time the sun takes on
|
|
48
|
+
* the summer solstice at this latitude to go from the level horizon to the
|
|
49
|
+
* city's own. A listed place carries its own (`Place.temkin`), which strays
|
|
50
|
+
* from this by a few hundredths of a minute.
|
|
51
|
+
*/
|
|
52
|
+
export function takvimTemkin(latitude, heightM = 250) {
|
|
53
|
+
const phi = Math.min(Math.abs(latitude), 62) * RAD;
|
|
54
|
+
const dec = SOLSTICE_DECLINATION * RAD;
|
|
55
|
+
const hourAngle = (alt) => Math.acos(Math.max(-1, Math.min(1, (Math.sin(alt * RAD) - Math.sin(phi) * Math.sin(dec)) / (Math.cos(phi) * Math.cos(dec)))));
|
|
56
|
+
return ((hourAngle(-horizonDepth(heightM)) - hourAngle(0)) / RAD) * 4;
|
|
57
|
+
}
|
|
58
|
+
/** Whole days since 1970-01-01 of a civil date (month 0-based). */
|
|
59
|
+
const dayKeyOf = (year, month, day) => Math.round(Date.UTC(year, month, day) / DAY_MS);
|
|
60
|
+
/** Days from J2000.0 (noon) of a day's 00:00 UT. */
|
|
61
|
+
const d0Of = (key) => key - 10957 - 0.5;
|
|
62
|
+
/** The sun's events of a day at a point, minutes past the day's 00:00 UT; NaN where one does not happen. */
|
|
63
|
+
function events(latitude, longitude, key) {
|
|
64
|
+
const d0 = d0Of(key);
|
|
65
|
+
const at = (t) => preciseApparentSun(d0 + t / 1440);
|
|
66
|
+
let noon = 720 - 4 * longitude;
|
|
67
|
+
for (let i = 0; i < 3; i++)
|
|
68
|
+
noon = 720 - 4 * longitude - at(noon).eot;
|
|
69
|
+
const noonDec = at(noon).dec;
|
|
70
|
+
const sp = Math.sin(latitude * RAD);
|
|
71
|
+
const cp = Math.cos(latitude * RAD);
|
|
72
|
+
const event = (alt, sign, start) => {
|
|
73
|
+
let t = start;
|
|
74
|
+
for (let i = 0; i < 3; i++) {
|
|
75
|
+
const { dec, eot } = at(t);
|
|
76
|
+
const c = (Math.sin(alt * RAD) - sp * Math.sin(dec)) / (cp * Math.cos(dec));
|
|
77
|
+
if (!(Math.abs(c) <= 1))
|
|
78
|
+
return NaN;
|
|
79
|
+
t = 720 - 4 * longitude - eot + (sign * 4 * Math.acos(c)) / RAD;
|
|
80
|
+
}
|
|
81
|
+
return t;
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
noon,
|
|
85
|
+
at19: () => event(-19, -1, noon - 420),
|
|
86
|
+
at18: () => event(-18, -1, noon - 420),
|
|
87
|
+
sunrise: () => event(0, -1, noon - 360),
|
|
88
|
+
asr: (shadow) => event(Math.atan(1 / (shadow + Math.tan(Math.abs(latitude * RAD - noonDec)))) / RAD, 1, noon + 200),
|
|
89
|
+
sunset: () => event(0, 1, noon + 360),
|
|
90
|
+
at17: () => event(-17, 1, noon + 420),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Does the sun get 19° below the horizon in the night that ends on the
|
|
95
|
+
* morning of the day? The calendar counts it as reaching when its lowest
|
|
96
|
+
* point does at the declination of either of two moments: the local solar
|
|
97
|
+
* midnight that begins the day, or 12:00 UT of the day.
|
|
98
|
+
*/
|
|
99
|
+
function reaches19(latitude, longitude, key) {
|
|
100
|
+
const d0 = d0Of(key);
|
|
101
|
+
const lowest = (d) => Math.abs(latitude + preciseApparentSun(d).dec / RAD) - 90;
|
|
102
|
+
return Math.min(lowest(d0 - longitude / 360), lowest(d0 + 0.5)) <= -19;
|
|
103
|
+
}
|
|
104
|
+
/** The day whose night times stand for this one: itself, or the last before it whose night reached 19°. */
|
|
105
|
+
export function heldNight(latitude, longitude, key) {
|
|
106
|
+
for (let i = 0; i <= HOLD_SEARCH_DAYS; i++)
|
|
107
|
+
if (reaches19(latitude, longitude, key - i))
|
|
108
|
+
return key - i;
|
|
109
|
+
return key;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The calendar's times before rounding, minutes past 00:00 UT of the date
|
|
113
|
+
* (month 0-based): the six the library gives, and İmsâk. A held night's
|
|
114
|
+
* times are that night's time of day, on this date.
|
|
115
|
+
*/
|
|
116
|
+
export function takvimRawMinutes(latitude, longitude, year, month, day, temkin = takvimTemkin(latitude), asrShadow = 1) {
|
|
117
|
+
const key = dayKeyOf(year, month, day);
|
|
118
|
+
const today = events(latitude, longitude, key);
|
|
119
|
+
const night = heldNight(latitude, longitude, key);
|
|
120
|
+
const nightSun = night === key ? today : events(latitude, longitude, night);
|
|
121
|
+
// Isha belongs to the night that begins this evening: it is tomorrow's night that decides,
|
|
122
|
+
// and a held Isha is that of the evening before the last night that reached 19°.
|
|
123
|
+
const ishaNight = heldNight(latitude, longitude, key + 1);
|
|
124
|
+
const ishaDay = ishaNight === key + 1 ? key : ishaNight - 1;
|
|
125
|
+
const ishaSun = ishaDay === key ? today : events(latitude, longitude, ishaDay);
|
|
126
|
+
return {
|
|
127
|
+
imsak: nightSun.at19() - temkin,
|
|
128
|
+
fajr: nightSun.at18(),
|
|
129
|
+
sunrise: today.sunrise() - temkin - HORIZON_MARGIN,
|
|
130
|
+
dhuhr: today.noon + temkin,
|
|
131
|
+
asr: today.asr(asrShadow) + temkin,
|
|
132
|
+
maghrib: today.sunset() + temkin + HORIZON_MARGIN,
|
|
133
|
+
isha: ishaSun.at17() + temkin,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** Up to the minute, as the calendar rounds everything but İmsâk. */
|
|
137
|
+
const up = (m) => Math.ceil(m - 1e-9);
|
|
138
|
+
/**
|
|
139
|
+
* The calendar's İmsâk for the date, on the minute (rounded down), or null
|
|
140
|
+
* where it does not form. Not one of the six times the library certifies.
|
|
141
|
+
*/
|
|
142
|
+
export function takvimImsak(latitude, longitude, year, month, day, temkin) {
|
|
143
|
+
const m = takvimRawMinutes(latitude, longitude, year, month, day, temkin).imsak;
|
|
144
|
+
return Number.isFinite(m) ? new Date(Date.UTC(year, month, day) + Math.floor(m + 1e-9) * 60_000) : null;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Türkiye Takvimi's times for the civil date (month 0-based) at the point,
|
|
148
|
+
* each on the minute the calendar prints; Fajr is its Sabâh. Null where a
|
|
149
|
+
* time does not form.
|
|
150
|
+
*/
|
|
151
|
+
export function takvimTimes(latitude, longitude, year, month, day, temkin, asrShadow = 1) {
|
|
152
|
+
const r = takvimRawMinutes(latitude, longitude, year, month, day, temkin, asrShadow);
|
|
153
|
+
const all = [r.fajr, r.sunrise, r.dhuhr, r.asr, r.maghrib, r.isha];
|
|
154
|
+
if (!all.every(Number.isFinite))
|
|
155
|
+
return null;
|
|
156
|
+
const start = Date.UTC(year, month, day);
|
|
157
|
+
const at = (m) => new Date(start + up(m) * 60_000);
|
|
158
|
+
return { fajr: at(r.fajr), sunrise: at(r.sunrise), dhuhr: at(r.dhuhr), asr: at(r.asr), maghrib: at(r.maghrib), isha: at(r.isha) };
|
|
159
|
+
}
|
package/docs/methods.md
CHANGED
|
@@ -201,6 +201,45 @@ cities.
|
|
|
201
201
|
its table is computed.
|
|
202
202
|
- Each regency is printed in its province's zone (WIB, WITA or WIT).
|
|
203
203
|
|
|
204
|
+
## Türkiye Takvimi
|
|
205
|
+
|
|
206
|
+
`src/methods/turkiyeTakvimi.ts`. The calendar's own years for its cities
|
|
207
|
+
(namazvakti.com), read off cities from 42°S to 60°N.
|
|
208
|
+
|
|
209
|
+
- The **precise apparent sun** of Indonesia's method — here with ΔT added
|
|
210
|
+
to Universal Time, as the ephemeris asks — taken at each event's own
|
|
211
|
+
moment: three iterations from the transit, itself iterated
|
|
212
|
+
three times.
|
|
213
|
+
- A **temkin `T`** per city, in minutes with its fraction: the time the sun
|
|
214
|
+
takes on the summer solstice (declination 23.38°) at the city's latitude
|
|
215
|
+
`φ` to go from the level horizon to the city's own, `d` below it,
|
|
216
|
+
`T = 4 [ H(−d) − H(0) ]` with `cos H(a) = (sin a − sin φ sin 23.38°) / (cos φ cos 23.38°)`
|
|
217
|
+
and `d = 0.8416° + 0.03924° √h` for the height `h` the calendar gives the
|
|
218
|
+
city (250 m: 1.462°; 500 m: 1.719°). A listed place carries the `T` its
|
|
219
|
+
table shows (`Place.temkin`), which strays from the formula by a few
|
|
220
|
+
hundredths of a minute.
|
|
221
|
+
- **Fajr** is the calendar's Sabâh: the sun 18° below the horizon, with no
|
|
222
|
+
temkin. (Its İmsâk, which the library does not give among the six, is the
|
|
223
|
+
sun at 19° less `T`, rounded down.)
|
|
224
|
+
- **Sunrise**: the sun's centre on the level horizon (altitude 0°, no
|
|
225
|
+
refraction), less `T` and two minutes.
|
|
226
|
+
- **Dhuhr**: the transit plus `T`.
|
|
227
|
+
- **Asr**: the altitude `arccot(s + tan|φ − δ|)` with `δ` the declination
|
|
228
|
+
of local noon (the hour angle from the sun at Asr itself), plus `T`.
|
|
229
|
+
- **Maghrib**: the sun's centre on the level horizon, plus `T` and two
|
|
230
|
+
minutes.
|
|
231
|
+
- **Isha**: the sun 17° below the horizon, plus `T`.
|
|
232
|
+
- Every time rounded **up** to the minute.
|
|
233
|
+
- **Where the sun does not get 19° below the horizon** (north of about
|
|
234
|
+
47.5° in summer), İmsâk, Fajr and Isha are held at the times of the last
|
|
235
|
+
night it did. A night counts as reaching 19° when the sun's lowest point,
|
|
236
|
+
`|φ + δ| − 90°`, does at the declination of either the local solar
|
|
237
|
+
midnight that begins the day or 12:00 UT of the day. The certified list
|
|
238
|
+
has no place that far north; the rule is as the calendar's northern
|
|
239
|
+
cities show it, and no table here holds it.
|
|
240
|
+
- The calendar's files give a city's point to the whole arc-minute and it
|
|
241
|
+
computes at a finer one; each place is at the point its year shows.
|
|
242
|
+
|
|
204
243
|
## Checking a port
|
|
205
244
|
|
|
206
245
|
1. Take `test/vectors.json`. For each case, compute the six times at the
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mihrab-methods",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "The prayer-time authorities' own calculation methods, each reproducing its published timetable to the minute: Sweden (Diyanet, as Islamiska Förbundet prints it), Diyanet worldwide, Morocco (Habous), Algeria (Ministry of Religious Affairs), Indonesia (Kemenag).",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "The prayer-time authorities' own calculation methods, each reproducing its published timetable to the minute: Sweden (Diyanet, as Islamiska Förbundet prints it), Diyanet worldwide, Morocco (Habous), Algeria (Ministry of Religious Affairs), Indonesia (Kemenag), Türkiye Takvimi.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "Hassan El Ghamri",
|
|
7
7
|
"repository": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"./dist/*/morocco.js",
|
|
29
29
|
"./dist/*/algeria.js",
|
|
30
30
|
"./dist/*/indonesia.js",
|
|
31
|
+
"./dist/*/turkiyetakvimi.js",
|
|
31
32
|
"./dist/*/authorities/*.js",
|
|
32
33
|
"./src/index.ts",
|
|
33
34
|
"./src/sweden.ts",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"./src/morocco.ts",
|
|
36
37
|
"./src/algeria.ts",
|
|
37
38
|
"./src/indonesia.ts",
|
|
39
|
+
"./src/turkiyetakvimi.ts",
|
|
38
40
|
"./src/authorities/*.ts"
|
|
39
41
|
],
|
|
40
42
|
"engines": {
|
|
@@ -121,6 +123,16 @@
|
|
|
121
123
|
"default": "./dist/cjs/indonesia.js"
|
|
122
124
|
}
|
|
123
125
|
},
|
|
126
|
+
"./turkiyetakvimi": {
|
|
127
|
+
"import": {
|
|
128
|
+
"types": "./dist/esm/turkiyetakvimi.d.ts",
|
|
129
|
+
"default": "./dist/esm/turkiyetakvimi.js"
|
|
130
|
+
},
|
|
131
|
+
"require": {
|
|
132
|
+
"types": "./dist/cjs/turkiyetakvimi.d.ts",
|
|
133
|
+
"default": "./dist/cjs/turkiyetakvimi.js"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
124
136
|
"./locate": {
|
|
125
137
|
"import": {
|
|
126
138
|
"types": "./dist/esm/locate.d.ts",
|
|
@@ -156,6 +168,9 @@
|
|
|
156
168
|
"indonesia": [
|
|
157
169
|
"./dist/cjs/indonesia.d.ts"
|
|
158
170
|
],
|
|
171
|
+
"turkiyetakvimi": [
|
|
172
|
+
"./dist/cjs/turkiyetakvimi.d.ts"
|
|
173
|
+
],
|
|
159
174
|
"locate": [
|
|
160
175
|
"./dist/cjs/locate.d.ts"
|
|
161
176
|
]
|