Azure culture-specific month/day formatting different than localhost - c#

I'm running into a very strange issue where the "month/day" standard date format as specified on https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx is rendering differently on my local machine than it is on my azure cloud services and websites.
The culture in this case that is rendering differently is "en-AU". For the date of 2017-05-04 it should render as 4 May and on my local machine it does exactly that. On our website (azure cloud service) and our API (azure website) it renders as May 4. The strange part is that if I use the "short date pattern" it renders as 04/05/2017 on both azure/local. So this seems to be specific only to the "month/day" pattern.
I've tried setting
var culture = new CultureInfo("en-AU");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
and the formatting code is
string.Format(new CultureInfo("en-AU"), "Until {0:M} {0:yyyy}", endDate);
I'm wondering if its possible that the version of some culture definition is different in Azure than it is on my local machine? To my knowledge they are both running .net 4.5. I've added log statements in the code so I can confirm that the culture is set correctly on the line that the code runs, but for some reason, it is just outputting a different value in Azure than it does locally.

I have used both "en-AU" and "en-ZA" culture in both local and Azure environments.Unfortunately,I did not face the issue that you have mentioned in your question in both environments.
It seems the date format that you are getting is US format which might be due to the fact that azure data center that you are using to host your application is based in USA and your date is formatted to that culture.Anyway,give a try to format the date like :
var currentCulture = new CultureInfo("en-AU");
var formattedDate = DateTime.Now.ToString("G",currentCulture);
For the South African culture,try the following:
var currentCulture = new CultureInfo("en-ZA");
var formattedCurrency = currency.ToString("C", currentCulture);
//currency = 100000 then formattedCurrency => R 100 000,00
Good luck ..!!!

Related

Make DateTime.Now Display European Format Globally on Linux

I'm running a .NET Core app which contains DateTime.Now.ToString(). When on my PC it displays European date format (dd/mm/yy) but when running on a Linux VM located in the US it displays American date format (mm/dd/yy) despite the timezone on the VM being GMT.
How can I make it display only European date format?
I know I can format it manually inside the program, but is there a way to do this globally on the Linux system?
To set a culture for all application threads you can use CultureInfo.DefaultThreadCurrentCulture property, like that
if (Thread.CurrentThread.CurrentCulture.Name == "en-US")
{
culture = CultureInfo.CreateSpecificCulture("...");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
You are checking that current culture is en-US and update the default culture to any EU specific culture, like de-DE or fr-FR for example. You can also refer to MSDN for details
You can use below code :
DateTime.Now.ToString("dd/MM/yy")
It should work.
For more info: https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1

DateTime.Parse works in c# console app but not asp.net

I have written a C# console application that after all of it's processing outputs a DateTime to disk. It does this like so:
writer.WriteLine(myDateTime).
This same console appication has no problems with using the following to read this DateTime back:
DateTime.Parse(reader.ReadLine())
However, upon attempting to use the following code in my separate Asp.Net program I recieve an error saying that my string is not a valid DateTime which is odd to say the least.
StreamReader reader = new StreamReader(#"D:\InformerReports\Archive\ReliabilityData\StartTime.hist");
string dateString = reader.ReadLine();
return DateTime.Parse(dateString);
I have checked and the string it is reading in is 10/25/2016 12:00:00 AM.
I have also attempted to use return DateTime.ParseExact(dateString, "dd/MM/yyyy hh:mm:ss tt",null) but this returns the same error.
I can't seem to fathom why identical code performed on the same file works in one case and not the other. I'd appreciate some help.
I guess the culture of the server is different from the machine you are testing from.
The correct format you have to use seems to be:
return DateTime.ParseExact(dateString, "MM/dd/yyyy hh:mm:ss tt", null)
// 10/25/2016 12:00:00 AM
As an add-on to the previous answers.
To avoid the differing cultures across clients you can set the site culture in the global.asax files Application_BeginRequest method like below:
Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-FR");
Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");
This will force the above specified culture for each user accessing the site.
I am not sure if there are drawbacks to doing it this way, but this solved my issue in the past.

Inconsistent DateTime conversion behaviour in .NET Web Service

Problem
I've a Windows app syncs with the Server using SharePoint hosted Web Services.
When the app syncs to the server using LAN (goes through an internal Proxy server) all the DateTime formats are in dd/MM/yyyy format (which is how it is intended to be)
However, when the app syncs over 4G,all DateTime formats are in MM/dd/yyyy format.
This happens for all data inbound and outbound.
Server
Windows Server 2012 with SharePoint 2013 hosting SOAP services
Region: Singapore
Format: English (Singapore)
Client
Windows 10 tablet app
Region: Singapore
Format: English (Singapore)
Other information:
1. It is the same tablet being used on both WiFi and 4G, so we can rule
out 2 tablets having different regional settings.
2. I've verified that the Windows 10 app passes the formats correctly and it is the server that behaves differently over WiFi and 4G.
3. I beleive that the issue is caused by .NET itself and not because of SharePoint. However, I don't want to rule it out as I'm not sure of the actual cause. Please comment if you require any further information if you feel that it is caused because of SharePoint
Snippets:
I've skipped the using statements and SPWeb statements in the snippet to keep it simple. And the LastModifiedTime field in the SPList of type DateTime and not single line text.
Model
public class Record
{
public string ID {get; set}
public string ModifiedDateTime {get; set;} //Don't ask why it is not a DateTime object. It was too late by the time I took over
}
Web Service
public class WebService : IWebService
{
public List<Record> GetUpdates(string lastModifiedTime)
{
SPQuery query= QueryBuilder.GetUpdateQuery(lastModifiedDateTime);
SPList spRecordList = spWeb.Lists["Record"];
SPListItemCollection results = spRecordList.GetItems(query);
List<Record> records = new List<Record>();
foreach(SPListItem spRecord in results)
{
Record record = new Record();
record.ID = spRecord.ID.ToString();
record.ModifiedDateTime = Convert.ToString(spRecord["LastModifiedTime"]);
//1 June 2015 would return as 01/06/2015 in WiFi but 06/01/2015 on 4G
records.Add(record);
}
return records;
}
public Record CreateOrUpdateRecord(Record record)
{
SPListItem spRecord = null;
SPList spRecordList = spWeb.Lists["Record"];
if(string.IsNullOrEmpty(record.ID))
{
spRecord = spRecordList.AddItem();
record.ID = spRecord.ID.ToString();
}
else
{
spRecord = spRecordList.GetItemByID(record.ID);
}
DateTime modified = Convert.ToDateTime(record.Modified);
spRecord["LastModifiedTime"] = modified;
/*
Say ModifiedDateTime is 1 June 2015.
Then on WiFi, modified = 01/06/2015
On 4G, modified = 06/01/2015
*/
return record;
}
}
Now, I've fixed the problem by using format strings when converting between string and DateTime and vice-versa. So more or less, I've got it working for now.
So my question here is, what is the reason behind this behaviour? If possible, please cite links to documentation or references to any other sources that explain this behaviour
Is it possible that the server infers the culture info from the request header? I've always thought that the DateTime.Parse()/Convert.ToDateTime() always got the defaults from the regional settings of the machine it runs on.
First of all, a DateTime does not have any implicit format. It just have date and time values. Format concept only applies when you get it textual (string) representation. I strongly suggest to change this data type from string to DateTime if you can that returns by web service.
I've verified that the Windows 10 app passes the formats correctly and
it is the server that behaves differently over WiFi and 4G
There is no such a thing. Parsing string to DateTime or vice versa does not depends on how you connected to internet. It is all about culture settings.
Since you use it as;
DateTime modified = Convert.ToDateTime(record.Modified);
This code will use CurrentCulture settings by default where it's located. Since you said;
It is the same tablet being used on both WiFi and 4G, so we can rule
out 2 tablets having different regional settings
One regional settings parse your string as a 6 January and the other settings parse your string as 1 June. That's too normal. Looks like one setting uses dd/MM/yyyy format and the other one uses MM/dd/yyyy.
As a solution, you can use DateTime.ParseExact method to specify exact culture that matches with your string. Or you can equalize regional settings on both tablet.
For example;
DateTime dt = DateTime.ParseExact("01/06/2015", "dd/MM/yyyy", CultureInfo.InvariantCulture);
will parse as 1 June 2015 but
DateTime dt = DateTime.ParseExact("01/06/2015", "MM/dd/yyyy", CultureInfo.InvariantCulture);
will parse as 6 January 2015.

IIS use wrong pt-PT

In .net 4.0, web forms and IIS 8
I have in web.config this:
<globalization culture="pt-PT" uiCulture="pt-PT" />
When I do in C# this:
ltNumber.Text = (12345.12).ToString("N");
I get this: 12 345,12
But the output must be 12.345,12
This began to look bad on windows 10. windows 7 everything was fine. What can be wrong?
The numeric ("N") format specifier uses your CurrentCulture settings.
That means your CurrentCulture has white space as a NumberGroupSeparator and , as a NumberDecimalSeparator.
As a solution, you can Clone your CurrentCulture, set these properties what ever you want, and use that culture as a second parameter in your ToString method. Like;
var clone = (CultureInfo) CultureInfo.CurrentCulture.Clone();
clone.NumberFormat.NumberDecimalSeparator = ",";
clone.NumberFormat.NumberGroupSeparator = ".";
ltNumber.Text = (12345.12).ToString("N", clone); // 12.345,12
I don't think these properties are changed based on operating system versions. It all about which culture settings you use.

Use the Culture of the OS, but not the language

I've encountered several times the same problem in applications we develop:
We want to allow the user to edit/display it's data in his format (date, currency, ...), but we want to display the application in English only (for several reasons, it's a pro, international application, in a domain in which we communicate mostly in English).
There is no problem when we manage the whole application, but most of third-party pro frameworks that I used (Telerik, DevExpress) are using the CurrentCulture to display my data in the correct format AND in the corresponding language.
So, even if I have my computer in English, I have my regional settings set to fr-CH, I will have all third party user controls in French.
I cannot set the CurrentCulture to a specific culture and set the format of my user controls to something else (I would loose my default format) and I can't let the CurrentCulture to be the default one because I would have my third party components in another language.
I tried to build my own culture (CultureAndRegionInfoBuilder), with no success. When I change the language, I still have my application in the user-specific language.
Concrete problem
I'm using a date editor(basic, it has one text input and can popup a calendar). I want to have the date displayed in my OS locale(ch-FR, so 15 january 2013 would be "15.01.2013"), but I don't want that when I display the calendar month/day name appears in french.
What is the correct approach with this?
Store the original CultureInfo for your purposes and try editing CurrentCulture and CurrentUICulture properties of the CurrentThread property in System.Threading.Thread, maybe this will solve your problem.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
I resolved my problem by having a custom culture info:
private static void UpdateCultureInfoWithoutLangage()
{
//We initialize a en-US cultureInfo and change all formats + number infor related
CultureInfo cultureInfoEn = new CultureInfo("en-US");
CultureInfo cultureInfoEnClone = (CultureInfo)cultureInfoEn.Clone();
//Setting DateTimeFormat(Without changing translations)
cultureInfoEnClone.DateTimeFormat.FirstDayOfWeek = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
cultureInfoEnClone.DateTimeFormat.FullDateTimePattern = CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern;
cultureInfoEnClone.DateTimeFormat.LongDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
cultureInfoEnClone.DateTimeFormat.LongTimePattern = CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern;
cultureInfoEnClone.DateTimeFormat.MonthDayPattern = CultureInfo.CurrentCulture.DateTimeFormat.MonthDayPattern;
cultureInfoEnClone.DateTimeFormat.ShortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
cultureInfoEnClone.DateTimeFormat.ShortTimePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern;
cultureInfoEnClone.DateTimeFormat.TimeSeparator = CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator;
cultureInfoEnClone.DateTimeFormat.YearMonthPattern = CultureInfo.CurrentCulture.DateTimeFormat.YearMonthPattern;
cultureInfoEnClone.NumberFormat = CultureInfo.CurrentCulture.NumberFormat;
Thread.CurrentThread.CurrentCulture = cultureInfoEnClone;
Thread.CurrentThread.CurrentUICulture = cultureInfoEnClone;
Application.CurrentCulture = cultureInfoEnClone;
}

Categories