Convert Jalali calendar to Gregorian by PHP in CodeIgniter
Asked Answered
F

5

11

I need to store Date in Persian (Jalali) date in MySQL. I'm using CodeIgniter. I need something like this:

$Date = Jalali_to_Georgian(1393,5,28) // Output: "2014/08/19"

Do I need to create a new library for this?

Flue answered 4/5, 2015 at 5:11 Comment(0)
L
6

It's generally better to stick to existing libs rather than writing your own one. Try, for example, jDateTime or Gregorian-Jalali-Date-Convertor.

P.S. I never tried to use them myself, but first one looks much more solid.

Lachman answered 6/5, 2015 at 14:50 Comment(2)
Thanks, but how can I integrate theme with codeigniter? How to use them in a library?Flue
Ideally, you should use composer or similar tool to integrate external librariesLachman
A
4

You can use this function

jalali_to_gregorian($year, $month, $day, $separator);
  • Example with separator:

    jalali_to_gregorian(1398, 5, 7, "-"); // Output => 2019-7-29
    
  • Example without separator:

    jalali_to_gregorian(1398, 5, 7); // Output => ["2019","7","29"]
    

And this is the function:

function jalali_to_gregorian($jy, $jm, $jd, $mod = '')
{
    if ($jy > 979) {
        $gy = 1600;
        $jy -= 979;
    } else {
        $gy = 621;
    }

    $days = (365 * $jy) + (((int)($jy / 33)) * 8) + ((int)((($jy % 33) + 3) / 4)) + 78 + $jd + (($jm < 7) ? ($jm - 1) * 31 : (($jm - 7) * 30) + 186);
    $gy += 400 * ((int)($days / 146097));
    $days %= 146097;
    if ($days > 36524) {
        $gy += 100 * ((int)(--$days / 36524));
        $days %= 36524;
        if ($days >= 365) $days++;
    }
    $gy += 4 * ((int)(($days) / 1461));
    $days %= 1461;
    $gy += (int)(($days - 1) / 365);
    if ($days > 365) $days = ($days - 1) % 365;
    $gd = $days + 1;
    foreach (array(0, 31, ((($gy % 4 == 0) and ($gy % 100 != 0)) or ($gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) as $gm => $v) {
        if ($gd <= $v) break;
        $gd -= $v;
    }

    return ($mod === '') ? array($gy, $gm, $gd) : $gy . $mod . $gm . $mod . $gd;
}
Arboretum answered 27/7, 2019 at 12:43 Comment(0)
A
1

you can simply use:

    $fmt = new IntlDateFormatter(
    'en_US@calendar=persian',
    IntlDateFormatter::FULL, //date format
    IntlDateFormatter::NONE, //time format
    'Asia/Tehran',
    IntlDateFormatter::TRADITIONAL,
"yyyy-MM-dd"
);
$Date=date('Y-m-d', $fmt->parse('1393-05-28 AP'));
Amanda answered 15/5, 2023 at 7:17 Comment(0)
S
0

First, Create a library in application/libraries named Calendar.php

Class Calendar
{


    function jalali_to_gregorian($j_y, $j_m, $j_d)
    {
        $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
        $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);



        $jy = $j_y-979;
        $jm = $j_m-1;
        $jd = $j_d-1;

        $j_day_no = 365*$jy + $this->div($jy, 33)*8 + $this->div($jy%33+3, 4);
        for ($i=0; $i < $jm; ++$i)
        $j_day_no += $j_days_in_month[$i];

        $j_day_no += $jd;

        $g_day_no = $j_day_no+79;

        $gy = 1600 + 400*$this->div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
        $g_day_no = $g_day_no % 146097;

        $leap = true;
        if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
        {
            $g_day_no--;
            $gy += 100*$this->div($g_day_no,  36524); /* 36524 = 365*100 + 100/4 - 100/100 */
            $g_day_no = $g_day_no % 36524;

            if ($g_day_no >= 365)
            $g_day_no++;
            else
            $leap = false;
        }

        $gy += 4*$this->div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
        $g_day_no %= 1461;

        if ($g_day_no >= 366) {
            $leap = false;

            $g_day_no--;
            $gy += $this->div($g_day_no, 365);
            $g_day_no = $g_day_no % 365;
        }

        for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
        $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
        $gm = $i+1;
        $gd = $g_day_no+1;

        return array($gy, $gm, $gd);
    }
}

Then use it whenever you want:

Class TestController
{
    function index()
    {
        $this->load->library('calendar');
        list($year, $month, $day) = $this->calendar->jalali_to_gregorian(1395,5,12);
        echo "$year/$month/$day";
    }
}

Best Regards

Solana answered 22/1, 2019 at 20:50 Comment(0)
A
0

I'm sure that jDate is not working properly. I myself have written a class that correctly converts between miladi, qamary, and jalali dates from 1/1/1 to 29/12/3000

Unfortunately, I cannot provide you with the source code, but if you come up with another way to solve your problem, I can cooperate with you.

Also, if I want to guide you to write the date conversion, I must say that there is no formula for calculating the leap year in the Jalali calendar. (I can explain why if you want) I have the list of leap years up to 3000 Jalali. It can solve your biggest challenge.

  4  , 9  , 
  13 , 17 , 21 , 25 , 29 , 33 , 37 , 42 , 
  46 , 50 , 54 , 58 , 62 , 66 , 71 ,
  75 , 79 , 83 , 87 , 91 , 95 , 99 , 104,
  108, 112, 116, 120, 124, 128, 132, 137,
  141, 145, 149, 153, 157, 161, 165, 170,
  174, 178, 182, 186, 190, 194, 198, 203,
  207, 211, 215, 219, 223, 227, 231, 236,
  240, 244, 248, 252, 256, 260, 264, 269,
  273, 277, 281, 285, 289, 293, 297, 302,
  306, 310, 314, 318, 322, 326, 331,
  335, 339, 343, 347, 351, 355, 359, 364,
  368, 372, 376, 380, 384, 388, 392, 397,
  401, 405, 409, 413, 417, 421, 425, 430,
  434, 438, 442, 446, 450, 454, 458, 463,
  467, 471, 475, 479, 483, 487, 491, 496,
  500, 504, 508, 512, 516, 520, 524, 529,
  533, 537, 541, 545, 549, 553, 558,
  562, 566, 570, 574, 578, 582, 586, 591,
  595, 599, 603, 607, 611, 615, 619, 624,
  628, 632, 636, 640, 644, 648, 652, 656, 661,
  665, 669, 673, 677, 681, 685, 690,
  694, 698, 702, 706, 710, 714, 718, 723,
  727, 731, 735, 739, 743, 747, 751, 756,
  760, 764, 768, 772, 776, 780, 784, 789,
  793, 797, 801, 805, 809, 813, 817, 822,
  826, 830, 834, 838, 842, 846, 850, 855,
  859, 863, 867, 871, 875, 879, 883, 888,
  892, 896, 900, 904, 908, 912, 916, 921,
  925, 929, 933, 937, 941, 945, 949, 954,
  958, 962, 966, 970, 974, 978, 983,

  987 , 991 , 995 , 999 , 1003, 1007, 1011, 1016,
  1020, 1024, 1028, 1032, 1036, 1040, 1044, 1049,
  1053, 1057, 1061, 1065, 1069, 1073, 1077, 1082,
  1086, 1090, 1094, 1098, 1102, 1106, 1110, 1115,
  1119, 1123, 1127, 1131, 1135, 1139, 1143, 1148,
  1152, 1156, 1160, 1164, 1168, 1172, 1176, 1181,
  1185, 1189, 1193, 1197, 1201, 1205, 1209, 1214,
  1218, 1222, 1226, 1230, 1234, 1238, 1243,
  1247, 1251, 1255, 1259, 1263, 1267, 1271, 1275, 1280,
  1284, 1288, 1292, 1296, 1300, 1304, 1308, 1313,
  1317, 1321, 1325, 1329, 1333, 1337, 1341, 1346,
  1350, 1354, 1358, 1362, 1366, 1370, 1375,
  1379, 1383, 1387, 1391, 1395, 1399, 1403, 1408,
  1412, 1416, 1420, 1424, 1428, 1432, 1436, 1441,
  1445, 1449, 1453, 1457, 1461, 1465, 1469, 1473, 1478,
  1482, 1486, 1490, 1494, 1498, 1502, 1507,
  1511, 1515, 1519, 1523, 1527, 1531, 1535, 1540,
  1544, 1548, 1552, 1556, 1560, 1564, 1568, 1573,
  1577, 1581, 1585, 1589, 1593, 1597, 1601, 1606,
  1610, 1614, 1618, 1622, 1626, 1630, 1634, 1639, 
  1643, 1647, 1651, 1655, 1659, 1663, 1667, 1672,
  1676, 1680, 1684, 1688, 1692, 1696, 1700, 1705,
  1709, 1713, 1717, 1721, 1725, 1729, 1733, 1738,
  1742, 1746, 1750, 1754, 1758, 1762, 1766, 1771,
  1775, 1779, 1783, 1787, 1791, 1795, 1799, 1804,
  1808, 1812, 1816, 1820, 1824, 1828, 1832, 1837,
  1841, 1845, 1849, 1853, 1857, 1861, 1865, 1870,
  1874, 1878, 1882, 1886, 1890, 1894, 1898, 1903,
  1907, 1911, 1915, 1919, 1923, 1927, 1932,
  1936, 1940, 1944, 1948, 1952, 1956, 1960, 1965,
  1969, 1973, 1977, 1981, 1985, 1989, 1993, 1997, 2002,
  2006, 2010, 2014, 2018, 2022, 2026, 2030, 2035,
  2039, 2043, 2047, 2051, 2055, 2059, 2064,
  2068, 2072, 2076, 2080, 2084, 2088, 2092, 2097,
  2101, 2105, 2109, 2113, 2117, 2121, 2125, 2130,
  2134, 2138, 2142, 2146, 2150, 2154, 2158, 2163,
  2167, 2171, 2175, 2179, 2183, 2187, 2191, 2196,
  2200, 2204, 2208, 2212, 2216, 2220, 2224, 2229,
  2233, 2237, 2241, 2245, 2249, 2253, 2257, 2262,
  2266, 2270, 2274, 2278, 2282, 2286, 2290, 2295,
  2299, 2303, 2307, 2311, 2315, 2319, 2323, 2328,
  2332, 2336, 2340, 2344, 2348, 2352, 2356, 2361,
  2365, 2369, 2373, 2377, 2381, 2385, 2389, 2394,
  2398, 2402, 2406, 2410, 2414, 2418, 2422, 2427,
  2431, 2435, 2439, 2443, 2447, 2451, 2455, 2460,
  2464, 2468, 2472, 2476, 2480, 2484, 2488, 2493,
  2497, 2501, 2505, 2509, 2513, 2517, 2521, 2526,
  2530, 2534, 2538, 2542, 2546, 2550, 2554, 2559,
  2563, 2567, 2571, 2575, 2579, 2583, 2587, 2592,
  2596, 2600, 2604, 2608, 2612, 2616, 2621,
  2625, 2629, 2633, 2637, 2641, 2645, 2649, 2654,
  2658, 2662, 2666, 2670, 2674, 2678, 2682, 2686, 2691,
  2695, 2699, 2703, 2707, 2711, 2715, 2719, 2724,
  2728, 2732, 2736, 2740, 2744, 2748, 2752, 2757,
  2761, 2765, 2769, 2773, 2777, 2781, 2786,
  2790, 2794, 2798, 2802, 2806, 2810, 2814, 2818, 2823,
  2827, 2831, 2835, 2839, 2843, 2847, 2851, 2856,
  2860, 2864, 2868, 2872, 2876, 2880, 2884, 2889,
  2893, 2897, 2901, 2905, 2909, 2913, 2918,
  2922, 2926, 2930, 2934, 2938, 2942, 2946, 2951,
  2955, 2959, 2963, 2967, 2971, 2975, 2979, 2984,
  2988, 2992, 2996, 3000
Altman answered 29/3, 2023 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.