https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #8 from Chuck R chuck.the.pc.guy+winehq@gmail.com --- My patch has the functional parts of %G, %u, and %V, just needs tests. Yeah, it was annoying to get the math right on that one.
In the patch I submitted above, I had to use a calls to MSVCRT_mktime and MSVCRT_gmtime (saving the buffer beforehand so as not to clobber what's in there already since they use an internal buffer).
But, here's a quick rundown of %V (parts of which are used in %u and %G):
NOTE: Jan 4 is always in the first week of the ISO year (source: https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar_text_2.htm)
1. The week number is calculated like this:
d = ISO8601 Day of the Week (1 is Monday, 7 is Sunday) o = ordinal day (straight from tm.tm_yday -- I had to convert the given time in mstm to an epoch and back to a tm in order to assure that tm.tm_yday was populated as it may or may not be populated in mstm)
week number = ((o + 1) - d + 10) / 7 (source: https://en.wikipedia.org/wiki/ISO_week_date#Calculation)
If the week number is 0, this means that the day belongs to the last week of the previous year. But, since ISO years can be 52 or 53 weeks long, you have to calculate that value by subtracting one week from Jan 4 of the year given in mstm and re-calculating its week number.
If the week number is 53, this means that either it belongs to week 53 of that year, or week 1 of the next year. The best way to find this is to get the epoch of January 4th of the next year (guaranteed to be in week 1), subtract until Monday (the first day of the first week) and then check that date against mstm. If mstm >= monday, the week number is 1, otherwise it's 53. In my patch, 604800 = 1 week in seconds, 86400 = 1 day in seconds.
The math in the patch I gave you does line up with output from a sample program in Visual Studio 2010 -- at least from 01-01-2013 until now.
The middle week numbers were the easy part. The hard part was tweaking the beginning and ends of the year. I can't tell you how many times I had to recompile and recheck to verify it! I'm surprised I didn't kill my SSD, honestly.