LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-19-2017, 06:59 AM   #1
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,657

Rep: Reputation: 255Reputation: 255Reputation: 255
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) );

}
 
Old 05-19-2017, 07:50 AM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
The date(1) command does this with the %U option.

First place I would look is the source for that command under the gnu coreutils.
 
Old 05-19-2017, 07:51 AM   #3
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
google says

https://cboard.cprogramming.com/c-pr...mber-year.html
 
Old 05-19-2017, 07:56 AM   #4
Guttorm
Senior Member
 
Registered: Dec 2003
Location: Trondheim, Norway
Distribution: Debian and Ubuntu
Posts: 1,453

Rep: Reputation: 447Reputation: 447Reputation: 447Reputation: 447Reputation: 447
It's easier with strftime.

http://man7.org/linux/man-pages/man3/strftime.3.html

Use %U, %V or %W - they have different meanings. The man page has details.
 
1 members found this post helpful.
Old 05-19-2017, 08:03 AM   #5
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by Guttorm View Post
It's easier with strftime.

http://man7.org/linux/man-pages/man3/strftime.3.html

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.
 
Old 05-19-2017, 09:44 AM   #6
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
"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.
 
1 members found this post helpful.
Old 05-19-2017, 12:23 PM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
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);
    }

Last edited by NevemTeve; 05-19-2017 at 02:09 PM.
 
Old 05-19-2017, 01:36 PM   #8
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,264
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
Quote:
Originally Posted by Xeratul View Post
it does not work.
That is not a useful problem description.

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.

Last edited by astrogeek; 05-19-2017 at 01:37 PM.
 
Old 05-24-2017, 12:57 PM   #9
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
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.
Code:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char * argv[] ){
time_t  t;
        t = time( NULL );
        printf( "%d", ( localtime( &t )->tm_yday )/7 );
        exit( 0 );
}

Last edited by theNbomr; 05-24-2017 at 01:03 PM.
 
Old 05-24-2017, 01:07 PM   #10
273
LQ Addict
 
Registered: Dec 2011
Location: UK
Distribution: Debian Sid AMD64, Raspbian Wheezy, various VMs
Posts: 7,680

Rep: Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373Reputation: 2373
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.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
help with calendar with only week number ANU Programming 1 04-27-2012 08:24 AM
any lang: week number ezekieldas Programming 13 03-30-2012 03:50 PM
Beginning C programming- how to print memory locations? printf conversion number? keithostertag Programming 5 02-03-2012 10:03 AM
LQ-er of the day/week/month/year? alan_ri LQ Suggestions & Feedback 0 01-24-2009 05:11 PM
The joke of the week. (Or, maybe, the year?) z-vet General 15 12-04-2004 08:05 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration