Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust date based on Moon sighting #8

Open
moosalim opened this issue Feb 11, 2021 · 18 comments
Open

Adjust date based on Moon sighting #8

moosalim opened this issue Feb 11, 2021 · 18 comments

Comments

@moosalim
Copy link

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.

@youssefali424
Copy link

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

@iballan
Copy link
Collaborator

iballan commented Aug 16, 2022

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);

@mobin-sk
Copy link

mobin-sk commented Mar 8, 2023

Any Update on this ?

@aarif
Copy link
Contributor

aarif commented Mar 8, 2023

Does this work for you @mobin-sk?

HijriCalendar.fromDate(DateTime.now().add(Duration(days: -1)));

@youssefali424
Copy link

i did do it by using an api as well, but man really this package needs a refactor

@mobin-sk
Copy link

@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)));

@mobin-sk
Copy link

Can anyone explain what are this numbers, where can i find for my required month & year

adj[17292] = 59083; // 30 days instead of 29

@aarif
Copy link
Contributor

aarif commented Mar 18, 2023

@mobin-sk,
Please have a look at the thread in Issue #6. If you still have questions, I will do my best to explain.

@mobin-sk
Copy link

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

@mobin-sk
Copy link

mobin-sk commented Mar 18, 2023

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?

@aarif
Copy link
Contributor

aarif commented Mar 18, 2023

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));

@aarif
Copy link
Contributor

aarif commented Mar 18, 2023

@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()}");
}

@mobin-sk
Copy link

Thanks i have changed it, & i was almost close to complete my Hijri Calendar page with day adjustment option,
Thanks again. : )

@aarif
Copy link
Contributor

aarif commented Mar 18, 2023

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 persisted

@mobin-sk
Copy link

That would be great !

@mobin-sk
Copy link

mobin-sk commented Mar 20, 2023

@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

@aarif
Copy link
Contributor

aarif commented Mar 21, 2023

@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.

@mobin-sk
Copy link

Thanks @aarif let me try in this way.

  1. so value is start day of the selected month.
  2. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants