Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# Calendar week from CTime

Posted on 1998-12-10
Medium Priority
377 Views
I have got the following problem:
I´ve got a function that should return the calendar week (1-53) that includes the day specified by a CTime object:

int WeekNo( CTime tTime )
{
int nWeek = ...
return nWeek;
}

ISO Norm: "The first week of a year is the one which includes january 4".

But this is not really the problem. The problem is, that a calendar week begins at monday. So if the monday of the week which includes january 4 of the NEXT year is not in the NEXT year but in the CURRENT, the 53. week of the CURRENT year  is the 1. of the NEXT year. And thats not all. The project I am working at the moment is old old 16Bit Win 3.1x application so I have to work with VC++1.52.

logis
0
Question by:logis
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 6

LVL 8

Accepted Solution

ID: 1326003
See answer in my comment below
0

LVL 8

Expert Comment

ID: 1326004
1. First off you probably want to make your WeekNo function use a const reference,  this doesn't really make any difference, but it avoids generating an extra CTime object

int WeekNo( const CTime& tTime )

2. Righjt now on to the maths,

CTime has a member GetTime which returns a time_t.  This is the number of seconds since 1970.  Now it also has a constructor which can take year, month, day, etc.

Therefore you can use this to do your maths (by subtracting these time_t values and converting back)

// get start of year
CTime tsoy( tTime.GetYear(), tTime.GetMonth(), tTime.GetDay(), 0, 0, 0 ) ;
time_t xStartOfYear = tsoy.GetTime() ;

This gives you the start of year as a seconds since 1970

0

LVL 8

Expert Comment

ID: 1326005
Oops.  Ignore item #2 above, I think I'll start from #2 again.

2. Now one other thing, is that your return a week number, that's fine, except you want to know the year as well (e.g. 1 January 19xx could count as being week 53 of year xx-1), so let's change your returning methods, to use references

void WeekNo( const CTime& tTime, int& year, int& weekno )

Basically the year and weekno will get changed by the function, so you'd call it like this

CTime someTime(...etc..)
int nYear ;
int nWeekNo ;
WeekNo( someTime, nYear, nWeekNo ) ;
printf( "Week %d of Year %d\n", nWeekNo, nYear ) ; // obviously change this to however you want to display - e.g don't use printf if not a console program.

0

LVL 8

Expert Comment

ID: 1326006
3. Now the maths, we want to calculate the time_t value for the 1 January of the year, and what day of the week

CTime jan1( tTime.GetYear(), 1, 1, 0, 0, 0 ) ;
time_t tjan1 = jan1.GetTime() ;
int wdayjan1 = jan1.GetDayOfWeek() ;

The GetDayOfWeek function returns 1=Sun, 2=Mon, 3=Tue, 4=Wed, etc..

Now Jan4 will count as the same week as Jan1 if, Jan1 is not Friday, Saturday or Sunday

BOOL bExtraWeek = TRUE ;
if ( ( wdayjan1 == 6 ) || ( wday == 7 ) || ( wday == 1 ) )
{
bExtraWeek = FALSE ;
}

0

LVL 8

Expert Comment

ID: 1326007
Now the next thing is to calculate the time_t for the first Monday in the year

// day of month of first Monday in the year
int nDayFirstMonday ;
switch ( wdayjan1 )
{
case 1 : nDayFirstMonday = 2 ; break ; // 2nd Jan if 1 Jan is Sunday
case 2 : nDayFirstMonday = 1 ; break ; // 1st Jan if 1 Jan is Monday
case 3 : nDayFirstMonday = 7 ; break ;
case 4 : nDayFirstMonday = 6 ; break ;
case 5 : nDayFirstMonday = 5 ; break ;
case 6 : nDayFirstMonday = 4 : break ;
case 7 : nDayFirstMonday = 3 ; break ;
}
CTime firstmonday( tTime.GetYear(), 1, nDayFirstMonday, 0, 0, 0 ) ;
time_t tfirstmonday = firstmonday.GetTime() ;

Now calculate the seconds elapses between the first monday and the date your concerned with

int secs = tTime.GetTime() - tfirstmonday ;

// convert this to weeks
int weeks = secs / ( 24 * 60 * 60 * 7 ) ;

The week numbers start from 1, therefore Now allowing for the fact that the year has an extra, week, (sorry I didn't fully understand how you want to handle the dates of the first week, maybe you can elaborate, but I think you mean)

if ( !bExtraWeek)
{
weeks++ ;
}

Finally make the function return the stuff you need

0

LVL 8

Expert Comment

ID: 1326008
if ( weeks == 0 )
{
// week 0 is week 53 of the previous year
year = tTime.GetYear() - 1 ;
weekno = 53 ;
} else
{
year = tTime.GetYear() ;
weekno = weeks ;
}

0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
###### Suggested Courses
Course of the Month4 days, 22 hours left to enroll