egydata 1.0.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/LICENSE +21 -0
- package/README.md +164 -0
- package/index.mjs +4 -0
- package/package.json +50 -0
- package/src/cities.js +241 -0
- package/src/governorates.js +62 -0
- package/src/index.js +8 -0
- package/src/phoneArea.js +61 -0
- package/src/timezone.js +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 egydata
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Egydata
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/egydata)
|
|
4
|
+
[](https://github.com/ahmed-ashraf-dv/egydata/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
Structured Egyptian geographical and timezone data for Node.js and the browser.
|
|
7
|
+
|
|
8
|
+
Provides a complete, offline dataset of Egyptian governorates, cities, landline and mobile area codes, and timezone utilities — with zero dependencies.
|
|
9
|
+
|
|
10
|
+
[View on GitHub](https://github.com/ahmed-ashraf-dv/egydata) | [View on NPM](https://www.npmjs.com/package/egydata)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install egydata
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
// CommonJS
|
|
22
|
+
const { governorates, cities, phoneArea, timezone } = require('egydata');
|
|
23
|
+
|
|
24
|
+
// ESM
|
|
25
|
+
import { governorates, cities, phoneArea, timezone } from 'egydata';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Governorates
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
const { governorates } = require('egydata');
|
|
34
|
+
|
|
35
|
+
// Get all 27 governorates
|
|
36
|
+
const all = governorates.getAll();
|
|
37
|
+
// [{ id: 1, code: 'CAI', name: 'القاهرة', nameEn: 'Cairo' }, ...]
|
|
38
|
+
|
|
39
|
+
// Find by code
|
|
40
|
+
const cairo = governorates.getByCode('CAI');
|
|
41
|
+
// { id: 1, code: 'CAI', name: 'القاهرة', nameEn: 'Cairo' }
|
|
42
|
+
|
|
43
|
+
// Find by id
|
|
44
|
+
const gov = governorates.getById(2);
|
|
45
|
+
// { id: 2, code: 'ALX', name: 'الإسكندرية', nameEn: 'Alexandria' }
|
|
46
|
+
|
|
47
|
+
// Search (Arabic or English, partial match)
|
|
48
|
+
const results = governorates.search('alex');
|
|
49
|
+
// [{ id: 2, code: 'ALX', name: 'الإسكندرية', nameEn: 'Alexandria' }]
|
|
50
|
+
|
|
51
|
+
const arResults = governorates.search('القاهرة');
|
|
52
|
+
// [{ id: 1, code: 'CAI', name: 'القاهرة', nameEn: 'Cairo' }]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Cities
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
const { cities } = require('egydata');
|
|
59
|
+
|
|
60
|
+
// Get cities by governorate code
|
|
61
|
+
const cairoCities = cities.getByGovernorate('CAI');
|
|
62
|
+
// [{ id: 1, name: 'مدينة نصر', nameEn: 'Nasr City', governorateCode: 'CAI' }, ...]
|
|
63
|
+
|
|
64
|
+
// Find by id
|
|
65
|
+
const city = cities.getById(131);
|
|
66
|
+
// { id: 131, name: 'شرم الشيخ', nameEn: 'Sharm El Sheikh', governorateCode: 'SIS' }
|
|
67
|
+
|
|
68
|
+
// Search cities (Arabic or English, partial match)
|
|
69
|
+
const found = cities.search('Maadi');
|
|
70
|
+
// [{ id: 3, name: 'المعادي', nameEn: 'Maadi', governorateCode: 'CAI' }]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Phone Area Codes
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
const { phoneArea } = require('egydata');
|
|
77
|
+
|
|
78
|
+
// Get all area codes (landline and mobile)
|
|
79
|
+
const all = phoneArea.getAll();
|
|
80
|
+
// [{ code: '02', region: 'القاهرة والجيزة', regionEn: 'Cairo & Giza' }, ...]
|
|
81
|
+
|
|
82
|
+
// Look up a region by code
|
|
83
|
+
const region = phoneArea.getRegion('03');
|
|
84
|
+
// { code: '03', region: 'الإسكندرية', regionEn: 'Alexandria' }
|
|
85
|
+
|
|
86
|
+
// Find area code by region name
|
|
87
|
+
const entry = phoneArea.getCode('Mansoura');
|
|
88
|
+
// { code: '050', region: 'الدقهلية (المنصورة)', regionEn: 'Dakahlia (Mansoura)' }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Timezone
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const { timezone } = require('egydata');
|
|
95
|
+
|
|
96
|
+
console.log(timezone.name); // 'Africa/Cairo'
|
|
97
|
+
console.log(timezone.offset); // '+02:00'
|
|
98
|
+
|
|
99
|
+
const now = timezone.now(); // Current date/time in Egypt (Date object)
|
|
100
|
+
console.log(now.toISOString());
|
|
101
|
+
|
|
102
|
+
console.log(timezone.isDST()); // true or false depending on current date (Egypt resumed DST in 2023)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## API Reference
|
|
106
|
+
|
|
107
|
+
### `governorates`
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
| Method | Parameters | Returns | Description |
|
|
111
|
+
| ----------------- | ----------------- | ------------------------- | ------------------------------------------------------------ |
|
|
112
|
+
| `getAll()` | — | `Array<Governorate>` | Returns all 27 Egyptian governorates |
|
|
113
|
+
| `getByCode(code)` | `string` | `Governorate | undefined` | Find a governorate by its code (e.g. `'CAI'`) |
|
|
114
|
+
| `getById(id)` | `number | string` | `Governorate | undefined` | Find a governorate by its numeric id |
|
|
115
|
+
| `search(query)` | `string` | `Array<Governorate>` | Search by Arabic or English name (partial, case-insensitive) |
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
**Governorate shape:** `{ id: number, code: string, name: string, nameEn: string }`
|
|
119
|
+
|
|
120
|
+
### `cities`
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
| Method | Parameters | Returns | Description |
|
|
124
|
+
| --------------------------- | ----------------- | ------------------ | ------------------------------------------------------------ |
|
|
125
|
+
| `getByGovernorate(govCode)` | `string` | `Array<City>` | Get all cities in a governorate |
|
|
126
|
+
| `getById(id)` | `number | string` | `City | undefined` | Find a city by its numeric id |
|
|
127
|
+
| `search(query)` | `string` | `Array<City>` | Search by Arabic or English name (partial, case-insensitive) |
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
**City shape:** `{ id: number, name: string, nameEn: string, governorateCode: string }`
|
|
131
|
+
|
|
132
|
+
### `phoneArea`
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
| Method | Parameters | Returns | Description |
|
|
136
|
+
| --------------------- | ---------- | ---------------------- | ------------------------------------------------------- |
|
|
137
|
+
| `getAll()` | — | `Array<AreaCode>` | Returns all Egyptian landline and mobile area codes |
|
|
138
|
+
| `getRegion(code)` | `string` | `AreaCode | undefined` | Look up region info by area code |
|
|
139
|
+
| `getCode(regionName)` | `string` | `AreaCode | undefined` | Find area code entry by region name (Arabic or English) |
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
**AreaCode shape:** `{ code: string, region: string, regionEn: string }`
|
|
143
|
+
|
|
144
|
+
### `timezone`
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
| Property / Method | Returns | Description |
|
|
148
|
+
| ----------------- | ---------------- | --------------------------------------------------- |
|
|
149
|
+
| `name` | `'Africa/Cairo'` | IANA timezone identifier |
|
|
150
|
+
| `offset` | `'+02:00'` | UTC offset |
|
|
151
|
+
| `now()` | `Date` | Current date/time in Egypt |
|
|
152
|
+
| `isDST(date?)` | `boolean` | Whether DST is active (optionally for a given date) |
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
## Data Coverage
|
|
156
|
+
|
|
157
|
+
- **27** governorates with Arabic and English names
|
|
158
|
+
- **151** cities and districts across all governorates
|
|
159
|
+
- **30** landline and mobile area codes
|
|
160
|
+
- Full timezone support for `Africa/Cairo`
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
[MIT](LICENSE)
|
package/index.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "egydata",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Structured Egyptian geographical and timezone data — governorates, cities, phone area codes, and timezone utilities.",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"module": "./index.mjs",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./index.mjs",
|
|
10
|
+
"require": "./src/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "jest --coverage"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"egypt",
|
|
18
|
+
"egyptian",
|
|
19
|
+
"governorates",
|
|
20
|
+
"cities",
|
|
21
|
+
"geography",
|
|
22
|
+
"timezone",
|
|
23
|
+
"phone",
|
|
24
|
+
"area-codes",
|
|
25
|
+
"cairo",
|
|
26
|
+
"africa",
|
|
27
|
+
"arabic",
|
|
28
|
+
"محافظات",
|
|
29
|
+
"مصر"
|
|
30
|
+
],
|
|
31
|
+
"author": "Ahmed Ashraf <ahmdgun0@gmail.com> (https://github.com/ahmed-ashraf-dv)",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/ahmed-ashraf-dv/egydata.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/ahmed-ashraf-dv/egydata/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/ahmed-ashraf-dv/egydata#readme",
|
|
41
|
+
"files": [
|
|
42
|
+
"src/",
|
|
43
|
+
"index.mjs",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"jest": "^29.7.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/cities.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const cities = [
|
|
4
|
+
// Cairo (CAI)
|
|
5
|
+
{ id: 1, name: 'مدينة نصر', nameEn: 'Nasr City', governorateCode: 'CAI' },
|
|
6
|
+
{ id: 2, name: 'مصر الجديدة', nameEn: 'Heliopolis', governorateCode: 'CAI' },
|
|
7
|
+
{ id: 3, name: 'المعادي', nameEn: 'Maadi', governorateCode: 'CAI' },
|
|
8
|
+
{ id: 4, name: 'مصر القديمة', nameEn: 'Old Cairo', governorateCode: 'CAI' },
|
|
9
|
+
{ id: 5, name: 'شبرا', nameEn: 'Shubra', governorateCode: 'CAI' },
|
|
10
|
+
{ id: 6, name: 'عين شمس', nameEn: 'Ain Shams', governorateCode: 'CAI' },
|
|
11
|
+
{ id: 7, name: 'حلوان', nameEn: 'Helwan', governorateCode: 'CAI' },
|
|
12
|
+
{ id: 8, name: 'التجمع الخامس', nameEn: 'Fifth Settlement', governorateCode: 'CAI' },
|
|
13
|
+
{ id: 9, name: 'القاهرة الجديدة', nameEn: 'New Cairo', governorateCode: 'CAI' },
|
|
14
|
+
{ id: 10, name: 'المقطم', nameEn: 'Mokattam', governorateCode: 'CAI' },
|
|
15
|
+
|
|
16
|
+
// Alexandria (ALX)
|
|
17
|
+
{ id: 11, name: 'المنتزه', nameEn: 'Montaza', governorateCode: 'ALX' },
|
|
18
|
+
{ id: 12, name: 'وسط الإسكندرية', nameEn: 'Downtown Alexandria', governorateCode: 'ALX' },
|
|
19
|
+
{ id: 13, name: 'العجمي', nameEn: 'Agami', governorateCode: 'ALX' },
|
|
20
|
+
{ id: 14, name: 'سيدي بشر', nameEn: 'Sidi Bishr', governorateCode: 'ALX' },
|
|
21
|
+
{ id: 15, name: 'برج العرب', nameEn: 'Borg El Arab', governorateCode: 'ALX' },
|
|
22
|
+
{ id: 16, name: 'العامرية', nameEn: 'Amreya', governorateCode: 'ALX' },
|
|
23
|
+
|
|
24
|
+
// Giza (GIZ)
|
|
25
|
+
{ id: 17, name: 'الدقي', nameEn: 'Dokki', governorateCode: 'GIZ' },
|
|
26
|
+
{ id: 18, name: 'المهندسين', nameEn: 'Mohandessin', governorateCode: 'GIZ' },
|
|
27
|
+
{ id: 19, name: 'العجوزة', nameEn: 'Agouza', governorateCode: 'GIZ' },
|
|
28
|
+
{ id: 20, name: 'الهرم', nameEn: 'Haram', governorateCode: 'GIZ' },
|
|
29
|
+
{ id: 21, name: 'فيصل', nameEn: 'Faisal', governorateCode: 'GIZ' },
|
|
30
|
+
{ id: 22, name: '6 أكتوبر', nameEn: '6th of October', governorateCode: 'GIZ' },
|
|
31
|
+
{ id: 23, name: 'الشيخ زايد', nameEn: 'Sheikh Zayed', governorateCode: 'GIZ' },
|
|
32
|
+
{ id: 24, name: 'إمبابة', nameEn: 'Imbaba', governorateCode: 'GIZ' },
|
|
33
|
+
|
|
34
|
+
// Port Said (PTS)
|
|
35
|
+
{ id: 25, name: 'حي الشرق', nameEn: 'East District', governorateCode: 'PTS' },
|
|
36
|
+
{ id: 26, name: 'حي العرب', nameEn: 'Arab District', governorateCode: 'PTS' },
|
|
37
|
+
{ id: 27, name: 'حي الضواحي', nameEn: 'Suburbs District', governorateCode: 'PTS' },
|
|
38
|
+
{ id: 28, name: 'بورفؤاد', nameEn: 'Port Fouad', governorateCode: 'PTS' },
|
|
39
|
+
|
|
40
|
+
// Suez (SUZ)
|
|
41
|
+
{ id: 29, name: 'حي السويس', nameEn: 'Suez District', governorateCode: 'SUZ' },
|
|
42
|
+
{ id: 30, name: 'حي الأربعين', nameEn: 'Arbaeen District', governorateCode: 'SUZ' },
|
|
43
|
+
{ id: 31, name: 'عتاقة', nameEn: 'Ataka', governorateCode: 'SUZ' },
|
|
44
|
+
{ id: 32, name: 'حي فيصل', nameEn: 'Faisal District', governorateCode: 'SUZ' },
|
|
45
|
+
|
|
46
|
+
// Dakahlia (DKH)
|
|
47
|
+
{ id: 33, name: 'المنصورة', nameEn: 'Mansoura', governorateCode: 'DKH' },
|
|
48
|
+
{ id: 34, name: 'طلخا', nameEn: 'Talkha', governorateCode: 'DKH' },
|
|
49
|
+
{ id: 35, name: 'ميت غمر', nameEn: 'Mit Ghamr', governorateCode: 'DKH' },
|
|
50
|
+
{ id: 36, name: 'دكرنس', nameEn: 'Dikirnis', governorateCode: 'DKH' },
|
|
51
|
+
{ id: 37, name: 'أجا', nameEn: 'Aga', governorateCode: 'DKH' },
|
|
52
|
+
{ id: 38, name: 'السنبلاوين', nameEn: 'Sinbellawin', governorateCode: 'DKH' },
|
|
53
|
+
|
|
54
|
+
// Sharqia (SHR)
|
|
55
|
+
{ id: 39, name: 'الزقازيق', nameEn: 'Zagazig', governorateCode: 'SHR' },
|
|
56
|
+
{ id: 40, name: 'العاشر من رمضان', nameEn: '10th of Ramadan', governorateCode: 'SHR' },
|
|
57
|
+
{ id: 41, name: 'بلبيس', nameEn: 'Bilbeis', governorateCode: 'SHR' },
|
|
58
|
+
{ id: 42, name: 'أبو حماد', nameEn: 'Abu Hammad', governorateCode: 'SHR' },
|
|
59
|
+
{ id: 43, name: 'منيا القمح', nameEn: 'Minya Al Qamh', governorateCode: 'SHR' },
|
|
60
|
+
{ id: 44, name: 'فاقوس', nameEn: 'Faqous', governorateCode: 'SHR' },
|
|
61
|
+
|
|
62
|
+
// Qalyubia (QLB)
|
|
63
|
+
{ id: 45, name: 'بنها', nameEn: 'Benha', governorateCode: 'QLB' },
|
|
64
|
+
{ id: 46, name: 'شبرا الخيمة', nameEn: 'Shubra El Kheima', governorateCode: 'QLB' },
|
|
65
|
+
{ id: 47, name: 'قليوب', nameEn: 'Qalyub', governorateCode: 'QLB' },
|
|
66
|
+
{ id: 48, name: 'القناطر الخيرية', nameEn: 'El Qanater El Khayreya', governorateCode: 'QLB' },
|
|
67
|
+
{ id: 49, name: 'طوخ', nameEn: 'Toukh', governorateCode: 'QLB' },
|
|
68
|
+
|
|
69
|
+
// Kafr El Sheikh (KFS)
|
|
70
|
+
{ id: 50, name: 'كفر الشيخ', nameEn: 'Kafr El Sheikh City', governorateCode: 'KFS' },
|
|
71
|
+
{ id: 51, name: 'دسوق', nameEn: 'Desouk', governorateCode: 'KFS' },
|
|
72
|
+
{ id: 52, name: 'فوه', nameEn: 'Fuwwah', governorateCode: 'KFS' },
|
|
73
|
+
{ id: 53, name: 'بيلا', nameEn: 'Bella', governorateCode: 'KFS' },
|
|
74
|
+
|
|
75
|
+
// Gharbia (GHR)
|
|
76
|
+
{ id: 54, name: 'طنطا', nameEn: 'Tanta', governorateCode: 'GHR' },
|
|
77
|
+
{ id: 55, name: 'المحلة الكبرى', nameEn: 'El Mahalla El Kubra', governorateCode: 'GHR' },
|
|
78
|
+
{ id: 56, name: 'كفر الزيات', nameEn: 'Kafr El Zayat', governorateCode: 'GHR' },
|
|
79
|
+
{ id: 57, name: 'زفتى', nameEn: 'Zefta', governorateCode: 'GHR' },
|
|
80
|
+
{ id: 58, name: 'السنطة', nameEn: 'Santa', governorateCode: 'GHR' },
|
|
81
|
+
|
|
82
|
+
// Monufia (MNF)
|
|
83
|
+
{ id: 59, name: 'شبين الكوم', nameEn: 'Shebin El Kom', governorateCode: 'MNF' },
|
|
84
|
+
{ id: 60, name: 'منوف', nameEn: 'Menouf', governorateCode: 'MNF' },
|
|
85
|
+
{ id: 61, name: 'أشمون', nameEn: 'Ashmoun', governorateCode: 'MNF' },
|
|
86
|
+
{ id: 62, name: 'السادات', nameEn: 'Sadat City', governorateCode: 'MNF' },
|
|
87
|
+
{ id: 63, name: 'تلا', nameEn: 'Tala', governorateCode: 'MNF' },
|
|
88
|
+
|
|
89
|
+
// Beheira (BHR)
|
|
90
|
+
{ id: 64, name: 'دمنهور', nameEn: 'Damanhour', governorateCode: 'BHR' },
|
|
91
|
+
{ id: 65, name: 'كفر الدوار', nameEn: 'Kafr El Dawar', governorateCode: 'BHR' },
|
|
92
|
+
{ id: 66, name: 'رشيد', nameEn: 'Rashid', governorateCode: 'BHR' },
|
|
93
|
+
{ id: 67, name: 'إدكو', nameEn: 'Edku', governorateCode: 'BHR' },
|
|
94
|
+
{ id: 68, name: 'أبو المطامير', nameEn: 'Abu El Matamir', governorateCode: 'BHR' },
|
|
95
|
+
|
|
96
|
+
// Ismailia (ISM)
|
|
97
|
+
{ id: 69, name: 'الإسماعيلية', nameEn: 'Ismailia City', governorateCode: 'ISM' },
|
|
98
|
+
{ id: 70, name: 'فايد', nameEn: 'Fayed', governorateCode: 'ISM' },
|
|
99
|
+
{ id: 71, name: 'القنطرة شرق', nameEn: 'Qantara East', governorateCode: 'ISM' },
|
|
100
|
+
{ id: 72, name: 'التل الكبير', nameEn: 'Tell El Kebir', governorateCode: 'ISM' },
|
|
101
|
+
|
|
102
|
+
// Damietta (DMT)
|
|
103
|
+
{ id: 73, name: 'دمياط', nameEn: 'Damietta City', governorateCode: 'DMT' },
|
|
104
|
+
{ id: 74, name: 'دمياط الجديدة', nameEn: 'New Damietta', governorateCode: 'DMT' },
|
|
105
|
+
{ id: 75, name: 'رأس البر', nameEn: 'Ras El Bar', governorateCode: 'DMT' },
|
|
106
|
+
{ id: 76, name: 'فارسكور', nameEn: 'Faraskour', governorateCode: 'DMT' },
|
|
107
|
+
|
|
108
|
+
// Faiyum (FYM)
|
|
109
|
+
{ id: 77, name: 'الفيوم', nameEn: 'Faiyum City', governorateCode: 'FYM' },
|
|
110
|
+
{ id: 78, name: 'إطسا', nameEn: 'Etsa', governorateCode: 'FYM' },
|
|
111
|
+
{ id: 79, name: 'طامية', nameEn: 'Tamiya', governorateCode: 'FYM' },
|
|
112
|
+
{ id: 80, name: 'سنورس', nameEn: 'Snouris', governorateCode: 'FYM' },
|
|
113
|
+
|
|
114
|
+
// Beni Suef (BNS)
|
|
115
|
+
{ id: 81, name: 'بني سويف', nameEn: 'Beni Suef City', governorateCode: 'BNS' },
|
|
116
|
+
{ id: 82, name: 'الواسطى', nameEn: 'El Wasta', governorateCode: 'BNS' },
|
|
117
|
+
{ id: 83, name: 'ناصر', nameEn: 'Nasser', governorateCode: 'BNS' },
|
|
118
|
+
{ id: 84, name: 'إهناسيا', nameEn: 'Ehnasia', governorateCode: 'BNS' },
|
|
119
|
+
|
|
120
|
+
// Minya (MNY)
|
|
121
|
+
{ id: 85, name: 'المنيا', nameEn: 'Minya City', governorateCode: 'MNY' },
|
|
122
|
+
{ id: 86, name: 'ملوي', nameEn: 'Mallawi', governorateCode: 'MNY' },
|
|
123
|
+
{ id: 87, name: 'سمالوط', nameEn: 'Samalut', governorateCode: 'MNY' },
|
|
124
|
+
{ id: 88, name: 'المنيا الجديدة', nameEn: 'New Minya', governorateCode: 'MNY' },
|
|
125
|
+
{ id: 89, name: 'أبو قرقاص', nameEn: 'Abu Qurqas', governorateCode: 'MNY' },
|
|
126
|
+
|
|
127
|
+
// Asyut (AST)
|
|
128
|
+
{ id: 90, name: 'أسيوط', nameEn: 'Asyut City', governorateCode: 'AST' },
|
|
129
|
+
{ id: 91, name: 'ديروط', nameEn: 'Dairut', governorateCode: 'AST' },
|
|
130
|
+
{ id: 92, name: 'القوصية', nameEn: 'El Qusiya', governorateCode: 'AST' },
|
|
131
|
+
{ id: 93, name: 'منفلوط', nameEn: 'Manfalut', governorateCode: 'AST' },
|
|
132
|
+
{ id: 94, name: 'أبنوب', nameEn: 'Abnoub', governorateCode: 'AST' },
|
|
133
|
+
|
|
134
|
+
// Sohag (SHG)
|
|
135
|
+
{ id: 95, name: 'سوهاج', nameEn: 'Sohag City', governorateCode: 'SHG' },
|
|
136
|
+
{ id: 96, name: 'أخميم', nameEn: 'Akhmim', governorateCode: 'SHG' },
|
|
137
|
+
{ id: 97, name: 'جرجا', nameEn: 'Girga', governorateCode: 'SHG' },
|
|
138
|
+
{ id: 98, name: 'طهطا', nameEn: 'Tahta', governorateCode: 'SHG' },
|
|
139
|
+
{ id: 99, name: 'المراغة', nameEn: 'El Maragha', governorateCode: 'SHG' },
|
|
140
|
+
|
|
141
|
+
// Qena (QNA)
|
|
142
|
+
{ id: 100, name: 'قنا', nameEn: 'Qena City', governorateCode: 'QNA' },
|
|
143
|
+
{ id: 101, name: 'نجع حمادي', nameEn: 'Nag Hammadi', governorateCode: 'QNA' },
|
|
144
|
+
{ id: 102, name: 'دشنا', nameEn: 'Dishna', governorateCode: 'QNA' },
|
|
145
|
+
{ id: 103, name: 'قوص', nameEn: 'Qus', governorateCode: 'QNA' },
|
|
146
|
+
|
|
147
|
+
// Luxor (LXR)
|
|
148
|
+
{ id: 104, name: 'الأقصر', nameEn: 'Luxor City', governorateCode: 'LXR' },
|
|
149
|
+
{ id: 105, name: 'إسنا', nameEn: 'Esna', governorateCode: 'LXR' },
|
|
150
|
+
{ id: 106, name: 'أرمنت', nameEn: 'Armant', governorateCode: 'LXR' },
|
|
151
|
+
{ id: 107, name: 'الطود', nameEn: 'El Tod', governorateCode: 'LXR' },
|
|
152
|
+
|
|
153
|
+
// Aswan (ASN)
|
|
154
|
+
{ id: 108, name: 'أسوان', nameEn: 'Aswan City', governorateCode: 'ASN' },
|
|
155
|
+
{ id: 109, name: 'كوم أمبو', nameEn: 'Kom Ombo', governorateCode: 'ASN' },
|
|
156
|
+
{ id: 110, name: 'إدفو', nameEn: 'Edfu', governorateCode: 'ASN' },
|
|
157
|
+
{ id: 111, name: 'دراو', nameEn: 'Daraw', governorateCode: 'ASN' },
|
|
158
|
+
{ id: 112, name: 'أبو سمبل', nameEn: 'Abu Simbel', governorateCode: 'ASN' },
|
|
159
|
+
|
|
160
|
+
// Red Sea (RED)
|
|
161
|
+
{ id: 113, name: 'الغردقة', nameEn: 'Hurghada', governorateCode: 'RED' },
|
|
162
|
+
{ id: 114, name: 'سفاجا', nameEn: 'Safaga', governorateCode: 'RED' },
|
|
163
|
+
{ id: 115, name: 'القصير', nameEn: 'El Quseir', governorateCode: 'RED' },
|
|
164
|
+
{ id: 116, name: 'مرسى علم', nameEn: 'Marsa Alam', governorateCode: 'RED' },
|
|
165
|
+
{ id: 117, name: 'رأس غارب', nameEn: 'Ras Ghareb', governorateCode: 'RED' },
|
|
166
|
+
|
|
167
|
+
// New Valley (WAD)
|
|
168
|
+
{ id: 118, name: 'الخارجة', nameEn: 'El Kharga', governorateCode: 'WAD' },
|
|
169
|
+
{ id: 119, name: 'الداخلة', nameEn: 'Dakhla', governorateCode: 'WAD' },
|
|
170
|
+
{ id: 120, name: 'الفرافرة', nameEn: 'Farafra', governorateCode: 'WAD' },
|
|
171
|
+
{ id: 121, name: 'باريس', nameEn: 'Paris', governorateCode: 'WAD' },
|
|
172
|
+
|
|
173
|
+
// Matruh (MTR)
|
|
174
|
+
{ id: 122, name: 'مرسى مطروح', nameEn: 'Marsa Matruh', governorateCode: 'MTR' },
|
|
175
|
+
{ id: 123, name: 'سيوة', nameEn: 'Siwa', governorateCode: 'MTR' },
|
|
176
|
+
{ id: 124, name: 'الحمام', nameEn: 'El Hamam', governorateCode: 'MTR' },
|
|
177
|
+
{ id: 125, name: 'العلمين', nameEn: 'El Alamein', governorateCode: 'MTR' },
|
|
178
|
+
{ id: 126, name: 'الضبعة', nameEn: 'El Dabaa', governorateCode: 'MTR' },
|
|
179
|
+
|
|
180
|
+
// North Sinai (SIN)
|
|
181
|
+
{ id: 127, name: 'العريش', nameEn: 'Arish', governorateCode: 'SIN' },
|
|
182
|
+
{ id: 128, name: 'الشيخ زويد', nameEn: 'Sheikh Zuweid', governorateCode: 'SIN' },
|
|
183
|
+
{ id: 129, name: 'رفح', nameEn: 'Rafah', governorateCode: 'SIN' },
|
|
184
|
+
{ id: 130, name: 'بئر العبد', nameEn: 'Bir al-Abed', governorateCode: 'SIN' },
|
|
185
|
+
|
|
186
|
+
// South Sinai (SIS)
|
|
187
|
+
{ id: 131, name: 'شرم الشيخ', nameEn: 'Sharm El Sheikh', governorateCode: 'SIS' },
|
|
188
|
+
{ id: 132, name: 'دهب', nameEn: 'Dahab', governorateCode: 'SIS' },
|
|
189
|
+
{ id: 133, name: 'نويبع', nameEn: 'Nuweiba', governorateCode: 'SIS' },
|
|
190
|
+
{ id: 134, name: 'طابا', nameEn: 'Taba', governorateCode: 'SIS' },
|
|
191
|
+
{ id: 135, name: 'سانت كاترين', nameEn: 'Saint Catherine', governorateCode: 'SIS' },
|
|
192
|
+
{ id: 136, name: 'الطور', nameEn: 'El Tor', governorateCode: 'SIS' },
|
|
193
|
+
|
|
194
|
+
// New Cities (4th Generation & Others)
|
|
195
|
+
{ id: 137, name: 'العاصمة الإدارية الجديدة', nameEn: 'New Administrative Capital', governorateCode: 'CAI' },
|
|
196
|
+
{ id: 138, name: 'الشروق', nameEn: 'El Shorouk', governorateCode: 'CAI' },
|
|
197
|
+
{ id: 139, name: 'بدر', nameEn: 'Badr City', governorateCode: 'CAI' },
|
|
198
|
+
{ id: 140, name: 'مدينتي', nameEn: 'Madinaty', governorateCode: 'CAI' },
|
|
199
|
+
{ id: 141, name: 'مدينة الرحاب', nameEn: 'Al Rehab', governorateCode: 'CAI' },
|
|
200
|
+
{ id: 142, name: '15 مايو', nameEn: '15 May City', governorateCode: 'CAI' },
|
|
201
|
+
{ id: 143, name: 'سفنكس الجديدة', nameEn: 'New Sphinx', governorateCode: 'GIZ' },
|
|
202
|
+
{ id: 144, name: 'حدائق أكتوبر', nameEn: 'Hadayek October', governorateCode: 'GIZ' },
|
|
203
|
+
{ id: 145, name: 'برج العرب الجديدة', nameEn: 'New Borg El Arab', governorateCode: 'ALX' },
|
|
204
|
+
{ id: 146, name: 'العبور', nameEn: 'El Obour', governorateCode: 'QLB' },
|
|
205
|
+
{ id: 147, name: 'العبور الجديدة', nameEn: 'New Obour', governorateCode: 'QLB' },
|
|
206
|
+
{ id: 148, name: 'المنصورة الجديدة', nameEn: 'New Mansoura', governorateCode: 'DKH' },
|
|
207
|
+
{ id: 149, name: 'العلمين الجديدة', nameEn: 'New Alamein', governorateCode: 'MTR' },
|
|
208
|
+
{ id: 150, name: 'مدينة الجلالة', nameEn: 'Galala City', governorateCode: 'SUZ' },
|
|
209
|
+
{ id: 151, name: 'مدينة ناصر (غرب أسيوط)', nameEn: 'Nasser City (West Asyut)', governorateCode: 'AST' },
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
const idMap = new Map(cities.map((c) => [c.id, c]));
|
|
213
|
+
|
|
214
|
+
const govMap = new Map();
|
|
215
|
+
for (const city of cities) {
|
|
216
|
+
const code = city.governorateCode;
|
|
217
|
+
if (!govMap.has(code)) govMap.set(code, []);
|
|
218
|
+
govMap.get(code).push(city);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function getByGovernorate(govCode) {
|
|
222
|
+
if (typeof govCode !== 'string') return [];
|
|
223
|
+
const list = govMap.get(govCode.toUpperCase());
|
|
224
|
+
return list ? [...list] : [];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function getById(id) {
|
|
228
|
+
const numId = Number(id);
|
|
229
|
+
if (!Number.isInteger(numId)) return undefined;
|
|
230
|
+
return idMap.get(numId) || undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function search(query) {
|
|
234
|
+
if (typeof query !== 'string' || !query.trim()) return [];
|
|
235
|
+
const q = query.trim().toLowerCase();
|
|
236
|
+
return cities.filter(
|
|
237
|
+
(c) => c.name.includes(q) || c.nameEn.toLowerCase().includes(q)
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = { getByGovernorate, getById, search };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const governorates = [
|
|
4
|
+
{ id: 1, code: 'CAI', name: 'القاهرة', nameEn: 'Cairo' },
|
|
5
|
+
{ id: 2, code: 'ALX', name: 'الإسكندرية', nameEn: 'Alexandria' },
|
|
6
|
+
{ id: 3, code: 'GIZ', name: 'الجيزة', nameEn: 'Giza' },
|
|
7
|
+
{ id: 4, code: 'PTS', name: 'بورسعيد', nameEn: 'Port Said' },
|
|
8
|
+
{ id: 5, code: 'SUZ', name: 'السويس', nameEn: 'Suez' },
|
|
9
|
+
{ id: 6, code: 'DKH', name: 'الدقهلية', nameEn: 'Dakahlia' },
|
|
10
|
+
{ id: 7, code: 'SHR', name: 'الشرقية', nameEn: 'Sharqia' },
|
|
11
|
+
{ id: 8, code: 'QLB', name: 'القليوبية', nameEn: 'Qalyubia' },
|
|
12
|
+
{ id: 9, code: 'KFS', name: 'كفر الشيخ', nameEn: 'Kafr El Sheikh' },
|
|
13
|
+
{ id: 10, code: 'GHR', name: 'الغربية', nameEn: 'Gharbia' },
|
|
14
|
+
{ id: 11, code: 'MNF', name: 'المنوفية', nameEn: 'Monufia' },
|
|
15
|
+
{ id: 12, code: 'BHR', name: 'البحيرة', nameEn: 'Beheira' },
|
|
16
|
+
{ id: 13, code: 'ISM', name: 'الإسماعيلية', nameEn: 'Ismailia' },
|
|
17
|
+
{ id: 14, code: 'DMT', name: 'دمياط', nameEn: 'Damietta' },
|
|
18
|
+
{ id: 15, code: 'FYM', name: 'الفيوم', nameEn: 'Faiyum' },
|
|
19
|
+
{ id: 16, code: 'BNS', name: 'بني سويف', nameEn: 'Beni Suef' },
|
|
20
|
+
{ id: 17, code: 'MNY', name: 'المنيا', nameEn: 'Minya' },
|
|
21
|
+
{ id: 18, code: 'AST', name: 'أسيوط', nameEn: 'Asyut' },
|
|
22
|
+
{ id: 19, code: 'SHG', name: 'سوهاج', nameEn: 'Sohag' },
|
|
23
|
+
{ id: 20, code: 'QNA', name: 'قنا', nameEn: 'Qena' },
|
|
24
|
+
{ id: 21, code: 'LXR', name: 'الأقصر', nameEn: 'Luxor' },
|
|
25
|
+
{ id: 22, code: 'ASN', name: 'أسوان', nameEn: 'Aswan' },
|
|
26
|
+
{ id: 23, code: 'RED', name: 'البحر الأحمر', nameEn: 'Red Sea' },
|
|
27
|
+
{ id: 24, code: 'WAD', name: 'الوادي الجديد', nameEn: 'New Valley' },
|
|
28
|
+
{ id: 25, code: 'MTR', name: 'مطروح', nameEn: 'Matruh' },
|
|
29
|
+
{ id: 26, code: 'SIN', name: 'شمال سيناء', nameEn: 'North Sinai' },
|
|
30
|
+
{ id: 27, code: 'SIS', name: 'جنوب سيناء', nameEn: 'South Sinai' },
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const codeMap = new Map(governorates.map((g) => [g.code, g]));
|
|
34
|
+
const idMap = new Map(governorates.map((g) => [g.id, g]));
|
|
35
|
+
|
|
36
|
+
function getAll() {
|
|
37
|
+
return [...governorates];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getByCode(code) {
|
|
41
|
+
if (typeof code !== 'string') return undefined;
|
|
42
|
+
return codeMap.get(code.toUpperCase()) || undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getById(id) {
|
|
46
|
+
const numId = Number(id);
|
|
47
|
+
if (!Number.isInteger(numId)) return undefined;
|
|
48
|
+
return idMap.get(numId) || undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function search(query) {
|
|
52
|
+
if (typeof query !== 'string' || !query.trim()) return [];
|
|
53
|
+
const q = query.trim().toLowerCase();
|
|
54
|
+
return governorates.filter(
|
|
55
|
+
(g) =>
|
|
56
|
+
g.name.includes(q) ||
|
|
57
|
+
g.nameEn.toLowerCase().includes(q) ||
|
|
58
|
+
g.code.toLowerCase().includes(q)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { getAll, getByCode, getById, search };
|
package/src/index.js
ADDED
package/src/phoneArea.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const areaCodes = [
|
|
4
|
+
// Mobile Networks
|
|
5
|
+
{ code: '010', region: 'ڤودافون', regionEn: 'Vodafone' },
|
|
6
|
+
{ code: '011', region: 'اتصالات', regionEn: 'Etisalat' },
|
|
7
|
+
{ code: '012', region: 'أورنج', regionEn: 'Orange' },
|
|
8
|
+
{ code: '015', region: 'وي / العاشر من رمضان', regionEn: 'WE / 10th of Ramadan' },
|
|
9
|
+
|
|
10
|
+
// Landlines
|
|
11
|
+
{ code: '02', region: 'القاهرة والجيزة', regionEn: 'Cairo & Giza' },
|
|
12
|
+
{ code: '03', region: 'الإسكندرية', regionEn: 'Alexandria' },
|
|
13
|
+
{ code: '013', region: 'القليوبية (بنها)', regionEn: 'Qalyubia (Benha)' },
|
|
14
|
+
{ code: '040', region: 'الغربية (طنطا)', regionEn: 'Gharbia (Tanta)' },
|
|
15
|
+
{ code: '045', region: 'البحيرة (دمنهور)', regionEn: 'Beheira (Damanhour)' },
|
|
16
|
+
{ code: '046', region: 'مطروح', regionEn: 'Matruh' },
|
|
17
|
+
{ code: '047', region: 'كفر الشيخ', regionEn: 'Kafr El Sheikh' },
|
|
18
|
+
{ code: '048', region: 'المنوفية (شبين الكوم)', regionEn: 'Monufia (Shebin El Kom)' },
|
|
19
|
+
{ code: '050', region: 'الدقهلية (المنصورة)', regionEn: 'Dakahlia (Mansoura)' },
|
|
20
|
+
{ code: '055', region: 'الشرقية (الزقازيق)', regionEn: 'Sharqia (Zagazig)' },
|
|
21
|
+
{ code: '057', region: 'دمياط', regionEn: 'Damietta' },
|
|
22
|
+
{ code: '062', region: 'السويس', regionEn: 'Suez' },
|
|
23
|
+
{ code: '064', region: 'الإسماعيلية', regionEn: 'Ismailia' },
|
|
24
|
+
{ code: '065', region: 'البحر الأحمر (الغردقة)', regionEn: 'Red Sea (Hurghada)' },
|
|
25
|
+
{ code: '066', region: 'بورسعيد', regionEn: 'Port Said' },
|
|
26
|
+
{ code: '068', region: 'شمال سيناء (العريش)', regionEn: 'North Sinai (Arish)' },
|
|
27
|
+
{ code: '069', region: 'جنوب سيناء', regionEn: 'South Sinai' },
|
|
28
|
+
{ code: '082', region: 'بني سويف', regionEn: 'Beni Suef' },
|
|
29
|
+
{ code: '084', region: 'الفيوم', regionEn: 'Faiyum' },
|
|
30
|
+
{ code: '086', region: 'المنيا', regionEn: 'Minya' },
|
|
31
|
+
{ code: '088', region: 'أسيوط', regionEn: 'Asyut' },
|
|
32
|
+
{ code: '092', region: 'الوادي الجديد', regionEn: 'New Valley' },
|
|
33
|
+
{ code: '093', region: 'سوهاج', regionEn: 'Sohag' },
|
|
34
|
+
{ code: '095', region: 'الأقصر', regionEn: 'Luxor' },
|
|
35
|
+
{ code: '096', region: 'قنا', regionEn: 'Qena' },
|
|
36
|
+
{ code: '097', region: 'أسوان', regionEn: 'Aswan' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const codeMap = new Map(areaCodes.map((a) => [a.code, a]));
|
|
40
|
+
|
|
41
|
+
function getAll() {
|
|
42
|
+
return [...areaCodes];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getRegion(code) {
|
|
46
|
+
if (typeof code !== 'string') return undefined;
|
|
47
|
+
const normalized = code.replace(/^0*/, '0');
|
|
48
|
+
return codeMap.get(code) || codeMap.get(normalized) || undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getCode(regionName) {
|
|
52
|
+
if (typeof regionName !== 'string' || !regionName.trim()) return undefined;
|
|
53
|
+
const q = regionName.trim().toLowerCase();
|
|
54
|
+
return (
|
|
55
|
+
areaCodes.find(
|
|
56
|
+
(a) => a.region.includes(q) || a.regionEn.toLowerCase().includes(q)
|
|
57
|
+
) || undefined
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { getAll, getRegion, getCode };
|
package/src/timezone.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const name = 'Africa/Cairo';
|
|
4
|
+
const offset = '+02:00';
|
|
5
|
+
|
|
6
|
+
function now() {
|
|
7
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
8
|
+
timeZone: 'Africa/Cairo',
|
|
9
|
+
year: 'numeric',
|
|
10
|
+
month: '2-digit',
|
|
11
|
+
day: '2-digit',
|
|
12
|
+
hour: '2-digit',
|
|
13
|
+
minute: '2-digit',
|
|
14
|
+
second: '2-digit',
|
|
15
|
+
hour12: false,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const parts = formatter.formatToParts(new Date());
|
|
19
|
+
const get = (type) => parts.find((p) => p.type === type).value;
|
|
20
|
+
|
|
21
|
+
const year = Number(get('year'));
|
|
22
|
+
const month = Number(get('month')) - 1;
|
|
23
|
+
const day = Number(get('day'));
|
|
24
|
+
const hour = Number(get('hour'));
|
|
25
|
+
const minute = Number(get('minute'));
|
|
26
|
+
const second = Number(get('second'));
|
|
27
|
+
|
|
28
|
+
return new Date(Date.UTC(year, month, day, hour, minute, second));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function isDST(date = new Date()) {
|
|
32
|
+
// Egypt resumed daylight saving time in 2023.
|
|
33
|
+
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
34
|
+
timeZone: 'Africa/Cairo',
|
|
35
|
+
year: 'numeric',
|
|
36
|
+
month: '2-digit',
|
|
37
|
+
day: '2-digit',
|
|
38
|
+
hour: '2-digit',
|
|
39
|
+
minute: '2-digit',
|
|
40
|
+
second: '2-digit',
|
|
41
|
+
hour12: false,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const parts = formatter.formatToParts(date);
|
|
45
|
+
const get = (type) => Number(parts.find((p) => p.type === type).value);
|
|
46
|
+
|
|
47
|
+
const tzDate = new Date(Date.UTC(get('year'), get('month') - 1, get('day'), get('hour'), get('minute'), get('second')));
|
|
48
|
+
const offsetMinutes = Math.round((tzDate.getTime() - date.getTime()) / 60000);
|
|
49
|
+
|
|
50
|
+
// Standard time offset is +120 minutes (+02:00)
|
|
51
|
+
// DST offset is +180 minutes (+03:00)
|
|
52
|
+
return offsetMinutes === 180;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { name, offset, now, isDST };
|