Running this code should yield the Arabic representation of current month and it does on my local machine, however when running on server I always get English.
new CultureInfo("ar").DateTimeFormat.AbbreviatedMonthNames[System.DateTime.Now.Month]
At first I suspected it has something to do with request localization hence I tried to just new up a new culture info and see what it outputs, so the above code returns English regardless.
Set of supported cultures is OS specific - you get different sets even between flavors of Windows - desktop and server editions are different, generally with server having less supported cultures. Also the older version of Windows you use smaller list of cultures is supported. The same applies to running .NET core on other OS (including Linux in Kubernetes containers) - it's OS that essentially drives list of supported cultures.
Note that some OS (Windows 10 in particular) will happily provide you with "culture info" for any string you pass - it will try the best to construct something that may make sense (i.e. for "ru-GB" it may try to give "en-GB" culture as the closest one), but for something that has no information whatsoever you likely get invariant/neutral culture (which generally resembles en-US).
Related
I'm having an issue when using CultureInfo.
This is basically my code:
Console.WriteLine(0.5.ToString("P2", new CultureInfo("en-US")));
When running it, this is what I get on two different computers:
As you can notice, the formatting isn't the same. The Australia VPS ( running Windows Server 2016) having a space before the percent symbol compared to my computer (Windows 10).
Why that? How can I "really" use the same CultureInfo/formatting everywhere?
The CultureInfo on Windows uses machine/user level locale information and does not have any information on its own. This information is updated relatively frequently by OS versions and updates. As result machines with different levels of patches or different versions of OS will likely have differences, usually minor as you see but sometime critical if something like decimal separator changes between '.' and ',' or currency symbol for a region changes.
Usually it is not a problem as such formatting is used only to show/parse values from the user and not to store data anywhere (which uses InvariantCulture). Most individual users would not ever use enough machines to notice difference in desktop apps. And for server side code (i.e. ASP.Net) running multiple servers with different versions of OS is even less likely.
If you really must show identical formats independent of OS you would have to build your own CultureInfo objects for locales you interested in. In many cases you can just create your own CultureInfo based on existing one and just patch properties you care about.
On my machine when I run and output the following
string locale = "nb-NO";
CultureInfo culture = CultureInfo.CreateSpecificCulture(locale);
string shortDateFormatString = culture.DateTimeFormat.ShortDatePattern;
string shortTimeFormatString = culture.DateTimeFormat.ShortTimePattern;
I got the following output
shortDateFormatString "dd.MM.yyyy"
ShortTimePattern "HH:mm"
But on dotnetfiddle.net I got the following
shortDateFormatString "dd.MM.yyyy"
ShortTimePattern "HH.mm"
I suppose C# uses CLDR, so according to
https://github.com/unicode-cldr/cldr-dates-full/blob/1af902b749bef761f07281f80241250053b4313d/main/nb/ca-gregorian.json#L323
Both short time pattern should be valid.
And on dotnetfiddle it is possible to parse nb-NO datetime looking as following
06.12.2017 12:34
06.12.2017 12.34
However in VS2019 on my machine it is only possible to parse
06.12.2017 12:34
How is it possible it is different? both is using .NET 4.7.2.
You can check my fiddle here https://dotnetfiddle.net/68DDYz
How is it possible it is different?
Because culture information is loaded from the operating system, and changes over time. Unless two machines are on the exact same version of Windows (same set of updates, hotfixes etc), it's entirely possible for them to have different values for things like short time patterns. (And yes, that's annoying, but it's part of life.)
Jon is quite right (duh!)
Culture settings are tricky. Since they are stored on the windows registry, they can be different/change over .net framework versions, operating system versions, windows updates, hotfixes etc. That means even if both server uses same .NET Framework version, that doesn't mean that every culture settings will be same for both.
I can show you the it-IT culture for example.
See: .NET (3.5) formats times using dots instead of colons as TimeSeparator for it-IT culture?
For .NET Framework 3.5, it-IT culture has . as a TimeSeparator but with .NET Framework 4.0 version, it changed to : which is stated on Wikipedia.
This changes are not end of the world of course, but it was not pleasant either.
I was wondering about the difference between \ and / in file paths. I have noticed that sometimes a path contains /and sometimes it is with \.
It would be great if anyone can explain when to use \ and /.
/ is the path separator on Unix and Unix-like systems. Modern Windows can generally use both \ and / interchangeably for filepaths, but Microsoft has advocated for the use of \ as the path separator for decades.
This is done for historical reasons that date as far back as the 1970s, predating Windows by over a decade. In the beginning, MS-DOS (the foundation to early Windows) didn't support directories. Unix had directory support using the / character since the beginning. However, when directories were added in MS-DOS 2.0, Microsoft and IBM were already using the / character for command switches, and because of DOS's lightweight parser (descended from QDOS, designed to run on lower end hardware), they couldn't find a feasible way to use the / character without breaking compatibility with their existing applications.
So, to avoid errors about "missing a switch" or "invalid switch" when passing filepaths as arguments to commands such as these:
cd/ <---- no switch specified
dir folder1/folder2 <---- /folder2 is not a switch for dir
it was decided that the \ character would be used instead, so you could write those commands like this
cd\
dir folder1\folder2
without error.
Later, Microsoft and IBM collaborated on an operating system unrelated to DOS called OS/2. OS/2 had the ability to use both separators, probably to attract more Unix developers. When Microsoft and IBM parted ways in 1990, Microsoft took what code they had and created Windows NT, on which all modern versions of Windows are based, carrying this separator agnosticism with it.
As backward compatibility has been the name of the game for Microsoft from all of the major OS transitions that they've undertaken (DOS to Win16/DOS, to Win16/Win32, to Win32/WinNT), this peculiarity stuck, and it will probably exist for a while yet.
It's for this reason that this discrepancy exists. It should really have no effect on what you're doing because, like I said, the WinAPI can generally use them interchangeably. However, 3rd party applications will probably break if you pass a / when they expect a \ between directory names. If you're using Windows, stick with \. If you're using Unix or URIs (which have their foundation in Unix paths, but that's another story entirely), then use /.
In the context of C#: It should be noted, since this is technically a C# question, that if you want to write more "portable" C# code that works on both Unix and Windows (even if C# is predominantly a Windows language), you might want to use the Path.DirectorySeparatorChar field so your code uses the preferred separator on that system, and use Path.Combine() to append paths properly.
MS-DOS 1.0 retained the command line option (or switch) character convention of '/' from CP/M. At that time there was no directory structure in the file system and no conflict.
When Microsoft developed the more Unix like environment with MS-DOS (and PC-DOS) 2.0, they needed to represent the path separator using something that did not conflict with existing command line options. Internally, the system works equally well with either '/' or '\'. The command processor (and many applications) continued to use the '/' as a switch character.
A CONFIG.SYS entry SWITCHAR=- could be used to override the / default to improve Unix compatibility. This makes built in commands and standard utilities use the alternate character. The Unix path separator could then be unambiguously used for file and directory names. This entry was removed in later versions, but a DOS call was documented to set the value after booting.
This was little used and most third-party tools remained unchanged. The confusion persists. Many ports of Unix tools retain the '-' switch character while some support both conventions.
The follow-on PowerShell command processor implements rigorous escaping and switch parameters and largely avoids the confusion except where legacy tools are used.
Neither the question nor the answer relate to C#.
A URL, standardized in RFC 1738, always uses forward slashes,
regardless of platform.
A file path and a URI are different. \ is correct in a Windows file
path and / is correct in a URI.
Several browsers (namely, Firefox & Opera) fail catastrophically when
encountering URIs with backslashes.
System.IO.Path.DirectorySeparatorChar to get current path separator
This can be relevant resource.
On Unix-based systems \ is an escape character, that is, \ tells the parser that this is a space and not the end of the statement. On Unix systems / is the directory separator.
On Windows \ is the directory separator, but the / cannot be used in file or directory names.
You shouldn't be using either in C#. You should always use the Path class. This contains a method called Path.Combine that can be used to create paths without specifying the separator yourself.
Example usage:
string fullPath = System.IO.Path.Combine("C:", "Folder1", "Folder2", "file.txt");
Apart from the answers given, it is worth mentioning that \ is widely used for special characters (such as \n \t) in programming languages, text editors and general systems that apply lexical analysis.
If you are programming for instance, it is inconvenient at times to need to even need to escape backslash with another one (\\) in order to use it properly - or need to use escaping strings, such as C# #"\test".
Of course, as mentioned before, web URIs use forward slash by standard but both slashes work in the latest and most common command line tools.
UPDATE: After searching a little bit, it seems out the whole story between / and \ goes back in "computer history", in the ages of DOS and the Unix-based systems at that time. HowToGeek has an interesting article about this story.
In short terms, DOS 1.0 was initially released by IBM with no directory support, and / was used for another ("switching") command functionality. When directories were introduced in 2.0 version, / was already in use, so IBM chose the visually closest symbol, which was \. On the other hand, Unix standardly used / for directories.
When users started to use many different systems, they started becoming confused, making the OS developers to attempt making the systems work in both cases - this even applies in the part of URLs, as some browsers support the http:\\www.test.com\go format. This had drawbacks though in general, but the whole thing stands today still for backward compartibility causes, with an attempt for support of both slashes on Windows, even though they are not based on DOS anymore.
\ is used for Windows local file paths and network paths as in:
C:\Windows\Temp\ or \\NetworkSharedDisk\Documents\Archive\
/ is what is required by standard URIs as in:
http://www.stackoverflow.com/
Hi guys my problem is this. I made a software in c# that is able to read and edit dxf files, I have to give this software to an american company but I have discovered the following problem:
Where I live we use the ',' to separate the integer part from the decimal part of the number (for example: 2,3658) but in the USA they use the '.' so they write 2.3658.
When I try to read the string "2.3658" and convert it into a double with "Double.Parse("2.3658")" the double I get is 23658 like the method "Parse()" didn't recognised the decimal part.
I have found the following solution:
UpdatedCoorx = double.Parse(shiftedE[w + 1] ,NumberStyles.Number,CultureInfo.CreateSpecificCulture ("en-US"));
Using CultureInfo.CreateSpecificCulture ("en-US") the c# can read the numbers correctly.
My question is : is there a way that make c# automatically recognised the "Culture" of the pc where is installed so that it can read the number correctly???
is there a way that make c# automatically recognised the "Culture" of the pc where is installed so that it can read the number correctly?
That's what it's doing by default - and why you're having a problem, because the culture used to created of the value you're parsing ("2.3658") isn't the culture on your local machine.
For any particular value, you should really know which culture produced it. For machine-to-machine communication, it's best to use the invariant culture (CultureInfo.Invariant) which is mostly similar to the US. Ideally, you shouldn't store values in a culture-specific format at all; either store them in a binary representation instead of a string, or if you must store a string, treat that as effectively machine-to-machine communication.
If you're in the unfortunate position of receiving data where you know it's been formatted according to some human culture, but you don't know which one, you should probably use some heuristics to detect what the culture is. That can easily fail though - for example, is "1,234" meant to be a 1 followed by a "grouping" separator, followed by 234 - meaning one thousand, two hundred and thirty-four... or is it meant to be a 1 followed by a decimal separator, making the value just a bit more than 1? Both interpretations are valid, depending on the culture you use...
If you want to detect the Culture, you should be able to do so with this
As explained in the link CultureInfo.CurrentCulture returns the Culture from the Windows GetUserDefaultLocaleName function.
Jon's answer is pretty spot on (as usual). I just wanted to add that if you are developing an application that will be used by people in another country, it may be helpful for you to use CultureInfo.DefaultThreadCurrentUICulture while you are in development mode: just assign your users' culture to this property when the application starts, and you will have exactly the same usage experience (culture-related-things-wise) that your users will have. (Just remember to remove this when you ship your application! You could for example use a #if debug block)
Given that (at least on NTFS) the filesystem on Windows is case insensitive, I would like to compare String fileA to String fileB as such:
fileA.Equals(fileB, StringComparison.CurrentCultureIgnoreCase)
The question then becomes which culture I should use, does the default current (ui?) culture suffice? I can't seem to find any BCL methods for this purpose.
You should use StringComparison.OrdinalIgnoreCase, according to Best Practices for Using Strings in the .NET Framework.
The string behavior of the file system, registry keys and values, and environment variables is best represented by StringComparison.OrdinalIgnoreCase.
If you use a culture for matching the strings, you may get in a sitation where for example the names "häl.gif" and "hal.gif" would be considered a match.
This is not possible to do reliably.
Yes, the case conversion for the file system is case-insensitive.
But the case conversion table is stored on the file system itself (for NTFS), and it does change between versions (for instance the Vista case conversion table was brought to the Unicode 5 level, so Vista NTFS and XP NTFS have different case conversion rules).
And the thing that matters is the OS that formatted the file system, not the current OS.
Then you can run into all kind of problems with other file systems (Mac OS does some kind of Unicode normalization (not the standard one)), Linux does not do anything, but Samba (implementing the Windows file sharing protocol) does. And has other tables than Windows.
So what happens if I map a letter to a network disk shared by Linux or Mac OS?
In general you should never try to compare file names. If you want to know if it is there, try to access it.
Marcus,
You might want to at look at the answer for another StackOverflow question, which is very similar: Win32 File Name Comparison , which in turn mentions http://www.siao2.com/2005/10/17/481600.aspx .
Following a link in another answer to the same question and digging further, I came across the following MSDN article http://msdn.microsoft.com/en-us/library/ms973919.aspx . It is worth a read in general, but when it comes to file name comparison it recommends using StringComparison.OrdinalIgnoreCase. See Table 1 in the article, which contains file paths as one of the data types handled or the following the quote:
So, when interpreting file names, cookies, or anything else where something like the å combination can appear, ordinal comparisons still offer the most transparent and fitting behavior.
Hopes this helps,
Boaz
Maybe you could try this:
http://msdn.microsoft.com/en-us/library/zkcaxw5y.aspx
You could use InvariantCulture (look at http://msdn.microsoft.com/en-us/library/4c5zdc6a.aspx).
In your example:
FileA.Equals(FileB,StringComparison.InvariantCultureIgnoreCase )
I tried this.
Path.GetFullPath(path1).Equals(Path.GetFullPath(path2))