tags:

views:

85

answers:

2

I have the current week as an integer (43 as of now). I need the date for Monday in a format like 'Mon Oct 25'.

Thought I could accomplish that by a function from but I don't know how to do that. Any suggestions?

EDIT: I tried the suggestion from R., but it doesn't give the expected result. Did I implement it wrong?

time_t monday;
char date_format[32];
time_t now = time(NULL);
struct tm *tm = localtime(&now);

tm->tm_yday = 0; // reset to Jan 1st
tm->tm_hour = 24 * 7 * WEEK + 24; // goto Sun and add 24h for Mon

monday = mktime(tm);

strftime(date_format, 31, "%a : %D", tm);

printf("%s\n", date_format);
+2  A: 

Note: Not tested, but given the current year, this should do it:

const char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep",
                        "Oct","Nov","dec","Jan"};
/* Start with January 1st of the current year */
struct tm curYear={
  0, // secs
  0, // mins
  0, // hours
  1, // Day of month
  0, // Month (Jan)
  year,
  0, // wday
  0, // yday
  0}; // isdst

/* Offset the number of weeks specified */
time_t secsSinceEpoch=mktime(&curYear)+
                      weekNum*86400*7; /* Shift by number of weeks */
struct tm *candidateDate=gmtime(&secsSinceEpoch);

/* If the candidate date is not a Monday, shift it so that it is */
if (candidateDate->tm_wday!=1)
{
  secsSinceEpoch+=(86400*(candidateDate->tm_wday-1)); 
  candidateDate=gmtime(&secsSinceEpoch);
}

printf("Mon %s %d",months[candidateDate->tm_mon],candidateDate->tm_mday\n");

You may have to adjust the formulas in this code depending on what exactly you mean by week 43 of a given year or to conform with ISO-8601, for example. However, this should present you with good boiler plate code to get started. You may also want to parameterize the day of the week, so that it is not hard coded.

Also, if you want, you can avoid the months array and having to format the time, by truncating the result of the ctime function, which just so happens to display more than you asked for. You would pass to it a pointer to the secsSinceEpoch value and truncate its output to just display the day of the week, the day of the month and the abbreviation of the months name.

Michael Goldshteyn
You're making it too difficult. See my answer.
R..
What is wrong with using strftime() here?
Clifford
@Michael, you're really good at writing code without testing it :) I only needed to change the array length to 13 and decrement the weeknumber by one. Then I get 'Mon Oct 25' which is absolutely correct.
ClosedID
Thanks for the complement. For what it's worth, I did go over the code mentally some five times trying to make sure that no bugs snuck in. But, ultimately, the only way to ensure that any piece of code works is to test it.
Michael Goldshteyn
+2  A: 

The mktime function can do this. Simply initialize struct tm foo to represent the first day of the year (or first day of the first week of the year, as needed), then set tm_hour to 24*7*weeknum and call mktime. It will normalize the date for you.

R..
Is this behavior compiler specific or part of the C standard?
Michael Goldshteyn
@Michael: the standard says that the initial values can be out of range, and that they are "forced" into range. It doesn't say how they're forced (at least, not in 7.23.2.3/2 of C99), so possibly you could argue the standard doesn't require it, but I think the intention is that time overflow calculations are done. @R. Do you have to set the time to (e.g.) midday on the first day, rather than midnight, to avoid being out by one day due to daylight savings?
Steve Jessop
That's a nifty solution but I can't get it to work as expected. I added the suggested code to my original post. It prints 'Sun : 08/28/11' for current week 43. Someone sees the error?
ClosedID
You implemented it wrong. Don't call `localtime` then set `tm_yday` - this won't work since `tm_yday` is a derived value that can't override others. Instead make the whole `struct tm` from scratch, or else call `localtime` then zero out all the time/day elements (just leaving the year) before doing the procedure in my answer.
R..