0

old title: How to calculate number of week in a given month

Due to the answer i provide i change the title...


i'm creating a library to then wrap it in my project, which provide some date information in my culture,

the library is like this:

///<reference path="IDate.ts"/>
/**
 * Created by Hassan on 1/28/2016.
 */
// Help References:
// 1- http://www.aftabir.com/encyclopedia/urgent/calendar/chronometry/leapyear_new.php
var PersianDate = (function () {
    function PersianDate(year, month, day, firstDayOfWeek) {
        this.day = day;
        this.month = month;
        this.year = year;
        this.firstDayOfWeek = firstDayOfWeek;
    }
    PersianDate.prototype.isLeapYear = function () {
        var year = this.year;
        //var a = 0.025;
        //var b = 266;
        //var leapDays0;
        //var leapDays1;
        //var frac0;
        //var frac1;
        //if (year > 0) {
        //    leapDays0 = ((year + 38) % 2820) * 0.24219 + a; // 0.24219 ~ extra days of one year
        //    leapDays1 = ((year + 39) % 2820) * 0.24219 + a; // 38 days is the difference of epoch to 2820-year cycle
        //}
        //else if (year < 0) {
        //    leapDays0 = ((year + 39) % 2820) * 0.24219 + a;
        //    leapDays1 = ((year + 40) % 2820) * 0.24219 + a;
        //}
        //else {
        //    return false;
        //}
        //frac0 = Math.floor((leapDays0 - Math.floor(leapDays0)) * 1000);
        //frac1 = Math.floor((leapDays1 - Math.floor(leapDays1)) * 1000);
        //if (frac0 <= b && frac1 > b)
        //    return true;
        //else
        //    return false;

        var a = year+2346;
        var a2 = year-1 + 2346; //(A-1)=N-1+2346 -> 'A-1' is just a name of last year
        var b1 = Math.ceil(a * 365.24219879);
        var b2 = Math.ceil(a2 * 365.24219879);

        return b1 - b2 == 366;
    };
    PersianDate.prototype.getDaysInMonth = function () {
        switch (this.month) {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
                return 31;
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
                return 30;
            case 12:
                return (this.isLeapYear() ? 30 : 29);
        }
        return undefined;
    };
    PersianDate.prototype.getDaysInWeek = function () {
        return 7;
    };
    PersianDate.prototype.getDaysInYear = function () {
        return 365 + (this.isLeapYear() ? 1 : 0);
    };
    PersianDate.prototype.getMonthsInYear = function () {
        return 12;
    };
    PersianDate.prototype.getWeeksInYear = function () {
        return this.getDaysInYear() + (this.getWeekFirstDay()) / 7;
    };
    PersianDate.prototype.getWeeksInMonth = function () {
        var month = this.getMonth();
        console.log(month);
        var totalDaysToMonthStart;
        if (month <= 7) {
            totalDaysToMonthStart = (month - 1) * 31;
            console.log(totalDaysToMonthStart)
        }
        else {
            totalDaysToMonthStart = 186 + ((month - 6 - 1) * 30);
            console.log(totalDaysToMonthStart)
        }
        var remainedDayWithoutStartingDays = 7 - (totalDaysToMonthStart% 7);

        var WeeksAfterStarting = Math.floor((this.getDaysInMonth() - remainedDayWithoutStartingDays) / 7);

        console.log("remainedDayWithoutStartingDays: ", remainedDayWithoutStartingDays);
        console.log("WeeksAfterStarting: ", WeeksAfterStarting)
        return WeeksAfterStarting + (remainedDayWithoutStartingDays != 0)? 1:0;
    };
    PersianDate.prototype.getWeekFirstDay = function () {
        var n = this.year;
        var a = n - 1;
        var b = a + 2346;
        var yearLength = b * 365.24219879; //tool sal motevasete khorshidi
        var c = Math.ceil(yearLength);
        //نظر به آنکه مبداء سال ۲۳۴۶- روز سه‌شنبه بوده است (و با انتساب اعداد صفر و يک تا شش به شنبه و يکشنبه تا جمعه) به C سه واحد مى‌افزائيم يا از آن چهار واحد کم مى‌کنيم تا به مبداء شنبه انتقال يابيم و عدد حاصل را d مى‌ناميم.
        var d = c + 3;
        var r = d % 7;
        console.log("First day of year: " + r);
        return r;
    };
    PersianDate.prototype.getDay = function () {
        return this.day;
    };
    PersianDate.prototype.getWeekOfYear = function () {
        console.log("Week of Year: " + this.getDayOfYear() + this.getWeekFirstDay() / 7);
        return this.getDayOfYear() + this.getWeekFirstDay() / 7;
    };
    PersianDate.prototype.getWeekOfMonth = function () {
        return undefined;
    };
    PersianDate.prototype.getDayOfWeek = function () {
        return undefined;
    };
    PersianDate.prototype.getDayOfMonth = function () {
        return undefined;
    };
    PersianDate.prototype.getDayOfYear = function () {
        return undefined;
    };
    PersianDate.prototype.getMonth = function () {
        return this.month;
    };
    PersianDate.prototype.getYear = function () {
        return this.year;
    };
    return PersianDate;
})();
//# sourceMappingURL=PersianDate.js.map

var pd = new PersianDate(1395, 1, 1);
pd.getWeekFirstDay();
pd.getWeeksInMonth();

first day of week return 0 to 6 (i'm not sure if standard datetime do this or not)

and the thing become problematic is the getWeeksInMonth:

first i made it work, but in month with full set of days in their first weeks it failed, then i change it, now it doesn't work at all. i searched and i couldn't get the right formula. (better say i didn't got any formula at all)

what should i do to return weeks in a given month:

for the given date 1395/01 it should be like the image: enter image description here

as you can see in fifth and eleven month we have 6 week in one month, and other are 5days. hopw to fix it? i kinda have issue with weeks in all kinda dates :'(

Thank you.


NOTE: To any guys in future may visit this thread, this class is based on PersianCalendar, not GregorianCalendar.

Hassan Faghihi
  • 1,888
  • 1
  • 37
  • 55
  • `PersianDate.prototype.isLeapYear = function () {...`. Why so complex? Read [this answer](http://stackoverflow.com/a/19570985/2118955) to see how your code can be dramatically simplified. – hindmost Jan 28 '16 at 16:05
  • it's leapYear in my culture, i found it somewhere, and it's very accurate, BTW, i'm sure there's something exists as you said for just specific duration of time, which we won't require any more most of the times. *BUT* that's not the issue here, that's the weeks... – Hassan Faghihi Jan 28 '16 at 16:13
  • @hindmost here, for your sake, i simplified it. but be careful, it's date based PersianCalendar, not Gregorian one. – Hassan Faghihi Jan 28 '16 at 16:50

1 Answers1

0

it sure take lot time since someone helped me to solve that issue, and then i forgot about it all, but i made a repository, so the important formula are there:

https://github.com/deadmann/Calendar

Hassan Faghihi
  • 1,888
  • 1
  • 37
  • 55
  • 1
    Could my method here help you?: https://stackoverflow.com/questions/71421825/how-to-convert-persian-jalali-dates-to-other-18-calendar-dates-in-javascript-w – Mohsen Alyafei Mar 12 '22 at 09:34
  • To be honest after relocating, I got involved with many stuff that I hardly find time for the urgent ones. – Hassan Faghihi Mar 12 '22 at 14:20