@@ -11,24 +11,135 @@ class Bikram {
1111
1212    double  YugaRotation_star = 1582237828 ;
1313    double  YugaRotation_sun = 4320000 ;
14-     double  YugaCivilDays = YugaRotation_star - YugaRotation_sun;  //  Initialize here 
15-     double  PlanetApogee_sun = 77  + 17.0  / 60 ;  //  Use double for division 
16-     double  PlanetCircumm_sun = 13  + 50.0  / 60 ;  //  Use double for division 
14+     double  YugaCivilDays = YugaRotation_star - YugaRotation_sun;
15+     double  PlanetApogee_sun = 77  + 17.0  / 60 ;
16+     double  PlanetCircumm_sun = 13  + 50.0  / 60 ;
1717    static  constexpr  double  rad = 57.2957795 ; //  180 / pi
1818
19+     //  Precomputed Data (starting from 2000 BS)
20+     static  const  int  BS_START_YEAR = 2000 ;
21+     static  const  int  BS_END_YEAR = 2089 ; //  Need adjustment depending how much data we have
22+ 
23+     inline  static  const  int  NP_MONTHS_DATA[][13 ] = {
24+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2000
25+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2001
26+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2002
27+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2003
28+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2004
29+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2005
30+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2006
31+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2007
32+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,29 ,31 ,365 }, //  2008
33+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2009
34+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2010
35+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2011
36+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2012
37+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2013
38+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2014
39+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2015
40+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2016
41+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2017
42+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2018
43+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2019
44+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2020
45+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2021
46+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,30 ,365 }, //  2022
47+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2023
48+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2024
49+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2025
50+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2026
51+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2027
52+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2028
53+         {31 ,31 ,32 ,31 ,32 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2029
54+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2030
55+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2031
56+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2032
57+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2033
58+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2034
59+         {30 ,32 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,29 ,31 ,365 }, //  2035
60+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2036
61+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2037
62+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2038
63+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2039
64+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2040
65+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2041
66+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2042
67+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2043
68+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2044
69+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2045
70+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2046
71+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2047
72+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2048
73+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,30 ,365 }, //  2049
74+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2050
75+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2051
76+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2052
77+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,30 ,365 }, //  2053
78+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2054
79+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2055
80+         {31 ,31 ,32 ,31 ,32 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2056
81+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2057
82+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2058
83+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2059
84+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2060
85+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2061
86+         {30 ,32 ,31 ,32 ,31 ,31 ,29 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2062
87+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2063
88+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2064
89+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2065
90+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,29 ,31 ,365 }, //  2066
91+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2067
92+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2068
93+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2069
94+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2070
95+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2071
96+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2072
97+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2073
98+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2074
99+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2075
100+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,30 ,365 }, //  2076
101+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2077
102+         {31 ,31 ,31 ,32 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2078
103+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2079
104+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,30 ,365 }, //  2080
105+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,366 }, //  2081
106+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2082
107+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2083
108+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2084
109+         {30 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2085
110+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2086
111+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2087
112+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2088
113+         {30 ,32 ,31 ,32 ,31 ,31 ,29 ,30 ,29 ,30 ,29 ,31 ,365 }, //  2089
114+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2090
115+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2091
116+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2092
117+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,29 ,31 ,365 }, //  2093
118+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2094
119+         {31 ,31 ,32 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2095
120+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,30 ,29 ,29 ,30 ,31 ,366 }, //  2096
121+         {31 ,31 ,31 ,32 ,31 ,31 ,29 ,30 ,30 ,29 ,30 ,30 ,365 }, //  2097
122+         {31 ,31 ,32 ,31 ,31 ,31 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2098
123+         {31 ,32 ,31 ,32 ,31 ,30 ,30 ,29 ,30 ,29 ,30 ,30 ,365 }, //  2099
124+     };
125+     static  const  int  NP_DATA_YEAR_COUNT = sizeof (NP_MONTHS_DATA) / sizeof (NP_MONTHS_DATA[0 ]);
126+ 
19127    void  getSauraMasaDay (long  ahar, int * m, int * d) const ;
20128    int  todaySauraMasaFirstP (long  ahar) const ;
21129    double  getTslong (long  ahar) const ;
22130    double  getJulianDate (int  year, int  month, int  day) const ;
23131    void  fromJulianDate (double  julian_date, int & year, int & month, int & day) const ;
24132
133+     void  fromGregorianAstronomical (int  y, int  m, int  d);  //  fallback
134+     void  toGregorianAstronomical (int  bsYear, int  bsMonth, int  bsDay, int & gYear , int & gMonth , int & gDay ); //  fallback
135+ 
25136public: 
26137    void  fromGregorian (int  y, int  m, int  d);
27138    void  toGregorian (int  bsYear, int  bsMonth, int  bsDay, int & gYear , int & gMonth , int & gDay );
28139    int  getYear () const ;
29140    int  getMonth () const ;
30141    int  getDay () const ;
31-     int  daysInMonth (int  year , int  month );
142+     int  daysInMonth (int  bsYear , int  bsMonth );
32143};
33144
34145inline  void  Bikram::getSauraMasaDay (long  ahar, int * m, int * d) const  {
@@ -77,7 +188,7 @@ inline double Bikram::getJulianDate(int year, int month, int day) const {
77188    }
78189    double  a = floor (year / 100.0 );
79190    double  b = 2  - a + floor (a / 4.0 );
80-     return  floor   (365.25  * (year + 4716 )) + floor (30.6001  * (month + 1 )) + day + b - 1524.5 ;
191+     return  floor (365.25  * (year + 4716 )) + floor (30.6001  * (month + 1 )) + day + b - 1524.5 ;
81192}
82193
83194inline  void  Bikram::fromJulianDate (double  julian_date, int & year, int & month, int & day) const  {
@@ -92,7 +203,58 @@ inline void Bikram::fromJulianDate(double julian_date, int& year, int& month, in
92203    year = (month > 2 ) ? (c - 4716 ) : (c - 4715 );
93204}
94205
206+ //  ------------- Modified fromGregorian to use precomputed first --------------
95207inline  void  Bikram::fromGregorian (int  y, int  m, int  d) {
208+     //  First calculate Julian days from fixed known date
209+     double  julian = getJulianDate (y, m, d);
210+     double  ref_julian = getJulianDate (1943 , 4 , 14 ); //  1 Baisakh 2000 BS = 14 April 1943
211+ 
212+     long  diff = static_cast <long >(julian - ref_julian);
213+     int  bs_year = BS_START_YEAR;
214+ 
215+     if  (diff >= 0 ) {
216+         while  (bs_year <= BS_START_YEAR + NP_DATA_YEAR_COUNT - 1 ) {
217+             for  (int  i = 0 ; i < 12 ; ++i) {
218+                 if  (diff < NP_MONTHS_DATA[bs_year - BS_START_YEAR][i]) {
219+                     Year = bs_year;
220+                     Month = i + 1 ;
221+                     Day = static_cast <int >(diff) + 1 ;
222+                     return ;
223+                 } else  {
224+                     diff -= NP_MONTHS_DATA[bs_year - BS_START_YEAR][i];
225+                 }
226+             }
227+             bs_year++;
228+         }
229+     }
230+     //  fallback to astronomical if outside precomputed
231+     fromGregorianAstronomical (y, m, d);
232+ }
233+ 
234+ //  -------------  Use precomputed first --------------
235+ inline  void  Bikram::toGregorian (int  bsYear, int  bsMonth, int  bsDay, int & gYear , int & gMonth , int & gDay ) {
236+     if  (bsYear >= BS_START_YEAR && bsYear < BS_START_YEAR + NP_DATA_YEAR_COUNT) {
237+         double  ref_julian = getJulianDate (1943 , 4 , 14 ); //  1 Baisakh 2000 BS
238+         long  total_days = 0 ;
239+         for  (int  year = BS_START_YEAR; year < bsYear; ++year) {
240+             total_days += NP_MONTHS_DATA[year - BS_START_YEAR][12 ];
241+         }
242+         for  (int  month = 0 ; month < bsMonth - 1 ; ++month) {
243+             total_days += NP_MONTHS_DATA[bsYear - BS_START_YEAR][month];
244+         }
245+         total_days += (bsDay - 1 );
246+ 
247+         double  target_julian = ref_julian + total_days;
248+         fromJulianDate (target_julian, gYear , gMonth , gDay );
249+         return ;
250+     }
251+     //  fallback to astronomical
252+     toGregorianAstronomical (bsYear, bsMonth, bsDay, gYear , gMonth , gDay );
253+ }
254+ 
255+ //  fallback methods
256+ 
257+ inline  void  Bikram::fromGregorianAstronomical (int  y, int  m, int  d) {
96258    double  julian = getJulianDate (y, m, d);
97259    long  ahar = julian - 588465.5 ;
98260    int  saura_masa_num;
@@ -102,11 +264,11 @@ inline void Bikram::fromGregorian(int y, int m, int d) {
102264    int  YearSaka = YearKali - 3179 ;
103265    int  nepalimonth = (saura_masa_num) % 12 ;
104266    Year = YearSaka + 135  + static_cast <int >((saura_masa_num - nepalimonth) / 12 );
105-     Month = (saura_masa_num + 12 ) % 12 ;
267+     Month = (saura_masa_num + 12 ) % 12  +  1 ;
106268    Day = saura_masa_day;
107269}
108270
109- inline  void  Bikram::toGregorian  (int  bsYear, int  bsMonth, int  bsDay, int & gYear , int & gMonth , int & gDay ) {
271+ inline  void  Bikram::toGregorianAstronomical  (int  bsYear, int  bsMonth, int  bsDay, int & gYear , int & gMonth , int & gDay ) {
110272    int  YearSaka = bsYear - 135 ;
111273    long  YearKali = YearSaka + 3179 ;
112274    long  ahar = static_cast <long >((YearKali * YugaCivilDays) / YugaRotation_sun);
@@ -126,14 +288,18 @@ inline int Bikram::getYear() const {
126288}
127289
128290inline  int  Bikram::getMonth () const  {
129-     return  Month +  1 ;
291+     return  Month;
130292}
131293
132294inline  int  Bikram::getDay () const  {
133295    return  Day;
134296}
135297
136298inline  int  Bikram::daysInMonth (int  bsYear, int  bsMonth) {
299+     if  (bsYear >= BS_START_YEAR && bsYear < BS_START_YEAR + NP_DATA_YEAR_COUNT) {
300+         return  NP_MONTHS_DATA[bsYear - BS_START_YEAR][bsMonth - 1 ];
301+     }
302+     //  fallback method
137303    int  gYear , gMonth , gDay ;
138304    int  nextMonth = (bsMonth % 12 ) + 1 ;
139305    int  nextYear = (bsMonth == 12 ) ? bsYear + 1  : bsYear;
0 commit comments