C# - Oracle Dates Different on Desktop vs Server - c#

I'm running windows 10 and recently updated my MVC app from 32 bit to 64 bit, including the Oracle client.
I installed ODAC1931_x64 on my machine and am using this nuget:
https://www.nuget.org/packages/Oracle.ManagedDataAccess/
When I run the app on my desktop, everything works fine. I can pass dates to my DB packages like so:
comm.Parameters.Add(Constants.DATABASE_PARAMETERS.FIELDS.START_DATE, OracleDbType.Date).Value = startDate;
And in the DB package the date come through as:
25-NOV-20
I installed the same ODAC on the server, Windows 2016, and moved my app to it. But when I run it, the date is showing up on the DB as:
20-11-25
And now the DB package is throwing the error:
ORA-01858: a non-numeric character was found where a numeric was expected
This did not happen when I was on 32 bit Oracle, the date came through as 25-NOV-20, it only happens with the 64 bit client and only on the server, not my desktop.
Any idea how to fix this?

You are relying on implicit date conversion in order to display it and enter it as a string. You need to use conversion functions with explicit date formats in order to be safe.
Eg. to_char(my_date_column,'dd/mm/yyyy hh24:mi:ss') if you want to display a date as a string
to_date('25/11/2020 21:00:00','hh24:mi:ss') if you have a string and want to set a date column.
Remember 2 digit years are why every software engineer worked around the clock coming up to the year 2000. Always use 4 digits.

Related

Input string was not in a correct format on Convert.ToDouble("Infinity")

Why would the following fail with a System.FormatException on 64-bit Windows 10, but runs fine on 32-bit Windows 7? Both machines have .NET Framework 4.6.1 installed.
Convert.ToDouble("Infinity");
I have searched and cannot find an answer to this.
The string used for Infinity is culture specific and may have even had different values between Win 7 & 10 (can't confirm that at the moment).
Try using the constant instead of hard coding a string:
Convert.ToDouble(NumberFormatInfo.PositiveInfinitySymbol);

Why might my local machine be incorrectly formatting international dates?

Here's a weird one...
I've just seen a (previously passing) test fail because of extra spaces in a string representation of a date. The test in question has previously passed in CI and on my local machine, but is now failing (on my local machine) because of extra spaces between segments of the date.
The same behaviour is exhibited by the following MCVE:
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
var date = new DateTime(2018, 01, 31);
var format = "d/M/yyyy";
var skSK = new CultureInfo("sk-SK");
Console.WriteLine(date.ToString(format, skSK));
}
}
In most places (including .NET Fiddle) this correctly returns:
31.1.2018
But on my machine, I now get:
31. 1. 2018
Note the extra spaces!
I'm confident that this was working as expected on my local PC just earlier this week, as I was using the project with this test in as a starting point for some experimentation with coverage tools. When I've resumed that experimentation this afternoon, the coverage file is no longer being produced due to the newly failing test.
What could have changed on my PC to cause this broken behaviour?
In Windows (like many others System), the source for the Locale date/time formats is the Unicode Common Locale Data Repository (CLDR), which provides internationalization and localization support specific for software developers and linguists.
A Short list of meaningful users:
Microsoft (Windows, Office, Visual Studio etc.)
Apple (macOS, iOS, watchOS, tvOS, Apple Mobile Device Support and iTunes for Windows;
Google (Web Search, Chrome, Android, Adwords, Google+, Google Maps, Blogger, Google Analytics)
IBM (DB2, Lotus, Websphere, Tivoli, Rational, AIX, i/OS, z/OS)
Amazon
See the Online data explorer of the Localizations: Locale Explorer.
The Short Date format, localized to the sk-SK culture as d. M. yyyy, is the one listed in this archive. It's the same for all OS (Windows 7 to Window 10).
A MS Developer related blog: Locale Builder and Finnish or other locales.
Fiddler or other Online code-runners services are not a source of comparison on this matter.
Locales are different from system to system. Also, these international formats change over time and depend on the updates that a system receives (if it receives these updates at all).
In Windows 7 and Windows 10, the default Short Date format for the sk-SK Culture is d. M. yyyy.
But the DateTime patterns do not match, if the formats list is parsed further.
string format = CultureInfo.CreateSpecificCulture("sk-SK")
.DateTimeFormat.GetAllDateTimePatterns()[1];
In Windows 7, the second element in the DateTimePatterns list is d.M.yyyy
In Windows 10, the element at the same index is: dddd d. MMMM yyyy
A Windows update may change the default pattern for any of the Locales (without explicit notification).
It's understood that applications must provide parsing means for special cases. Or refer to the user Locale settings when formatting, without trying to force a specific pattern for internal uses.
Date/Time formats should be used for presentation only. The Locale and the user settings determine that format. An user of a System may decide to use a different format than the default Locale.
This GitHub repository holds an updated JSON of the CLDR database:
CLDR Date Modern
Also interesting, the ECMAScript reference for API internationalization:
ECMAScript® 2017 Internationalization API Specification
MSDN latest guidelines for Globalization and localization (UWP related):
Globalization and localization
Globalize your date/time/number formats
Use the Multilingual App Toolkit 4.0
I had the same issue in my Windows 10 machine, got "31. 1. 208". But using:
var format = "d.M.yyyy";
produces: 31.1.2018
it seams to be something with CultureInfo("sk-SK"):
Console.WriteLine(date.ToString("d", new CultureInfo("de-DE")));
produces: 31.01.2018
and
Console.WriteLine(date.ToString("d/M/yyyy", new CultureInfo("de-DE")));
produces: 31.1.2018
(in Windows Control Panel - Region, mine is set as "English - Canada" and short date: "dd/MM/yyyy".
It seems to be defined in the .Net Framework - see the spaces there:
I hope that helps.

.ToShortDateString returning different cultural format than expected

Here's a weird one for you.
We've got a c# interface that's been running since the beginning of the year without problem on a windows XP (32bit) PC. We've just upgraded the PC to windows 7 (64bit) with apps installed by SCCM.
With the latest run the dates in the text area have started appearing in US format (5/2/2014) instead of UK format (02/05/2014).
The code that is being used is:
string Lines = FromFormat.Text + " from " + FromFormat.Charge_From.ToShortDateString() + " to " + FromFormat.Charge_To.ToShortDateString() +".";
Where FromFormat is an object with the source data, Charge_From & Charge_To are DataTime variables.
We've checked the PC's regional settings and created a little test app to display the pc's settings from .Net both of these are set as UK formats
Code for test app:
label1.Text = DateTime.Now.ToString();
label2.Text = DateTime.Now.ToString("dd MMM yyyy");
label3.Text = DateTime.Now.ToShortDateString();
label4.Text = Thread.CurrentThread.CurrentCulture.EnglishName;
I know that I can replace the ToShortDateString() with a ToString("dd/MM/yyyy") to force the correct format but my question is why is this happening?
Is it something to do with the windows 7 upgrade? or the SCCM?
Thanks in advance
ToShortDateString method uses ShortDatePattern property which is identical of "d" standard date and time format of your CurrentCulture.
en-GB culture's ShortDatePattern property is dd/MM/yyyy.
But en-US culture's ShortDatePattern property is M/d/yyyy.
That's why you can't always replace with ToShortDateString and ToString("dd/MM/yyyy"). They are not always the same. And "/" Custom Format Specifier has a special meaning as replace me with the current culture or specified culture's date separator.
I suspect your regional settings changed on your upgrade process and that's why ToShortDateString method generates different results.
But since you didn't tell us your CurrentCulture, we never know what the real problem is..
After much testing and scratching of heads we think we've found an answer to this.
During the testing we noticed that PC’s that had had the interface installed via SCCM (windows 7 only) were producing the US date formatted text but those that were via Click Once directly (predominantly XP) were producing UK date formatted text.
Further testing confirmed that if we installed a Windows 7 PC via Click Once we got UK date formatted text.
Following a lot of confusion, we noticed that when SCCM installed the interface it was installing the RTM version of the Report Viewer but when Click Once was installing the interface the SP1 version of the Report Viewer was installed.
We altered the SCCM to install Report Viewer SP1 and tested a new SCCM installed version of the interface and got UK dates.
Why the version of Report Viewer would affect the culture settings of a PC or how ToShortDateString() works, we have no idea but this appears to be what the issue is.

Language and Locale settings in .NET Framework 4.0

We have a Winform application that gets some numeric values from a database. This works fine when the users version of windows is English. So number formats are all perfect. However when the same application is opened in Windows 7 with Portuguese as the base language (Portuguese-Brazil), the numbers are all formatted wrong. This is because US English and Portuguese formats for numbers are totally different.
It appears this change has occurred recently in .NET Framework 4.0 since the application was working perfectly when it was built using 2.0 Framework.
Example, the number "THOUSAND" will show up as 1.000,00 which is being interpreted as ONE in the system running the Portuguese version of windows.
English: 1,000.00 = Thousand
Portuguese: 1.000,00 = Thousand
Can someone point me to any resources on how to work around this or what is the correct method to force an application to use database values instead of formatting them to the local users' system? The users are OK with numbers being displayed in the US Format.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
this will reset the culture, use it at the start of your form/program
or
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
you can try both as i am not sure which one is gonna work
The format (delimmeters and spaces) of displayed numbers is a matter of their string representation. Decimals are stored in DB or memory without delimeters (obviously), they are just 128bits on your hard disk (roughly saying). The format comes to scope when you try to display them. If your number are stored in DB in correct numeric format, then this should not be a problem.
The problem may occur if somewhere you try to convert a string to number. For instance if you store values in db as string (I hope you dont). In this case you should specify the format provider each time you convert numbers to string and vice versa.
For instance:
decimal.Parse(numberAsString, CultureInfo.InvariantCulture); // 1
decimalNumber.ToString(CultureInfo.InvariantCulture); // 2
reference 1
reference 2

How do I query tables from a Big5 Jet Database on Windows 7 en-US from C#?

I've got a really old Big5 Jet Database that I would like to convert to Unicode and SQLite.
The first step here is to actually open the jet database. Using the C# ADO, and I can enumerate the tables in the Jet DB. They are all garbled, which is expected to me on Windows 7 en-US.
Now, if I simply take those table names and throw them into a simple
select * from "[garbled text]"
the jet database complains how it can't find the table. Similarly, if I attempt to load the jet database into Microsoft Access 2010, it is able to see tables but not query from them.
After hammering on this for a while, I decide to fire up the original host of the database, Windows XP zh-tw, which has Big5/Code Page 950 support.
I throw the exact same failing binary from Windows 7 zh-tw into Windows XP zh-tw. I run the exe and boom, it's able to query the tables no problem.
I'd really like to be able to do this on Windows 7 and I'd also really like to do this without depending on the host culture.
Things I've tried but failed:
Changing the thread culture to zh-tw of the thread that instantiates the jet db objects.
Specifying a locale on the ADO Source string:
Provider=Microsoft.Jet.OLEDB.4.0;Locale Identifier=950;
The jet database also has its own threadpool, but I don't know how to get to those threads to change their culture.
Is there anything I can do to query tables from this database on Windows 7 en-US?
On Windows 7 (any language), you can change system locale:
Region and Language -> Administrative -> Change system locale -> Chinese (Traditional, Taiwan) -> Ok, reboot
I don't know how to change Jet/ADO.NET locale in code, sorry.

Categories

Resources