https://bugs.winehq.org/show_bug.cgi?id=47809
Bug ID: 47809 Summary: mscrt: strftime is missing some substutions Product: Wine Version: unspecified Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: msvcrt Assignee: wine-bugs@winehq.org Reporter: chuck.the.pc.guy+winehq@gmail.com Distribution: ---
I realize that I am using a non-standard config to report this bug, but please read it all the way through.
I first realized this issue when installing a few Lua addons into Elder Scrolls Online (run via Proton because that's the only way I can get it work).
In the process I found that a couple of addons I had added were crashing. After verifying that the issue does not appear in Windows under the same circumstances I opted to have a look.
After a little digging I found that these crashes were due to addon calls to Lua os.date. I dug through the Lua code and found that os.date calls strftime for its results.
The addons that were giving me issues were LibDateTime and LibDebugLogger, which begin their failure due to the following calls:
LibDateTime: os.date("%V", timestamp) LibDebugLogger: os.date("%F %T.%%03.0f %z", timestamp / 1000)
After looking at the code in msvcrt (linked to by crtdll) I can see that there is no implementation of the %V token (which gives the first error). I did fix the second error by using the 3-token substitutions of %F and %T, but I had to substitute both (%F simply isn't implemented, but even expanding %F and leaving %T -- which is implemented -- didn't work either) to get it working.
Cross-referencing the Microsoft docs about the substitutions, I ran across the following missing substitutions:
%C - Century, year dividied by 100 and truncated to integer %D - Same as %m/%d/%y %e - Day of month as decimal, with leaded space if requried %F - Same as %Y-%m-%d %g - Two-digit ISO 8601 week-based year %G - ISO 8601 week-based year %h - Same as %b %n - newline character %R - Same as %H:%M %r - Locale's 12-hour clock time %t - horizontal tab %u - ISO 8601 week day %V - ISO 8601 week number
I'm not sure if %T is working correctly, so I'll have to find some way to test that.
Reference: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strftime-wc...
https://bugs.winehq.org/show_bug.cgi?id=47809
Vijay Kamuju infyquest@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |infyquest@gmail.com
--- Comment #1 from Vijay Kamuju infyquest@gmail.com --- %T is now implemented by commit bfe02fc747611b6f7bb70ae1f2bbba175eb7382d in wine 4.17
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #2 from Vijay Kamuju infyquest@gmail.com --- %R is now implemented by commit 20810377ed6353cc59c4b73149f132178657de80
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #3 from Chuck R chuck.the.pc.guy+winehq@gmail.com --- I've done patches for everything but %r. I've been trying to submit my patch but every time I've gone to do it I have to fix it due to additions.
I admit I am trying to learn how to do the tests at the moment. But I am going to submit my full patch to the mailing list (though, it will still need tests).
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #4 from Chuck R chuck.the.pc.guy+winehq@gmail.com --- Created attachment 65363 --> https://bugs.winehq.org/attachment.cgi?id=65363 Initial patch
My implementation of everything except %r. I can't see the changes that are currently being made, so conflicts will have to be resolved.
Also, I don't know how to write tests as of yet, so I'm trying to figure that one out as well. Help would be appreciated!
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #5 from Chuck R chuck.the.pc.guy+winehq@gmail.com --- Forgot the mention, I saw your _MSVCR_VER test. I'm not sure how to find out which _MSVCR_VER needs to be set for each substitution. There doesn't seem to be any clear indication in the MS docs.
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #6 from Vijay Kamuju infyquest@gmail.com --- I have checked the older msdn documentation online, its not present till year 2015 (msvcr120.dll). Hence all the new options are introduced in msvcr140 and after.
I have sent patches for %D, %F and will send for %h and %C later.
https://bugs.winehq.org/show_bug.cgi?id=47809
--- Comment #7 from Vijay Kamuju infyquest@gmail.com --- Only %G, %u, %V are pending, they may take sometime to implement.
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.
https://bugs.winehq.org/show_bug.cgi?id=47809
Vijay Kamuju infyquest@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Fixed by SHA1| |c6bafaa6d92b78c82be5b955cae | |455f581750a00 Resolution|--- |FIXED
--- Comment #9 from Vijay Kamuju infyquest@gmail.com --- All missing flags are now implemented last one %r implemented by https://source.winehq.org/git/wine.git/commitdiff/c6bafaa6d92b78c82be5b955ca...
https://bugs.winehq.org/show_bug.cgi?id=47809
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #10 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 4.21.