Date format different on server - c#

When I execute the code below, I am getting my dates formatted as 04-07-2015 which is as expected what I want.
But when I execute the same code on another server, I am getting date as 7/4/2015. Why?
Here is my code on pageload:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
fillProject();
}
grdData.Visible = false;
TxtIndate.Value = System.DateTime.Now.ToShortDateString();
txtOutDate.Value = System.DateTime.Now.ToShortDateString();
}

ToShortDateString method uses ShortDatePattern property of the CurrentCulture settings.
Probably your servers have different culture settings, that's why when you run this code, you get different string representations of your DateTime.
If you wanna get same representation in both server, set the same culture on both server in region and language settings or use custom date and time format specifiers like;
TxtIndate.Value = DateTime.Now.ToString("dd-MM-yyyy");
or as a better way as Matt mentioned, use InvariantCulture with string format like;
TxtIndate.Value = DateTime.Now.ToString("dd-MM-yyyy", CultureInfo.InvariantCulture );

From the c# code it seems impossible that the same code produces two different time formats. So as far as I can tell, we have to find it somewhere else.
Maybe the source of the confusion is in two different types of input controls in your HTML output. One type=text, one type=date that could explain the different formatting since the HTML 5 date control renders differently. So one date is the server formatted value, the other is the browser, and possibly client culture, formatted value.

As other posters have said, this is due to the different cultures.
If having the same date format is important (caveat, users expect to see dates in the format they're used to for their culture) then you can always set it explicitly.
var myCultureDateFormat = new CultureInfo("en-US").DateTimeFormat;
// Short date string
var shortDate = DateTime.Now.ToString(myCultureDateFormat.ShortDatePattern);
// Long date string
var longDate = DateTime.Now.ToString(myCultureDateFormat.LongDatePattern);
Happy coding!

Related

Best way to validate a date string in C#

I was trying to validate a date read from app.config file using DateTime.TryParse() method. However, it returned true when the input was "12/05/201". This was actually a typo, and should have been, "12/05/2018". When I stepped through the code it automatically converted the date to "12/05/0201" and returned true. However when I used DateTime.TryParseExact(), it correctly returned false for the above input. So, should we always use DateTime.TryParseExact()? I am little confused because earlier I used use DateTime.TryParse() whenever I had to validate a date string! Both the code is given below:
Boolean isValidStartDate = DateTime.TryParse(startDate, out DateTime startDateVerified);
CultureInfo enUS = new CultureInfo("en-US");
Boolean isValidStartDate = DateTime.TryParseExact(startDate,"MM/dd/yyyy",enUS, DateTimeStyles.None, out DateTime startDateVerified);
Thanks
The year 201 being invalid is business logic - if you want to have logical safeguards on your imported data (and you should), do them explicitly. With C# you can easily add an extension method to DateTime if you want, something like
public static DateTime ParseDateWithSanity(this DateTime, string date)
{
dt = DateTime.Parse(date);
if dt.Year < 1900
{
throw BadInputException()
}
}
Best way to Validate date depends upon the use case and input data source and its formate
DateTime.TryParse is parsed using formatting information in the current DateTimeFormatInfo object so let's say if you use TryParse "12/05/201" it will return the parsed data according to your current culture settings. Which is "12/05/0201" ie in date format "MM/DD/YYYY"
Its always good practice to specify date formate and culture variance while parsing date and use TryParseExact instead of TryParse
(Note: To know about current culture settings you can look for a member of classes CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture)

.NET saving date in dd/MM/yyyy format in HttpPost

Unlike the U.S.A ... most other countries uses the dd/MM/yyyy format (from smallest to biggest). However, .NET naturally takes in date in MM/dd/yyyy format.
I have an input that accepts a datetime, and the user will want to type in the date in dd/MM/yyyy format, let's say they type in 30/1/2017 ... but when that date is posted in the backend, it becomes unrecognized.. or it becomes reversed (1/2/2017 becomes 2/1/2017).
[HttpPost]
public ActionResult Save(DateTime date) // user entered 1/2/2017 from front-end
{
date.ToString("dd/MM/yyyy"); // this becomes 2/1/2017
}
Is there some kind of global setting to reverse this recognization of date in .NET? I would not like to manually switch dates from front-end because that seems like alot of work and alot of places to do it from.
You'd be better off setting the culture on the thread or in the controller initialization, or in the routing. There are a couple of answers in this question that show several excellent ways to do it.
The point is, the Thread.CurrentCulture controls the formatting of date/time and currency, among other cool things...so you can focus on the real solution, and leave all the trivial work to the framework.
DateTime.ParseExact is one of the shots you can try.
You need to specify culture, and then parse the date:
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime.ParseExact("01/02/2017", "dd/MM/yyyy", provider);
DateTime.ParseExact("01/02/2017", "MM/dd/yyyy", provider);
If you will show output, the first one will be [01.02.2017 00:00:00] and the seccond [02.01.2017 00:00:00]
Your solution does not work, because when you are getting the data, it's probalbly get with the same American format of "MM/dd/yyyy"
DateTime isn't a good idea for serialisation/deserialisation like that because of stuff like this, or timezones. Rather than trying to hack it such that it works, avoid it altogether by sending it as a Unix timestamp (or similar things, like strings with timezone info that you then parse), and then turn it into a DateTime on your end.
You can follow this answer and cater it to your purposes like so:
[HttpPost]
public ActionResult Save(double timestamp)
{
var date = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc).AddSeconds( timestamp );
}
This isn't ideal, but there must be a way to automate it. Be aware your front-end will need to send it as a normal Unix timestamp (Javascript, for example, uses a timestamp in milliseconds instead of seconds.) and as UTC. This also avoids timezone issues.
If you will going to use this format conversion multiple times, why not to use a Helper Method ?
Like this c# console aplication exemple:
static void Main(string[] args)
{
DateTime mydate = new DateTime(2017, 04, 08);
string myValue = convertDate(mydate);
Console.WriteLine(myValue);
Console.ReadKey();
}
private static string convertDate(DateTime dateToConvert)
{
return string.Format("{0:MM/dd/yyyy}", dateToConvert);
}

How to convert string to ToString("#,##0") format

in my application i am update my ui with my label and i want to show the number in #,##0 format.
myClass.getNumberOfFiles return string.
myLabel.Text = myClass.getNumberOfFiles();
Assuming getNumberOfFiles returns a string (which, by its name, it shouldn't) :
myLabel.Text = int.Parse(myClass.getNumberOfFiles()).ToString("#,##0");
I suspect you want the standard "numeric" format specifier, with a precision of 0:
label.Text = GetNumberOfFiles().ToString("N0");
This is after you've fixed your getNumberOfFiles() method to be GetNumberOfFiles() (naming convention) and made it return int or long (a method which is meant to fetch a number should not return a string).
This will use the appropriate grouping for the current culture; if you want a different culture you can specify it as a second argument.
int files;
if (int.TryParse(myClass.getNumberOfFiles(), out files)) {
myLabel.Text = files.ToString("N0");
}
This won't work if you have any formatting in the number already I think. It will work though if on the return of getNumberOfFiles() someone was turning an int into a string. If getNumberOfFiles() is returning a formatted string, you will need to do some different stuff. Below assumes the formatting is in the en-US format coming in and you want to display it in Brazilian Portuguese for example. It is shown in a verbose manner so you know how to plug other cultures in if you need to. If its formatted and doesn't need to change between cultures I don't know why you couldn't just assign the return of getNumberOfFiles() directly to the label's Text property.
int files;
var incomingCulture = CultureInfo.CreateSpecificCulture("en-US");
var outgoingCulture = CultureInfo.CreateSpecificCulture("pt-BR");
if (int.TryParse(myClass.getNumberOfFiles(), NumberStyles.Number, incomingCulture, out files)) {
myLabel.Text = files.ToString("N0", outgoingCulture);
}
That being said I agree with all the others saying it is ridiculous to return a string for an integer. But I know sometimes you don't have the luxury of being able to change it.
I'll also point out that if you use the named format specifiers like "N0", one day a programmer coming behind you will bless you in their heart when they have to globalize your code. This is because every CultureInfo instance has an implementation for each of the named formats, however it is impossible for it to have implementations for custom format specifiers.

How to get date in C#, without localisation

My C# application have to read some date from MySQL database. Problem I have is that format of date depends on system localisation settings.
My question is if is possible that I always get date in formats yyyy-MM-dd hh:mm:ss, and yyyy-MM-dd, no matter of localisation settings.
Thank you in advance!
If you are storing the dates as true date or datetime values, your application will get the raw binary data back, and it will not be subject to localization until you create a string representation of the date values. My guess is that you are looking at the values in the debugger or using Console.WriteLine(theValue);, which will use the current locale. Always include the desired format and/or the desired culture when converting non-string values to strings.
If you are storing the dates as strings, you will always have to know exactly what format went into the database.
Assuming the dates are stored as date or datetime: just handle the values as they are, and don't convert them to strings until you need to show them to a user:
DateTime theValue = theReader.GetDateTime(fieldOrdinal);
var theValueAsText = theValue.ToString(CultureInfo.InvariantCulture);
var specificTextRepr = theValue.ToString("yyyy-MM-dd HH:mm:ss");
The theValueAsText variable will be a string representation that is not tied to a specific culture. The specificTextRepr will be your specific text representation.
You shouldn't be reading it back as a string from the database - you haven't shown how you're reading the data, but if you use something to populate a DataTable, or LINQ, or IDataReader.GetDateTime then there's no string formatting involved (assuming it's stored properly in the database, which it looks like it is).
A DateTime value doesn't intrinsically have a format, any more than an int is in decimal or hex - it's how you choose to convert it that matters, and you should almost always avoid doing that formatting unless you really need to.
Since you store the dates in date and date/time specific representations, formatting does not play into it at all (as opposed to some highly discouraged storage schemes when date/time is stored as strings, when formatting does matter, but for a wrong reason).
When you query MySQL from your C# code, you will get the correct dates no matter what your locale is. They will be displayed differently based on the locale, but they will represent the proper date regardless of the locale settings.
You can format the date directly in the query by using
date_format(dob,'%d/%m/%Y')
select date_format(dob,'%d/%m/%Y') dob from student where Id=1
Change
CurrentDate = DateTime.Now.ToString("MMM d, yyyy");
CurrentTime = DateTime.Now.ToString("hh:mm tt");
TO
CurrentDate = DateTime.Now.ToString("MMM d, yyyy",CultureInfo.InvariantCulture);
CurrentTime = DateTime.Now.ToString("hh:mm tt", CultureInfo.InvariantCulture);

Format a date using the current thread culture Vs double digits for month and day?

I want to display some rows of data on a web page where one column is a DateTime.
I want the date format to be displayed based on the current thread culture.
Right now, I'm doing this (dt is a DateTime):
string s = dt.ToString(Thread.CurrentThread.CurrentCulture.DateTimeFormat);
It's working well, however, on some culture, months and days are represented as only one digit (hours too), for example:
8/8/2011 8:57:59 AM
I would like the date to be displayed like this:
08/08/2011 08:57:59 AM
It would be easier to read (and prettier) when there's a list of rows.
I saw that there's a String.format method I could use, but that makes the current culture irrelevant.
Is there a way to achieve what I'm trying to do?
The solution provided here might be useful.
I see only a single solution - you should obtain the current culture display format, patch it so that it meets your requirement and finally format your DateTime value using the patched format string.
Make a custom culture.
Base it on the current thread culture.
Modify the settings you want to override.
Then either set it back into the thread as the culture or use it temporarily during the format operation.
We currently do this to format all dates in an internationally unambiguous form ddMMMyyyy where MMM is only English three-letter abbreviations, yet obey local numeric formatting rules ./, etc.
The relevant properties to override would be here.
If you want to show it based on the current culture, then what is the problem? If you want a specific format, you have to specify that.
string text = myDateTime.ToString("{0:[your format]}");
I believe this defaults to the server format - but what if you try specifying "u" as the format code which will put the year first then I think two digits.
You can use
String.Format("{0:dd/MM/yyyy hh:MM PM ", yourDatetime)
The date separator / (slash) and time sepatator : (colon) will be rewritten to characters defined in the current DateTimeForma­tInfo.DateSepa­rator and DateTimeForma­tInfo.TimeSepa­rator.
EDIT: Forgot to add object param needed to the string.format
using System.Globalization;
private static CultureInfo defaultCulture = new CultureInfo("nl-NL");
public static CultureInfo GetCurrentCulture()
{
List<CultureInfo> badCultures = new List<CultureInfo>();
badCultures.Add(new CultureInfo("en-US"));
if (badCultures.Contains(System.Threading.Thread.CurrentThread.CurrentCulture))
return defaultCulture;
return System.Threading.Thread.CurrentThread.CurrentCulture;
}

Categories