C programme to printf the week number of the year?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
C programme to printf the week number of the year?
Hello,
I have tried to make a small programme to display using C, the output via printf, for the number of the week of the year?
it does not work.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int GetWeek( struct tm* date)
{
if (NULL == date)
{
return 0; // or -1 or throw exception
}
if (::mktime(date) < 0) // Make sure _USE_32BIT_TIME_T is NOT defined.
{
return 0; // or -1 or throw exception
}
// The basic calculation:
// {Day of Year (1 to 366) + 10 - Day of Week (Mon = 1 to Sun = 7)} / 7
int monToSun = (date->tm_wday == 0) ? 7 : date->tm_wday; // Adjust zero indexed week day
int week = ((date->tm_yday + 11 - monToSun) / 7); // Add 11 because yday is 0 to 365.
// Now deal with special cases:
// A) If calculated week is zero, then it is part of the last week of the previous year.
if (week == 0)
{
// We need to find out if there are 53 weeks in previous year.
// Unfortunately to do so we have to call mktime again to get the information we require.
// Here we can use a slight cheat - reuse this function!
// (This won't end up in a loop, because there's no way week will be zero again with these values).
tm lastDay = { 0 };
lastDay.tm_mday = 31;
lastDay.tm_mon = 11;
lastDay.tm_year = date->tm_year - 1;
// We set time to sometime during the day (midday seems to make sense)
// so that we don't get problems with daylight saving time.
lastDay.tm_hour = 12;
week = GetWeek(&lastDay);
}
// B) If calculated week is 53, then we need to determine if there really are 53 weeks in current year
// or if this is actually week one of the next year.
else if (week == 53)
{
// We need to find out if there really are 53 weeks in this year,
// There must be 53 weeks in the year if:
// a) it ends on Thurs (year also starts on Thurs, or Wed on leap year).
// b) it ends on Friday and starts on Thurs (a leap year).
// In order not to call mktime again, we can work this out from what we already know!
int lastDay = date->tm_wday + 31 - date->tm_mday;
if (lastDay == 5) // Last day of the year is Friday
{
// How many days in the year?
int daysInYear = date->tm_yday + 32 - date->tm_mday; // add 32 because yday is 0 to 365
if (daysInYear < 366)
{
// If 365 days in year, then the year started on Friday
// so there are only 52 weeks, and this is week one of next year.
week = 1;
}
}
else if (lastDay != 4) // Last day is NOT Thursday
{
// This must be the first week of next year
week = 1;
}
// Otherwise we really have 53 weeks!
}
return week;
}
int getw( int day, int month , int year)
{
tm date = { 0 };
date.tm_mday = day;
date.tm_mon = month - 1;
date.tm_year = year - 1900;
// We set time to sometime during the day (midday seems to make sense)
// so that we don't get problems with daylight saving time.
date.tm_hour = 12;
return GetWeek(&date);
}
int main( )
{
printf( "= %d =\n", getw(15,5,2013) );
}
Use %U, %V or %W - they have different meanings. The man page has details.
Thank you very much for finding the correct reference! I knew there should've been a C library function over the command line one, just couldn't find it. And yes, I would start with the code from these functions versus invent something new.
"it does not work" is not helpful. What is it doing wrong? Which corner cases is it succeeding/failing on? Have you done any debugging? Can you explain the problem?
Last edited by suicidaleggroll; 05-19-2017 at 09:45 AM.
I'd start with 'struct tm', fields 'tm_wday' and 'tm_yday'; from those, you can find out the d.o.w. on 1st January, then the d.o.y. of the first Sunday.
Code:
int wdayJan1= (tm.tm_wday - tm.tm_yday)%7;
if (wdayJan1<0) wdayJan1 += 7;
int ydayFirstSunday = (7 - wdayJan1)%7;
if (tm.tm_yday < ydayFirstSunday) {
printf ("Last week of previous year\n");
} else {
int week_of_year= (tm.tm_yday - ydayFirstSunday)/7; /* 0-based: 0..52 */
printf ("It's the #%d week of this year (zero-based)\n", week_of_year);
}
Guttorm's answer seems the right one, strftime(...). You already have the struct tm so a single call to strftime (hint: %U) will give the desired printf-ready result.
A call to time(NULL) will return a time_t, and that can be passed to localtime( &myTime_t ), which will return a struct containing a tm_yday (day of the year). Simple division by 7 computes the week of the year.
Distribution: Debian Sid AMD64, Raspbian Wheezy, various VMs
Posts: 7,680
Rep:
Are you taking a course in programing?
If so, you ought to come up with this yourself and, if not, it's this is part of most foundation programing courses.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.