I have a date on the format YWWD, where:
Y=year
WW=week number of year
D=day of week
Anyone have a clue on how to convert this to a regular date(CCYY-MM-DD)?
Can't find any functions for this in C..?
I have a date on the format YWWD, where:
Y=year
WW=week number of year
D=day of week
Anyone have a clue on how to convert this to a regular date(CCYY-MM-DD)?
Can't find any functions for this in C..?
Convert the original format into a unix timestamp, ie seconds since 1970, Then use the C standard time.h functions to convert it into the new format.
ie
Or somethingCode:SECONDSINAYEAR=365.25 * (24 * pow(60, 2)) SECONDSINAWEEK=7 * (24 * pow(60, 2)) year = 2000 ww = 24 d = 5 yearOffset = year - 1970 // etc for weeks / days secondsSinceEpoch = (yearsOffset * SECONDSINAYEAR) + (weekOffset * SECONDSINAWEEK)
Last edited by zacs7; 10-12-2007 at 04:50 AM.
How do i converet 7403(2007, week number 40, wednesday) to a unix time?
Edit:
Some years start with week number 53
Or to put it another way:
How do i get the week number of 01. january of a year?
Last edited by knutso; 10-12-2007 at 05:03 AM.
Here's a good start, Note it uses the leap year approximation method see http://en.wikipedia.org/wiki/Leap_year
All you have to do is make it pretty, add weeks and days then do whatever with the timestamp.Code:time_t makeTimestamp(int year, int week, int day) { time_t secs = 0; int daysPerYear = 365; /* if it's a leap year give it 366 days */ if(isLeapYear(year) != 0) daysPerYear = 366; /* add the years in seconds from 1970 */ secs += (year - 1970) * (daysPerYear * (24 * (60 * 60))); /* add the weeks, etc */ return secs; } /* returns non-zero if the year is a leap year */ int isLeapYear(int year) { if(year % 400 == 0 || year % 4 == 0) return 0; /* leap */ else if(year % 100 == 0) return 1; /* not a leap */ return 2; }
If the week is 47 then it'll be,
Or something, I don't know -- I don't like timeCode:weeksInDays = 47 * 7 daysSinceStartOfYear = weeksInDays - (7 - dayOfWeek)
Last edited by zacs7; 10-12-2007 at 05:10 AM.
OK, so the first question is "what is the definition of a workweek". You need to know which week is "week 1" and at what date that week starts, since, as you say, some years end with a week 53 that overlaps into the next year.
Once you know which date week one starts, you then add the number of days that your 40 weeks (40 * 7 = 280 days), combined with the day within the week.
Add the number of days to the "start of week 1 date", and you've got a date.
Since UNIX time is "seconds since 1 Jan 1970", you multiply the number of days by 24 * 60 * 60 and you get the number of seconds into the year.
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Well I was sortof on track
So is there a function like: weeknumber('2007.01.01');?
I'm not aware of a "commonly available" one like that. It's not helped much by different countries having different definitions of "week number".
I wrote something to solve this a long time ago, which works out the day of December 31st of previous year, (because if it's before wednesday, the first week is week 53, otherwise week 1), then calculates the week number by calculating number of days between week 1 and the "wanted" date. This was quite a while ago, and I had a quick look to see if I could find it, but I wasn't able to find it right now... [It would be in Pascal anyways, so you would have to convert the algorithm to C].
Edit: Found it!
Edit2: That is missing a few crucial functions. The CalcDayNum() is basicily a integer representing the number of days from a set date (such as 1 Jan 1970). Likewise, we need a function to figure out what day of the week a certain date is - there's a post recently that does that, or you can use the standard C time functions to get the day of week from a "time_t" type.Code:FUNCTION WeekNumber{date: String[h]): WORD}; VAR day, month, year: WORD; firstOf: INTEGER; dayNum: INTEGER; dayIntoYear: INTEGER; firstMonday: INTEGER; FUNCTION FirstMondayInYear(y: WORD): INTEGER; (* This calculates the Monday of Week 1 of the year we are interested in, which actually may be the in the previous year, since that week may begin in December. *) VAR x: INTEGER; d: WORD; step: INTEGER; BEGIN x := CalcDayNum(y, 1, 1); d := WeekDayNum(x); IF d < Thursday THEN step := -1 ELSE step := 1; WHILE d <> Monday DO BEGIN x := x + step; d := WeekDayNum(x); END; FirstMondayInYear := x; END; FUNCTION CalcWeekNumber(year, month, day: WORD): WORD; BEGIN firstMonday := FirstMondayInYear(year); firstOf := CalcDayNum(year, 1, 1); dayNum := CalcDayNum(year, month, day); IF dayNum < firstMonday THEN CalcWeekNumber := CalcWeekNumber(year-1, 12, 31) ELSE BEGIN IF dayNum >= FirstMondayInYear(year+1) THEN CalcWeekNumber := CalcWeekNumber(year+1, 1, 1) ELSE CalcWeekNumber := (dayNum - firstMonday) DIV 7 + 1; END; END; BEGIN SplitDate(date, year, month, day); WeekNumber := CalcWeekNumber(year, month, day); END;
--
Mats
Last edited by matsp; 10-12-2007 at 05:59 AM.
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Thanks to you both! I'll have a look at the code.
I hope you've got a number of sample input dates and their correct outputs to use as test cases. This is something that would very much bennefit from having some unit tests, and it would be very easy to test also.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Make sure you pick some weird dates in that case, such as 29Feb on a leap year, or some other weird ones.
Where on earth did you find such a weird date format anyways?
I've seen strange date formatting on mainframes, but that one definitely takes the cake!
The date format is from a lotnumber in a barcode, hence it has to be as short as possible.
I converted the functions to c, but i'm not entirely finished yet..I'll post it here when it's finished?
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Or they could use a 4 digit hex number that represents the number of days since 1970 -- that should be good until around the year 2149.In that case, I don't know why they didn't simply replace WWD with the 3-digit number for the day of the year since it's the same length.