Start page: ARABART home
← DinarSoft

HijriDate Plugin

What is Today

Today’s date in the Hijri calendar, in Arabic or English, right on the Pocket PC’s home screen.

Latest
1.5, March 2005
First
1.0, June 2003
Price then
$2.99
Today
Free
Runs on
Pocket PC 2002, Windows Mobile 2003 and 5
HijriDate
The Today screen with HijriDate: Sunday 2 Ramadan 1427 and Sunday 24 September 2006, both written in Arabic.
The Today screen with HijriDate: Sunday 2 Ramadan 1427 and Sunday 24 September 2006, both written in Arabic.

The story

The Hijri calendar follows the moon. It sets the dates of Ramadan and the two Eids for Muslims everywhere. HijriDate put it on the Pocket PC’s Today screen, its home screen, in Arabic or English, beside the usual date or instead of it. It was the first light-weight Today plug-in for the Hijri calendar.

It drew its Arabic by itself, with no extra fonts or programs, and calculated the date for Mecca. You could move it a day earlier or later to match the crescent sighting where you live. A tap switched between the two calendars.

Every version

From DinarSoft’s revision history and installers. Press Run to play through them, or step one at a time.

HijriDate.history
  1. HijriDate 1.0 June 27, 2003

    • The first release.
  2. HijriDate 1.1 March 10, 2004

    • A stronger date engine.
  3. HijriDate 1.2 April 20, 2004

    • Windows Mobile 2003 support.
  4. HijriDate 1.5 March 5, 2005

    • Windows Mobile 5 support.

Arabic on the home screen

In 1991 Yasser’s ARABART taught a DOS PC to write Arabic. In 2003 he did it again on a phone, with Hosam Aly. HijriDate put today’s Hijri date, in Arabic, on the Pocket PC’s home screen, right under the owner’s name and the unread mail.

The Hijri calendar follows the moon, and it sets the dates of Ramadan, the two Eids and the Hajj. A Pocket PC knew only the Gregorian calendar, and an English one had no Arabic font at all. HijriDate brought both. It is a Today plug-in, the 2003 version of a home screen widget, and it cost $2.99.

This is HijriDate rebuilt from its own file: its word pictures, its four settings pages, its icons and its calendar engine. Tap the clock icon to open the settings. Change the format, move the date a day, switch to English, or try another theme.

Start8:03
Tap here to set owner information
No unread messages
No tasks
No upcoming appointments
CalendarContacts
The plug-in, rebuilt from its own files. Tap the clock to open its settings.
The date on the device
Today screen theme

Sunday 2 Ramadan 1427, with the adjustment at +1.

DinarSoft’s 2006 screenshot of a Windows Mobile 5 Today screen: two Arabic lines under the clock icon, الأحد ٢، رمضان ١٤٢٧ and الأحد ٢٤، سبتمبر ٢٠٠٦.
DinarSoft’s own screenshot, September 2006. Pick 24 September 2006 above and the rebuilt plug-in draws the same two lines, pixel for pixel.

The moon decides

A Hijri month starts when the new crescent is first seen after sunset. HijriDate works that out from the moon itself, for any date, in about a dozen lines of arithmetic.

Pick a date. The steps below the answer are HijriDate’s, in its order. Count the days and estimate which new moon came last. Work out the exact moment it was born, and decide when it could first be seen. Then count months from a fixed starting point. Every number is the one its code computes. The engine on this page is a line-for-line copy of HijriDate’s, and it matches the original, running in an ARM emulator, on all 37,700 dates from 1700 to 2300.

1 Ramadan 1427

  1. Count the days. 24 September 2006 at midnight, London time, is Julian day 2,454,002.5: days since 4713 BC, the number astronomers use so dates subtract cleanly.
  2. Estimate the new moon. 106.7 years since 1900, times 12.3685 new moons a year, gives new moon number 1320.
  3. Find its birth. New moon 1320 is born on 22 September 2006 at 14:43 in Mecca. That is after 6:00 in the morning, so day 1 of the month is 24 September 2006.
  4. Name the month. New moon 1048 opened Muharram 1405. 1320 is 272 months later: 22 years and 8 months. Year 1427, month 9: Ramadan.
  5. Count the day. 24 September is the first full day of that month: 1 Ramadan 1427.
The same day in the Islamic calendars your browser knows
CalendarDate
HijriDate 1.5, its engine1 Ramadan 1427

Your browser ships four Islamic calendars, and they do not always agree with each other. One follows Saudi Arabia’s official tables, one estimates from the sky, and two use plain arithmetic. Muslims in different countries can start Ramadan a day apart for the same reason: the crescent is seen in one place before another. That is why HijriDate has an adjustment of up to two days either way. The date on the phone then matches the sighting announced where you live.

The new-moon formula, in HijriDate’s order

The moment of a new moon is a steady beat of 29.53 days, plus 13 small corrections for the pull of the sun and the tilt and stretch of the moon’s orbit, minus a few seconds for the Earth’s slowing spin. Its code runs them in this order, with these numbers:

tmoonphase (0x1020A8), as C
jd = 2415020.75933 + 29.53058868 * k // the steady beat
sa = 359.2242 + 29.10535608 * k // where the sun is
ma = 306.0253 + 385.81691806 * k // where the moon is
tf = 2 * (21.2964 + 390.67050646 * k) // its height above the Earth’s path
x = (0.1734 - 0.000393 * t) * sin(sa) // the biggest correction
x -= 0.4068 * sin(ma) // and 11 more like it
x -= (0.41 + 1.2053 * t + 0.4992 * t * t) / 1440 // the Earth’s spin
return jd + x
k counts new moons from January 1900; t is k in centuries. Every add and multiply is a call into the system’s software math, because the phone’s chip had no hardware for fractions.

Six in the morning, Mecca time

One rule turns the moment of the new moon into the first day of the month, and it fits in one short routine.

A crescent needs time to grow wide enough to see. A new moon born before 6:00 in the morning in Mecca is old enough to be seen at sunset that same day. The month then starts the next morning. Born any later, it is seen one evening later. Step through its routine with the new moon of September 2006, then drag the birth time yourself.

Three days in Mecca. The new moon is born at 14:43 on 22 Sep 2006. Born after 6:00, so the crescent is first seen on the evening of 23 Sep 2006 and the month starts on 24 Sep 2006. 6:00 18:00 22 Sep 2006 6:00 18:00 23 Sep 2006 6:00 18:00 24 Sep 2006 born 14:43 seen Day 1
HIJRIPLUGIN.DLL visible()
  1. 1036A8bl tmoonphase; new moon n: when?
  2. 1036BCstr r4,[r6]; keep it for later
  3. 1036F8mov pc,fp; __subd: drop whole days
  4. 103738mov pc,fp; __led: ≤ 0.5?
  5. 103740beq 103788; no: find the hour
  6. 103764mov pc,fp; __addd: + 1 day
  7. 1037B4mov pc,fp; __subd: − 0.5
  8. 1037D0mov pc,fp; __muld: × 24
  9. 1037ECmov pc,fp; __addd: + 3 hours
  10. 103828mov pc,fp; __gtd: after 6:00?
  11. 103850movne pc,fp; __addd: + 1 day
  12. 103854pop {r4,r5,r6,fp,pc}; return the start
The same in C
  1. double visible(int n, double *nm) {
  2. double jd = tmoonphase(n, 0);// UT
  3. *nm = jd;
  4. float f = jd - (int)jd;// 0 = noon
  5. if (f <= 0.5)
  6. return jd + 1;
  7. float h = (f - 0.5) * 24 + 3;
  8. if (h > 6)// too young
  9. return jd + 1;
  10. return jd;// seen
  11. }
Watches
Help

And 24 September 2006 is day 1 of Ramadan 1427. Drag the birth time to try any moment.

Every fraction here, the 0.5, the 24 and the 6, goes through the system’s software floating point, one call per add. Today, crescent calculators weigh the moon’s age, its height and its distance from the sun at every city. HijriDate packed the idea into one comparison against the holiest city, so the whole calendar fits beside a clock on a 2003 phone.

Forty-four words, drawn by hand

Arabic letters change shape with their neighbors, and in 2003 a Pocket PC could not join them. HijriDate never needs to. It carries every word it will ever show as a picture. There are 7 days, 12 Hijri months, 12 Gregorian months, 10 digits, a comma, a dash and a space.

Each is 16 pixels tall and one bit a pixel, ink or paper. Tap one to see its pixels.

Days

Hijri months

Gregorian months

Digits and marks

رمضان (Ramadan): 41 × 16 pixels. One of 44 pictures.

To write a date, HijriDate lists the words in reading order, then joins their pictures into one strip. Arabic reads right to left, but its numbers read left to right, so the digits of each number go into the list last first. Step through it:

The list for الأحد ٢، رمضان ١٤٢٧: الأحد (Sunday), space, digit ٢ (2), comma ،, space, رمضان (Ramadan), space, digit ٧ (7), digit ٢ (2), digit ٤ (4), digit ١ (1). Read from its end and pasted left to right, it becomes one strip 125 pixels wide. THE LIST, IN READING ORDER (RIGHT TO LEFT IN ARABIC) 115 29 px 121 3 px 124 8 px 104 6 px 121 3 px 155 41 px 121 3 px 129 9 px 124 8 px 126 8 px 123 7 px LOADED LAST FIRST 123 126 124 129 121 155 121 104 124 121 115 ONE STRIP, 125 × 16, PASTED LEFT TO RIGHT x = 0 x = 35 x = 96
HIJRIPLUGIN.DLL building the date
  1. 104FFCldr r3,[r0,#4]!; count the words
  2. 105014bl operator new; a slot per word
  3. 105038ldrh r1,[r7,#-4]!; next ID, from the end
  4. 105050bl LoadImageW; load its picture
  5. 105070bl sub_104E5C; Paste: join them
  6. 105088bl DeleteObject; free the pieces
  7. 104EC4bl GetObjectW; Paste: measure each
  8. 104ED4add sl,r3,sl; add up the widths
  9. 104F10bl CreateBitmap; one blank strip
  10. 104F4Cbl SelectObject; pick up a word
  11. 104F80bl BitBlt; copy it in at x
  12. 104F90add sb,r3,sb; x += its width
  13. 104FD0pop {r4-fp,pc}; return the strip
The same in C
  1. HBITMAP MakeStrip(DWORD *ids) {
  2. for (n = 0; ids[n]; n++) ;
  3. pic = new HBITMAP[n + 1];
  4. for (k = 0; k < n; k++)// last first
  5. pic[k] = LoadImage(hInst,
  6. ids[n - 1 - k], ...);
  7. pic[n] = 0;
  8. strip = Paste(pic);
  9. for (k = 0; k < n; k++)
  10. DeleteObject(pic[k]);
  11. return strip;
  12. }
  13. HBITMAP Paste(HBITMAP *pic) {
  14. for (n = w = 0; pic[n]; n++) {
  15. GetObject(pic[n], 24, &bm[n]);
  16. w += bm[n].bmWidth;
  17. }
  18. strip = CreateBitmap(w, 16, 1, 1, 0);
  19. for (k = x = 0; k < n; k++) {
  20. SelectObject(from, pic[k]);
  21. BitBlt(to, x, 0, bm[k].bmWidth, 16,
  22. from, 0, 0, SRCCOPY);
  23. x += bm[k].bmWidth;
  24. }
  25. return strip;
  26. }
Watches
Help

One picture holds the whole date, ready to draw in any color.

Eight formats come out of the same 44 pictures, from الأحد ٢، رمضان ١٤٢٧ to ٠٢-٠٩-٢٧. Today your phone shapes Arabic from a font on the fly. A website that ships its icons as one sprite sheet, or a game that draws its score from digit pictures, is doing what HijriDate did.

Any wallpaper, any color

Owners picked their own Today themes: blue waves, photos, black. The word pictures are plain black on white. Yet on the phone they show in the theme’s own text color, with the wallpaper showing through every gap.

It does it with BitBlt, the Windows call that copies pixels, and three of its raster operations: XOR, AND and OR. Two run once to color a copy of the word. Two run every time it is drawn. Pick a color and a wallpaper, then step through the code.

1. The word as stored Black ink on white paper, one bit a pixel.
2. The colored copy Flip it against white, then AND it with the color: color on the ink, black elsewhere.
3. Screen AND word Where the word is white, the wallpaper stays. Where it is black, a black hole.
4. Screen OR copy The color fills the holes. Black adds nothing anywhere else.
HIJRIPLUGIN.DLL mask and paint
  1. 105180cmp r3,sl; same color as before?
  2. 105190beq 105378; yes: copy is ready
  3. 10520Cbl CreateBitmap; a color picture
  4. 10527Cbl CreateSolidBrush; ink-color brush
  5. 105298bl FillRect; all ink color
  6. 1052BCbl FillRect; another, all white
  7. 1052F8bl BitBlt; SRCINVERT: XOR
  8. 10532Cbl BitBlt; SRCAND: AND
  9. 1053A0bl GetTextColor; the theme’s color
  10. 1053ACbl sub_105160; make the copy
  11. 105460bl BitBlt; SRCAND: screen AND
  12. 1054ACbl BitBlt; SRCPAINT: screen OR
The same in C
  1. BOOL Colorize(Word *w, COLORREF ink) {
  2. if (ink == w->ink && !w->dirty)
  3. return TRUE;// ready
  4. w->color = CreateBitmap(cx,cy,1,24,0);
  5. tmp = CreateBitmap(cx, cy, 1, 24, 0);
  6. b = CreateSolidBrush(ink);
  7. FillRect(w->color, &r, b);
  8. b = CreateSolidBrush(0xFFFFFF);// white
  9. FillRect(tmp, &r, b);
  10. BitBlt(tmp, 0, 0, cx, cy,
  11. w->word, 0, 0, SRCINVERT);
  12. BitBlt(w->color, 0, 0, cx, cy,
  13. tmp, 0, 0, SRCAND);
  14. w->ink = ink;
  15. return TRUE;
  16. }
  17. void Draw(Word *w, HDC dc, int x, int y) {
  18. Colorize(w, GetTextColor(dc));
  19. BitBlt(dc, x, y, cx, cy,
  20. w->word, 0, 0, SRCAND);
  21. BitBlt(dc, x, y, cx, cy,
  22. w->color, 0, 0, SRCPAINT);
  23. }
Watches
Help

The next time, with the same color, it skips straight to the two screen steps.

Then and now
2003 to 20052026Why it is the same idea
SRCAND with the word, then SRCPAINT with a colored copy CSS mask-image over a background-color One picture says where, another says what color.
GetTextColor on the Today screen currentColor in an SVG icon The icon takes the color of the text around it.
A colored copy kept until the color changes A memoized render Do the work once, reuse it until the input changes.

One small file

All of HijriDate is one file, HijriPlugin.dll: 95,232 bytes. The Today screen loads it, gives it a strip of the screen, and calls it.

A DLL is a library other programs load. The Today screen asks this one for two functions by number: 240 draws the item, 241 runs its settings. The installer uses the very same file for its own setup steps. Tap a part of the file to see what is in it.

HijriPlugin.dll, version 1.5 · 95,232 bytes

Code 32,768 bytes, 34%

Every routine: the moon, the calendar, the strip of words, the coloring, the settings pages and the key check. About 8,000 ARM instructions.

A widget on a phone today asks the system to wake it on a schedule. The Today screen of 2003 asked every plug-in, every two seconds, whether it needed to redraw. HijriDate answers no, again and again, until the day changes. Drag the device clock across midnight:

  1. Redraw? No
  2. Redraw? No
  3. Redraw? No
  4. Redraw? No
  5. Redraw? No
  6. Redraw? Yes: the date changed
  7. Redraw? No
  8. Redraw? No
  9. Redraw? No
  10. Redraw? No
  11. Redraw? No
2 Ramadan 1427
Then and now
2003 to 20052026Why it is the same idea
A Today plug-in: a DLL with functions 240 and 241 A WidgetKit widget on iPhone, an App Widget on Android A small view the home screen hosts and refreshes.
WM_TODAYCUSTOM_QUERYREFRESHCACHE every two seconds A widget timeline that names its next update Redraw only when the content changes.
Settings under Software\Microsoft\today\items\Hijri Date UserDefaults or SharedPreferences A small key-value store per app.
One broadcast after install, WM_WININICHANGE A widget reload call Tell the home screen to look again, no restart.

That last row is a quiet kindness. HijriDate’s installer ends by sending the Today screen one broadcast message, so the date appears at once, with no restart.

The redraw check, in ARM
HIJRIPLUGIN.DLL 0x103EBC
103ECC bl GetLocalTime ; what day is it now?
103EE0 cmp r2,r3 ; the same day as the one drawn?
103EF8 cmp r2,r3 ; the same month?
103F0C cmp r2,r3 ; the same year?
103F1C cmp r3,#0 ; settings changed?
103F24 mov r0,#1 ; yes: redraw
103F2C pop {r4,pc} ; otherwise 0: nothing to do

A key for each Pocket PC

HijriDate ran free for 15 days. To keep it, you bought a key for the Pocket PC Code shown on its License Key page. That key worked on that Pocket PC alone.

The code comes from the device ID, a number unique to each Pocket PC, folded into 16 letters and digits. The key is made from the code by a shuffle in the style of RC4. 120 numbers are mixed by a secret word, then walked to turn each character of the code into a letter. The letter O never appears, so nobody confuses it with a zero. Step through it, or type any code to see its key.

The 120 numbers after the shuffle keyed by “Hijri”, and the 16 letters of the key: EQZCSAYTYAJELERW. 28 58 105 85 100 2 18 111 43 12 117 8 101 104 79 30 24 22 31 26 60 49 113 37 70 96 27 45 90 75 50 99 76 82 64 71 106 89 41 16 44 67 29 92 21 81 53 87 66 116 108 73 119 68 35 3 57 17 48 84 14 72 103 69 77 33 62 0 115 46 39 80 56 1 110 91 13 59 65 40 88 54 10 55 7 38 94 78 112 36 61 47 74 42 9 98 19 15 97 6 63 5 20 107 102 23 118 32 93 11 34 25 86 52 114 109 51 83 95 4 KEY E Q Z C S A Y T Y A J E L E R W

Key: EQZC - SAYT - YAJE - LERW

HIJRIPLUGIN.DLL the key
  1. 1056F0bl wcslen; length of the code
  2. 105738strh r3,[r1]; S[i] = i
  3. 105774strh r3,[r1]; K: the word, repeated
  4. 1057A4add r1,r3,r1; j += S[i] + K[i]
  5. 1057B4mov pc,r3; __rt_udiv: mod 120
  6. 1057CCstrh r7,[r0]; swap S[i], S[j]
  7. 1057ECnext:add r1,r7,#1; i += 1
  8. 10581Cadd r1,r8,r5; j += S[i]
  9. 105840strh r5,[r0]; swap them
  10. 10584Cadd r1,r3,r2,lsr #16; t = S[i] + S[j]
  11. 105874eor r1,r2,r3; char XOR S[t]
  12. 105884mov pc,r3; __rt_udiv: mod 25
  13. 105890add r0,r3,#0x41; + 'A'
  14. 1058A0cmp r3,#0x4f; skip 'O'
  15. 1058B8bhi next; next character
The same in C
  1. void Key(WCHAR *code, WCHAR *word) {
  2. WORD S[120], K[120]; n = wcslen(code);
  3. for (i = 0; i < 120; i++) S[i] = i;
  4. for (i = 0; i < 120; i++)
  5. K[i] = word[i % wcslen(word)];
  6. for (i = j = 0; i < 120; i++) {
  7. j = (j + S[i] + K[i]) % 120;
  8. swap(&S[i], &S[j]);
  9. }
  10. for (i = j = 0; n--; code++) {
  11. i = (i + 1) % 120;
  12. j = (j + S[i]) % 120;
  13. swap(&S[i], &S[j]);
  14. t = (S[i] + S[j]) % 120;
  15. c = 'A' + (*code ^ S[t]) % 25;
  16. *code = c >= 'O' ? c + 1 : c;
  17. }
  18. }
Watches
Help

All 16: EQZC - SAYT - YAJE - LERW. On that one Pocket PC, this key unlocks HijriDate.

To check a key, HijriDate runs the same function on its own code and compares the two. The key is stored in the registry, so it survives a restart. Run in an ARM emulator, HijriDate’s own check routine accepted the key for each of 200 Pocket PCs and turned away all 1,000 near misses.

The 15 days are counted from a tiny file the installer writes, \Windows\inter.dat. It holds the install date twice, in two disguises, nudges every second byte by one, and ends with a checksum. Change any byte and see what HijriDate makes of it:

month × 2 + 3✓
year + 7✓
year + 21✓
day × 2 + 5✓
month × 2 + 1✓
(day + 2) × 2✓
checksum✓ sum

Installed 24 September 2006, so on 27 September the trial has 12 days left.

In 2026, Yasser Awad released HijriDate as freeware. The unlock section above makes the key for your Pocket PC from its code, with the same function you just stepped through.

Download

Here are all 2 installers the Internet Archive kept, as DinarSoft published them. Take the one marked latest: the .CAB installs straight on the device, the .exe installs from a Windows PC.

FileVersionSizeSHA-256
DinarSoftHijriDate15.CABInstall on the Pocket PC · latestRecovered from the Internet Archive (Wayback Machine, January 16, 2007)1.5186.4 KB5c0e955b80c01e6f4f76d80ae700ecbb39b63f77aff24b26adaabc128243202e
DinarSoftHijriDate15.exeRun on a Windows PC with ActiveSync · latestRecovered from the Internet Archive (Wayback Machine, December 24, 2006)1.5344 KB91611e8cd8faba5d1dcbf5aabf340b989137ec5bc8f29031fa49026c757d0e82
Check a download

Pick an installer you downloaded. Your browser computes its SHA-256 fingerprint on your own device, nothing is uploaded, and looks for it among all 24 DinarSoft files. A match means every byte is the one the Internet Archive kept.

Unlock the full version

HijriDate: Register

Every DinarSoft trial asked for an unlock key after 15 days. In 2026 Yasser Awad made HijriDate free, so here is the key, made the way DinarSoft made it.

Each Pocket PC gets its own key. On the Today screen, tap the clock icon beside the date, open About and tap Register…. Copy the Pocket PC Code into the box here. Then type the key, four groups of four letters, into the four boxes.

For HijriDate 1.5.

Install it

  1. On a Pocket PC or Windows Mobile phone. Download the .CAB file marked latest. Copy it to the device on a memory card, through ActiveSync, or download it in Pocket Internet Explorer. Then open File Explorer on the device and tap it. It installs itself, like tapping an .apk on Android.
  2. From a Windows PC. Connect the device through ActiveSync on Windows XP, or Windows Mobile Device Center on later Windows, and run the Setup .exe. It sends the app to the device.
  3. In an emulator. Microsoft’s Device Emulator runs Windows Mobile 5 and 6 on a Windows PC. In its File menu, choose Configure and set a shared folder. The device sees that folder as its Storage Card. Put the .CAB there and tap it in File Explorer.
  4. Unlock it. Open HijriDate, find its Register screen, and type the key from this page.