Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

weeks in year calculation??? 1

Status
Not open for further replies.

level1

Programmer
Apr 16, 2002
60
0
0
GB
Dear all

I ve been asked to do find a way to calculate all weeks in a year.

More specifically working weeks, which doesnt mean that i have to exlude any days like weekends but simply it means that the first week it will be: 14-March-2002 to 20-March-2002 starting from Thursday to Wednesday. So all these working weeks will count standart Thursday to the following Wednesday.

And as that the last working week it will be:
6-Mar-2003 to 12-Mar-2003

In total we have 52 working weeks.

Al i wanted was a similar script that given a Date will display a number (from 1-52) that shows in which working week we are.

So for example if i give 14-Mar-2002 the script will return 1.
and also if i give 17-Mar-2002 the script will again return 1. While giving 12-Mar-2003 the script will return 52.

The problem is that i did that using ASP script which goes through every single week and validate it as follows:

if (days>=14) and (days<=20) AND (months=&quot;Mar&quot;) AND (years=&quot;2002&quot;) THEN : i = 1 : end if
if (days>=21) and (days<=27) AND (months=&quot;Mar&quot;) AND (years=&quot;2002&quot;) THEN : i = 2 : end if

if ((days>=28) and (months=&quot;Mar&quot;)) OR ((days<=3) and (months=&quot;Apr&quot;)) AND (years=&quot;2002&quot;) THEN : i = 3 : end if Rem***month changes

.......

if ((days>=26) and (months=&quot;Dec&quot;) and (years=&quot;2002&quot;)) OR ((days<=1) and (months=&quot;Jan&quot;) and (years=&quot;2003&quot;)) THEN : i = 42 : end if rem year changes

.......

if (days>=6) and (days<=12) AND (months=&quot;Mar&quot;) AND (years=&quot;2003&quot;) THEN : i = 52 : end if

This done on ASP and works fine. But the problem is that only works for hardcoded dates as you see. E.g cannot work for year 2005 cause i havent put anything for this.

So i was about a Js or VB script that can do something similar but more dinamiclly. Any thoughts?
 
var a;
var b;
var c;
var startday = a;
var endday;
var startmonth = b;
var endmonth;
var startyear = c;
var endyears;
var daysworedinthewantedperiod = 0;
while (startyear <= endyear) {
while (startmonth <= endmonth) {
while (startday <= endday) {
daysworedinthewantedperiod++;
startday++;
}
startday = a;
startmonth++;
}
startmonth = b;
startyear++;
}
// now daysworedinthewantedperiod
// should return proper value just compare it
// day worked in a week... someone knowledge ends where
someone else knowledge starts
 
Date.prototype.isLeap = function()
{
var year = this.getFullYear();
return ((year() % 4) && (year % 100)) || !(year%400)
}

Date.prototype.getDaysInMonth = function()
{
var mDays = [
31,
( this.isLeap() ? 29 : 28 ),
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
];
return mDays[this.getMonth()];
}

Date.prototype.getMonthStartDay = function()
{
var date = this
date.setDate(1)
return date.getDay()
}

Date.prototype.getYearStartDay = function()
{
var date = this
date.setDate(1)
date.setMonth(0)
return date.getMonthStartDay()
}

Date.prototype.getWorkingWeek = function()
{
var yearReference = new Date(this.getFullYear(), 0, 0)

var yearInMills = yearReference.getTime() + (yearReference.getYearStartDay() * 24 * 60 * 60)
var week = Math.abs(yearInMills - this.getTime())
week = week / ((1000 * 60 * 60 * 24 * 7) - yearReference.getYearStartDay())

return (Math.ceil(week))
}

All you have to do from this code is create your new Date in JavaScript as you would normally for example :

var myDate = new Date() // without args it would be today
alert(myDate.getWorkingWeek())

Please debug my code and test it. I saw your post and got working ripping from another script of mine this code and adapting it. Don't be your life on it until you tested properly.

Hope this helps. Gary Haran
 
Thanks a lot people i never thought that it will be that quick. I tried all examples guys. I might dont solve the problem with Neversleep's example or with the thegiraffe's example but at least guys you helped me understand more about it. and trying work it out.

But what really impressed me was Xutopia's solution. You guy made it working without any mods at all, just change the begin dates and the thing works right.

Respect to all of you but special help to Xutopia.
 
Hey Garry can you ckeck your email please.
 
level1's question was how could we change the day on which we started counting the work weeks on. For example some companies have their legal accounting year start on june 1st and some on february first.

Here are modifications that are easily done to the Date object using the prototype keyword to attach new functionalities to it :

Date.prototype.getWorkingWeek = function()
{
var yearReference = new Date(this.getFullYear(), this.countStartMonth, this.countStartDay)

var yearInMills = yearReference.getTime() + (yearReference.getYearStartDay() * 24 * 60 * 60)
var week = Math.abs(yearInMills - this.getTime())
week = week / ((1000 * 60 * 60 * 24 * 7) - yearReference.getYearStartDay())

return (Math.ceil(week))
}

Date.prototype.countStartMonth = 0;
Date.prototype.countStartDay = 0;

Date.prototype.setCountStart = function(month, day)
{
this.countStartMonth = month;
this.countStartDay = day;
}


var myDate = new Date() // without args it would be today
myDate.setCountStart(1, 1)// sets year start on february 1st
alert(myDate.getWorkingWeek())

Hope this helps. Gary Haran
 
Dear Gary. Please correct me if im wrong but my js skills does not allow me to do much more from what you offering me: but if im right

this mods you ve done can offcourse alter the start date but not the end one.

in other words imagine that if the financial year starts at March for example 14-March-2002 it will suposed to be finish at 13-Mar-2003 and so on.

Your script works ok until December the 31st, but if im right when you request to see january of 2003 (any week) the script will return something smaller than expected, (suposed to show 40 or something but shows 8). Seems like it counts oposite direction, (like -8).

Correct me if im wrong but you can try it yourself by requesting any week on January using the script as its now. (starting on February)
 
darn, you asked me two minutes before I am leaving to go home. You are right I do have something wrong in my code.

I'll have to take a good look at it tomorow but I have no guarantees on deadline (R&D week is over with so I have less time on my hands) so anyone is welcomed to correct my mistake if they can come up with a fix.

Sorry can't help you much more tomorow. I promise I will take a look at it tomorow if no one came up with a solution. But don't count on me finding a solution. Dates are hard to deal with and I'm not being paid for the work I do in this forum.

Need sleep.... ;)

Gary Haran
 
Garry thanks dude. For all your help. Dont worry for me. Ill wait as much as i have to. I feel a bit usless that i cannot doit my self but as i said im not good on javascript. Thanks again.
 
Here is the fixed code. Once again warnings go out to anyone using this. It must be fully tested before depending on it.

Date.prototype.isLeap = function()
{
var year = this.getFullYear();
return ((year() % 4) && (year % 100)) || !(year%400)
}

Date.prototype.getDaysInMonth = function()
{
var mDays = [
31,
( this.isLeap() ? 29 : 28 ),
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
];
return mDays[this.getMonth()];
}

Date.prototype.getMonthStartDay = function()
{
var date = this
date.setDate(1)
return date.getDay()
}

Date.prototype.getYearStartDay = function()
{
var date = this
date.setDate(1)
date.setMonth(0)
return date.getMonthStartDay()
}

Date.prototype.getWorkingWeek = function()
{
var yearReference = new Date(this.getFullYear(), 0, 0)

var yearInMills = yearReference.getTime() + (yearReference.getYearStartDay() * 24 * 60 * 60)
var week = Math.abs(yearInMills - this.getTime())
week = week / ((1000 * 60 * 60 * 24 * 7) - yearReference.getYearStartDay())

var currentWorkWeek = Math.ceil(week) + this.weekCountStart

if (currentWorkWeek > 52)
{
currentWorkWeek -= 52
}

return currentWorkWeek
}

Date.prototype.weekCountStart = 0;

Date.prototype.setWeekCountStart = function (week)
{
this.weekCountStart = week;
}


Pretty much you instantiate a date the way you normally would in JavaScript (check any JS reference). Have this code in a JS file somewhere (I recommend calling it workWeek.js and linking to it in the head of the HTML pages) then all you have to do is create a Date and set the week count start.

var myDate = new Date() // without args it would be today
myDate.setWeekCountStart(5)// set the offset week you want to start on.
alert(myDate.getWorkingWeek())


You could also simply change the line :

Date.prototype.weekCountStart = 0;

With the offset you desire that way you don't need to change it using the setWeekCountStart method.


Date.prototype.weekCountStart = 5;
var myDate = new Date() // without args it would be today
alert(myDate.getWorkingWeek())


I hope this helps. Gary Haran
 
Hey Garry
There is a problem again which i managed to solve looking and debugging carefully your scripts.
So here we go:
Lets say im changing my clock at
25-dec-2002
and the following to
myDate.setWeekCountStart(0)
This returns 52 which seems ok.
But if i set it to
myDate.setWeekCountStart(1)
returns
1(one)??????
which offcourse is not right
should be 51
In my case that i want the first week to be week 10 (14-Mar-2002)
i should set the value to
myDate.setWeekCountStart(10)
but instead of getting
1(one)
i got 21?????
So i thought why not do the following
instead of
myDate.setWeekCountStart(10)
to do
myDate.setWeekCountStart(-10) !!!!!!!
which is ok until 31-dec-2002
but when reach january (say first week)
returns -9.
of course... simply add the following and your script now works perfect

if (currentWorkWeek == -9){currentWorkWeek = 44}
if (currentWorkWeek == -8){currentWorkWeek = 45}
if (currentWorkWeek == -7){currentWorkWeek = 46}
if (currentWorkWeek == -6){currentWorkWeek = 47}
if (currentWorkWeek == -5){currentWorkWeek = 48}
if (currentWorkWeek == -4){currentWorkWeek = 49}
if (currentWorkWeek == -3){currentWorkWeek = 50}
if (currentWorkWeek == -2){currentWorkWeek = 51}
if (currentWorkWeek == -1){currentWorkWeek = 52}
if (currentWorkWeek == 0){currentWorkWeek = 53}

i hope you understand what im trying to say

if not here is your script with my mods for a year beginning on week 10 (11-Mar-2002)...



----------------------------------------------------------------------------------------
Date.prototype.isLeap = function()
{
var year = this.getFullYear();
return ((year() % 4) && (year % 100)) || !(year%400)
}

Date.prototype.getDaysInMonth = function()
{
var mDays = [31,( this.isLeap() ? 29 : 28 ),31,30,31,30,31,31,30,31,30,31,];
return mDays[this.getMonth()];
}

Date.prototype.getMonthStartDay = function()
{
var date = this
date.setDate(1)
return date.getDay()
}

Date.prototype.getYearStartDay = function()
{
var date = this
date.setDate(1)
date.setMonth(0)
return date.getMonthStartDay()
}

Date.prototype.getWorkingWeek = function()
{
var yearReference = new Date(this.getFullYear(), 0, 0)

var yearInMills = yearReference.getTime() + (yearReference.getYearStartDay() * 24 * 60 * 60)
var week = Math.abs(yearInMills - this.getTime())
week = week / ((1000 * 60 * 60 * 24 * 7) - yearReference.getYearStartDay())

// return (Math.ceil(week))
//}
var currentWorkWeek = Math.ceil(week) + this.weekCountStart

if (currentWorkWeek > 52)
{
currentWorkWeek -= 52
}

if (currentWorkWeek == -9){currentWorkWeek = 44}
if (currentWorkWeek == -8){currentWorkWeek = 45}
if (currentWorkWeek == -7){currentWorkWeek = 46}
if (currentWorkWeek == -6){currentWorkWeek = 47}
if (currentWorkWeek == -5){currentWorkWeek = 48}
if (currentWorkWeek == -4){currentWorkWeek = 49}
if (currentWorkWeek == -3){currentWorkWeek = 50}
if (currentWorkWeek == -2){currentWorkWeek = 51}
if (currentWorkWeek == -1){currentWorkWeek = 52}
if (currentWorkWeek == 0){currentWorkWeek = 53}


return currentWorkWeek
}

//Date.prototype.weekCountStart = 10;

Date.prototype.setWeekCountStart = function (week)
{
this.weekCountStart = week;
}

var myDate = new Date() // without args it would be today
myDate.setWeekCountStart(-10)// set the offset week you want to start on.
//myDate.setWeekCountStart(1)// works wrong
alert(myDate.getWorkingWeek())

-----------------------------------------------------------------------------------



finally i wanna thank you for your responses to my anoing questions :))
when you have time whenever, can you show me how you can change the beggining day as we changed the beggining month, say the working week may start on tuesday instead of monday, or whatever...
Thats not urgent so if you want then check it.

Finally i wanan say i checked your site ???? are you a dhtml javascript genius or something?

very nice work :))) see you

 
glad I could help you. Dates is one of the most complex thing to work with since you have to make computers think in non standard counting techniques (computers count with binary, we count in decimals and time is counted in cyclical-incremental jibberish).

I like your modifications thanks for the good comments, it's apreciated. Hope you can continue to modify the script to make it work great. If you find you've reached something working great with all the efforts you put into the script, share it with others.

Glad to be of help. Gary Haran
 
Thanks for this detailed post. The script seems to be working. I am curious..if my start week is 29 then I need to have 29 if/then entries to convert the negative weeks into positive weeks right?

Thats a pain but it does the trick...if I can overcome this I will post back.

Thanks again.
Alex-
 

To convert negative values into positive, you can use Math.abs:

Code:
var positiveValue = Math.abs(-5);

Hope this helps,
Dan
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top