elixir-ecto / tds

TDS Driver for Elixir
https://hexdocs.pm/tds/
Apache License 2.0
116 stars 77 forks source link

date format dependency on default language #1

Closed swsch closed 9 years ago

swsch commented 9 years ago

I added a user with default language German and ran the tests:

2) test Decode Fixed Length Data types (QueryTest)
     test/query_test.exs:21
     match (=) failed
     code: [{1, false, 12, 100, {{2014, 10, 1}, {12, 30, 0}}, 5.2, -40532.5367, {{2014, 1, 11}, {11, 34, 25}}, 5.6, 6.3452, 1000}] = query("SELECT TOP(1) * FROM FixedLength", [])
     rhs:  [{1, false, 12, 100, {{2014, 1, 10}, {12, 30, 0}}, 5.2, -40532.5367, {{2014, 11, 1}, {11, 34, 25}}, 5.6,
             6.3452, 1000}]
     stacktrace:
       test/query_test.exs:38

After changing the user's default language to English, the test succeeded. Another workaround was to use a "T" between date and time in the insert query:

query("INSERT INTO FixedLength VALUES(1, 0, 12, 100, '2014-10-01T12:30:00', 5.2, '$-40,532.5367', '2014-01-11T11:34:25', 5.6, '$6.3452', 1000)", []);

This makes MSSQL believe that the string is ISO8601 formatted which fixes the sequence to y-m-d independent of language and DATEFORMAT.

mobileoverlord commented 9 years ago

The issue I see is that the term is being inserted inline using the sql batch query. The driver adopts a standard when using the parameterized query syntax by calling query/3 with %Tds.Parameter{} as the 3rd argument. Dates in the value of the param will be interpreted as {{year, month, day},{hour, minute, second, microseconds}}. If you are using sql DateTime, passing 0 for microseconds will encode. You can also specify the type for the param to :datetime or :datetim2 depending on how you want to store it.

Date and time are encoded to the correct positions using this protocol for tds (rpc). Let me know if this helps.

swsch commented 9 years ago

The main problem is that the test suite is depending on a server side setting that is not stated as prerequisite anywhere. So the tests in the repo failed unless I changed either the literal date string or the user's default language.

You can avoid having others run into this problem by either requesting an "English" user or by forcing the datetime encoder to use locale-independent algorithm by using "T" between date and time.

mobileoverlord commented 9 years ago

Ah. I guess it would be better to adjust the date time tests in query then. Can you do a PR with the fix for the tests that are broken? :) thanks