Open moosalim opened 3 years ago
typically it would require an internet connection for sure and a free API that does exactly as you said, so it isn't an easy HijriCalendar.now().add(Duration(days: -1)
that's a guess
It would be really great to have this HijriCalendar.now().add(Duration(days: -1));
instead of doing this:
final todayCorrected = DateTime.now().add(Duration(days: -1));
final hijriNow = HijriCalendar.fromDate(todayCorrected);
Any Update on this ?
Does this work for you @mobin-sk?
HijriCalendar.fromDate(DateTime.now().add(Duration(days: -1)));
i did do it by using an api as well, but man really this package needs a refactor
@aarif , it doesn't worked for me , i was to trying to adjust one day from calendar, based on moon sighting, but when i used this , Days in month are not adjusted .
HijriCalendar.fromDate(DateTime.now().add(Duration(days: -1)));
Can anyone explain what are this numbers, where can i find for my required month & year
adj[17292] = 59083; // 30 days instead of 29
@mobin-sk, Please have a look at the thread in Issue #6. If you still have questions, I will do my best to explain.
Yeah i checked it, seems like making some adjustments but not as desired may be i'm missing the logic to generarte key & value , Can you please share some example code to genetate key & values for desired date ? It will helps me lot
For your reference this is what i'm doing
int calculateHijriKey(int year, int month) {
// Passing hijri year & hijri Month
return (year - 1) * 12 + month;
}
int calculateJulianDay(int year, int month, int day) {
// passing DateTime year, month & day
print("$year $month $day");
int a = ((14 - month) ~/ 12);
int y = year + 4800 - a;
int m = month + 12 * a - 3;
int jd = day + ((153 * m + 2) ~/ 5) + 365 * y + (y ~/ 4) - (y ~/ 100) + (y ~/ 400) - 32045;
print(jd);
return (jd - 2400000);
}
void _updateNumDaysInMonth(int numDays) {
setState(() {
var defCal = HijriCalendar.fromDate(DateTime(2023, 3, 22));
print("By default ${defCal.fullDate()}");
var adjCal = HijriCalendar();
var adj = Map<int, int>();
int monthKey = calculateHijriKey(_selectedDate.hYear, _selectedDate.hMonth);
int julianValue = calculateJulianDay(2023, 3, 21);
adj[monthKey] = julianValue; // 29 days instead of 30
adjCal.setAdjustments(adj);
print(adj);
adjCal.gregorianToHijri(2023, 3, 22);
print("adjusted ${adjCal.fullDate()}");
});
}
This is what i'm trying method to generate key & value, and trying to adjust day is this correct way or i'm missing something?
I haven't verified the calculations above, but it appears you are trying to change the Ramadhan 1st, to be March 21, 2023.
This is a perfect example of what the adjustments are for and I believe you are on the right track.
The following line will return the monthKey
of the month corresponding to March 22nd, 2023:
int monthKey = calculateHijriKey(_selectedDate.hYear, _selectedDate.hMonth);
A quick look at the internal array, I see the Julian Date 60027
which corresponds to March 23rd, 2023.
Since according to the array, March 22nd, 2023 falls within Shabaan, this means that with the above code, you are changing Shabaan to start on March 21st instead of Ramadhan to start on March 21st.
I believe that if you change the date in the following line to be a date that is firmly in Ramadhan, the above code should work as expected:
var defCal = HijriCalendar.fromDate(DateTime(2023, 3, 22));
For example, given that all the calculations in the supporting functions are correct, changing the above line to the following should yield your desired result:
var defCal = HijriCalendar.fromDate(DateTime(2023, 3, 29));
@mobin-sk
(correction to the the above)
I made a slight modification to your calculateHijriKey
function. The Month needs to be zero-based (eg. Muharram is 0).
I also hard-coded the monthKey
calculation to use Ramadhan 1444, because I wasn't sure what the value of _selectedDate
was.
This code works as expected.
int calculateHijriKey(int year, int month) {
// Passing hijri year & hijri Month
print("${year} ${month}");
return(year - 1) * 12 + month - 1;
}
int calculateJulianDay(int year, int month, int day) {
// passing DateTime year, month & day
print("$year $month $day");
int a = ((14 - month) ~/ 12);
int y = year + 4800 - a;
int m = month + 12 * a - 3;
int jd = day + ((153 * m + 2) ~/ 5) + 365 * y + (y ~/ 4) - (y ~/ 100) + (y ~/ 400) - 32045;
print(jd);
return (jd - 2400000);
}
void main() {
var defCal = HijriCalendar.fromDate(DateTime(2023, 3, 21));
print("By default ${defCal.fullDate()}");
var adjCal = HijriCalendar();
var adj = Map<int, int>();
int monthKey = calculateHijriKey(1444, 9); // Change Ramadhan 1444
int julianValue = calculateJulianDay(2023, 3, 21);
adj[monthKey] = julianValue;
adjCal.setAdjustments(adj);
print(adj);
adjCal.gregorianToHijri(2023, 3, 21);
print("adjusted ${adjCal.fullDate()}");
}
Thanks i have changed it, & i was almost close to complete my Hijri Calendar page with day adjustment option, Thanks again. : )
No worries.
I do feel that this library could do with some extra helper function to make management of the adjustments easier.
For example:
adjustCurrentMonth(int)
which will adjust the beginning of the current month by an offset (eg. 1 or -1)adjustNextMonth(int)
which will adjust the beginning of the next month by an offset (eg. 1 or -1)getAdjustments()
to return the current calendars adjustments so they can be persistedThat would be great !
@aarif I just to summarize this Key Value concept correct me if wrong Scenario : Changing 30 days of shaaban to 29 days KEY : it will be generated key for hijri month which we want to adjust. For Example : I want to adjust Shaaban : Then resulted key using the below logic will be : 17323
calculateHijriKey(1444,8); // Results : 17323
int calculateHijriKey(int year, int month) {
print("Hijri $year + Hijri $month"); // Hijri 1444, Hijri 8
return (year - 1) * 12 + (month - 1); // 17323
}
VALUE : It will be julian day of the Selected Gregorian day For Example : Selected day is 21,Mar,2023 then its related Julian day after converting will be : 60025
calculateJulianDay(2023,03,21); // 60025
int calculateJulianDay(int year, int month, int day) {
print("Converting date : $year/$month/$day to Jullian Day");
int a = ((14 - month) ~/ 12);
int y = year + 4800 - a;
int m = month + 12 * a - 3;
int JDN = day + ((153 * m + 2) ~/ 5) + 365 * y + (y ~/ 4) - (y ~/ 100) + (y ~/ 400) - 32045;
return (JDN - 2400000);
}
So the final Adjsutment map will be :
Map<int,int> adjustment = {17323 : 60025 };
When I add this adjustments to hijricalendar results where stunning making Shaaban as Two days. 🤪
Finally Method I'm calling:
Future<void> _updateNumDaysInMonth(int y, int m, int d) async {
_numDaysInMonth = _selectedDate.getDaysInMonth(_selectedDate.hYear, _selectedDate.hMonth);
print("Before Adjusting No of days $_numDaysInMonth : @$y/$m/$d || Hijri : : : :${_selectedDate.hYear}/${_selectedDate.hMonth}"); // Before Adjusting No of days : 30 @2023/3/21 || Hijri : 1444/8
int monthKey = calculateHijriKey(_selectedDate.hYear, _selectedDate.hMonth);
int julianValue = calculateJulianDay(y, m, d);
adj[monthKey] = julianValue;
_selectedDate.setAdjustments(adj);
_numDaysInMonth = _selectedDate.getDaysInMonth(_selectedDate.hYear, _selectedDate.hMonth);
print("After Adjusting | adj $adj No of days : $_numDaysInMonth @$y/$m/$d || Hijri : ${_selectedDate.hYear}/${_selectedDate.hMonth}"); //After Adjusting | adj {17323: 60025} No of days : 2 @2023/3/21 || Hijri : 1444/8
@mobin-sk
Yes, you are correct. The key represents a particular Hijri month and the value is the Julian day in the Gregorian calendar that the month should start.
In your example, you changed the month of Shabaan to start on March 21st, but you did not change the next element in the array which represents Ramadhan, so it still falls on March 23rd. So, as you have deduced, Shabaan has 2 days.
The adjustment mechanism only adjusts one month at a time. In order to maintain the integrity of the array, you may need to apply several adjustments to achieve what you want.
The default array is quite accurate, as it should be. I expect that if you are use this library, or any library which uses the same algorithm, you should have very few adjustments.
Thanks @aarif let me try in this way.
only one adjustment per month.
I can see from internet, hijri date is different in UAE & India one day difference.
Default is matching with UAE but not with India I was trying to adjust, calendar to match with Indian dates.
Thanks for this plugin, Jazak Allah Khair
I believe there should be a way to correct the date if there is a need to so so, based on moon sighting. Please try to add this feature as it is very important.
I suggest adding method similar to the flutter standard one :
DateTime.now().add(Duration(days: -1))
So, for for hijri it can be like this
HijriCalendar.now().add(Duration(days: -1))
May Allah reward your work.