One general question:
Does the DateTime object stores the CultureInfo with it, or you need to use the Formatter to format the DateTime according to current culture ?
I have a class property that retuns a DateTime. Within that property I am setting the DateTime object with current culture information using CultureInfo object. Below is the code for class property I am using:
public DateTime PrintedQuoteDate {
get {
DateTime printQuoteDate = DateTime.Today;
// cInfo = CultureInfo object
return Convert.ToDateTime(printQuoteDate , cInfo);
}
}
So my question is when I will use the above property in my code, will it have the corrosponding culture information that I am setting in its get method, or I will have to use the same CONVERT code for formatting date time. The restriction here is that the Property should return only DateTime type.
Any idea, suggestions
DateTime does not store any Culture what so ever. In fact it does not even hold a reference to a TimeZone, all it knows is whether it is a UTC DateTime or not. This is handled by an internal enum.
You need to specify a format provider (every culture in itself is a format provider) when using the ToString method of a DateTime, otherwise it will use the culture (really the culture and not the UI Culture) of the current thread.
You can get a predifined culture by using the ISO country/locale codes like this:
var us = new CultureInfo("en-US");
var british = new CultureInfo("en-GB");
var danish = new CultureInfo("da");
As you can see for danish it is enough to specify the language since there are no other locales (to my knowledge).
Related
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern="DD/MM/YYYY";
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortTimePattern ="hh:mm tt";
I am overriding the Date and time format for a culture in thread by doing this we will get Date and Time in given format in DateTime.Now.
I am able to get preferred format for Date same thing not working for Time.
How to get time in preferred format using above culture threading.
You might need to create an object of type 'System.Globalization.CultureInfo' and set the date and time format specifications on that object.
Next you need to set the current culture of your thread to that culture.
I have given the code for your reference below
private void UpdateCurrentCulture()
{
System.Globalization.CultureInfo objCulture = new System.Globalization.CultureInfo("en-US");
objCulture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
objCulture.DateTimeFormat.ShortTimePattern = "hh:mm tt";
System.Threading.Thread.CurrentThread.CurrentCulture = objCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = objCulture;
Console.WriteLine(DateTime.Now.ToShortDateString());
Console.WriteLine(DateTime.Now.ToShortTimeString());
}
This is my code:
DateTime Now = DateTime.Parse(DateTime.Now.ToString(), new System.Globalization.CultureInfo("fa-ir"));
The Geogorian date is: 16/06/2016
The Persian date is: 15/03/1395
while the value of Now is: 07/09/2025
The time is correct.
What can be the problem?
You are only passing a cultureinfo param to Parse, but not to ToString. This means the string is formatted using the thread culture, and then parsed using fa-ir culture.
If you're trying to obtain the year, month and day of "now" in the Persian Calendar, you should use the Calendar class:
using System;
using System.Globalization;
public class Test
{
static void Main()
{
var now = DateTime.Now;
var calendar = new PersianCalendar();
Console.WriteLine($"Year: {calendar.GetYear(now)}");
Console.WriteLine($"Month: {calendar.GetMonth(now)}");
Console.WriteLine($"Day: {calendar.GetDayOfMonth(now)}");
}
}
If you just want to format a value as a string, you can pass the CultureInfo into the ToString call:
using System;
using System.Globalization;
public class Test
{
static void Main()
{
var culture = new CultureInfo("fa-ir");
var now = DateTime.Now;
Console.WriteLine(now.ToString(culture));
}
}
Here, the CultureInfo has a default calendar associated with it (as well as date/time format strings) and that is used to format the value.
A DateTime itself is always effectively in the Gregorian calendar system - there's no way of creating a "DateTime in the Persian Calendar" for example, or "converting" a DateTime from one calendar to another.
Note that in my Noda Time library, that's not true - you can specify a calendar system for a ZonedDateTime, OffsetDateTime, LocalDate or LocalDateTime value, and convert from one to another. If you're doing a lot of calendar work, I'd recommend you at least give Noda Time a try - it's designed to make it a lot harder to make this sort of mistake.
I'm trying to convert a date time to a specific format using a CultureInfo object and ToString
for example:
var dateTime = someDate.ToString(cultureInfoObject);
The problem is that dateTime is a string after this executes but I still need it to be a DateTime object. If I try to convert it back to a DateTime I get an exception because it is in a different format (specifically en-AU in this case). Is there another way to do this?
CultureInfo cultureInfo = new CultureInfo("en-au");
var dateTime = DateTime.Now.ToString(cultureInfo);
DateTime dt = DateTime.Parse(dateTime, cultureInfo);
To convert back from string to DateTime, use the DateTime.parse method
For example (assuming dateTime is your string):
DateTime dteParsed = DateTime.Parse(dateTime, cultureInfoObject);
Note, this is a static method Optionally you can add a third parameter, Which is a DateTimeStyles Enumeration, which permits you to "guide" the parser for which format the date's text is presented see (https://msdn.microsoft.com/en-us/library/91hfhz89%28v=vs.110%29.aspx)
Consider the following code:
class Program
{
static void Main(string[] args)
{
try
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("fo-FO");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
Console.WriteLine("Was able to parse with fo-FO");
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
try
{
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
Console.WriteLine("Was able to parse with en-US");
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
}
}
The output is:
Exception: System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
at System.DateTime.Parse(String s, IFormatProvider provider)
at DateTimeTest2.Program.Main(String[] args) in C:\Projects\DateTimeTest2\DateTimeTest2\Program.cs:line 17
Was able to parse with en-US
This code fragment proves that DateTime.Parse uses Thread.CurrentThread.CurrentCulture regardless of the fact that the "InvariantCulture" is being passed in. I find this so unintuitive that I consider it a "bug".
Why do we have to pass in a CultureInfo if it is in fact ignored by DateTime.Parse in any case? Is there a way of calling DateTime.Parse in a way that is independent of the CurrentCulture?
This code fragment proves that DateTime.Parse uses Thread.CurrentThread.CurrentCulture regardless of the fact that the "InvariantCulture" is being passed in
I'm not sure how this example proves that. The strings passed to DateTime.Parse are different, so it's not completely surprising that different results ensue.
The first string has the time formatted as 23.59.59, which (apparently) InvariantCulture cannot parse; the second string has the time formatted as 23:59:59, which InvariantCulture can parse. What's the problem?
edit to add, since apparently it makes a difference, I am running with .NET 2.0 and the strings produced by fo-FO and en-US are respectively
9999-12-31T23.59.59Z
and
9999-12-31T23:59:59Z
from MSDN:
The invariant culture is
culture-insensitive. Your application
specifies the invariant culture by
name using an empty string ("") or by
its language identifier.
InvariantCulture retrieves an instance
of the invariant culture. It is
associated with the English language
but not with any country/region.
I could not find any reference to using the current thread's culture, as that would be counter-intuitive as you said.
You could (as a workaround) cache the current thread's culture, set it to a known good culture (en-US), perform your parsing, then set the thread's culture back to the old value.
CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
var s = DateTime.MaxValue.ToString("yyyy-MM-ddTHH:mm:ssZ");
var d = DateTime.Parse(s, CultureInfo.InvariantCulture);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
This will guarantee you know what culture is being used to parse the DateTime string and will not affect outside calling code because the culture is never changed from an outside perspective.
If you do not want to respect any timezones in the parsing you could use
var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
or
var d = DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
Both parses use InvariantCulture, which is the actually a hard-coded reference to the 'en-US' culture (there may be casses where the InvariantCulture is not 'en-US' but I haven't come accross them).
Replace your use of InvariantCulture with new CultureInfo("en-US") and it will become obvious why the first parse doesn't work.
In addition to what AakashM wrote:
I tried running it in .NET 3.5 SP1. In the second case, I get a System.FormatException stating that the value of the DateTime is out of range.
Stupid questions but cant get my head around it...
I have a string in this format 20081119
And I have a C# method that converts the string to a DateTime to be entered into a SQL Server DB
public static DateTime MyDateConversion(string dateAsString)
{
return System.DateTime.ParseExact(dateAsString, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
}
The problem is that the Date is coming out like this: Date = 19/11/2008 12:00:00 AM and I need it to be a DateTime of type yyyyMMdd as I am mapping it into a schema to call a stored proc.
Thanks in advance guys.
Cheers,
Con
There is no such thing as "a DateTime of type yyyyMMdd"; a DateTime is just a large integer, indicating the amount of time in an epoch - it doesn't have a format. But that is fine, since you should be using parametrized TSQL anyway - so just add the DateTime as the value of a DbParameter, and it will be handed to the db in an unambiguous way (don't use string concatenation to build a TSQL command):
DbParameter param = cmd.CreateParameter();
param.ParameterName = "#foo";
param.DbType = DbType.DateTime;
param.Value = yourDateTime; // the DateTime returned from .ParseExact
cmd.Parameters.Add(param);
or for a SqlCommand:
cmd.Parameters.Add("#foo", SqlDbType.DateTime).Value = yourDateTime;
If you genuinely need a string, then just use the string directly as a [n][var]char parameter.
Also - in this case, to parse the date I would use the invariant culture (since culture doesn't feature in the format):
DateTime yourDateTime =
DateTime.ParseExact(dateString, "yyyyMMdd", CultureInfo.InvariantCulture);
From the conversation, it seems you might also need to go from a DateTime to a string, in which case simply reverse it:
string dateString = yourDateTime.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
Date Time is a class that, by default, formats it's ToString as 19/11/2008 12:00:00 AM
This is from MSDN which may help you
Because the appearance of date and
time values is dependent on such
factors as culture, international
standards, application requirements,
and personal preference, the DateTime
structure offers a great deal of
flexibility in formatting date and
time values through the overloads of
its ToString method. The default
DateTime.ToString() method returns the
string representation of a date and
time value using the current culture's
short date and long time pattern. The
following example uses the default
DateTime.ToString() method to display
the date and time using the short date
and long time pattern for the en-US
culture, the current culture on the
computer on which the example was run.
You may be able, therefore, to overload the ToString on DateTime to the desired format, else pass the string representation directly to the stored procedure instead
Ok, back to the culture thing... When you say:
the Date is coming out like this: Date
= 19/11/2008 12:00:00 AM
I'm guessing you are running a ToString on the date to see this result? The formatting in ToString will vary based on the culture and will use your current culture by default.
I was able to reproduce the format your are getting by doing this:
var dateString = "20081119";
var fr = new System.Globalization.CultureInfo("fr-FR");
var resultingDate =DateTime.ParseExact(dateString,"yyyyMMdd",System.Globalization.CultureInfo.CurrentCulture);
Console.WriteLine(resultingDate.ToString(fr));
You have a valid date, so the formatting shouldn't matter, but if it does and you need to get it in the format you described, then you need to format it when converting to a string... if it's already a string, then there is no need for the date conversion.
I could be mis-reading your question, but I had to get this out b/c it was bugging me.
I'm thinking it's due to the culture set in CurrentCulture, without knowing what that is, I can't be certain, but specifying en-US works on my end. Here is the code I have:
var dateString = "20081119";
var enUS = new System.Globalization.CultureInfo("en-US");
var resultingDate = DateTime.ParseExact(dateString,"yyyyMMdd",enUS);
Console.WriteLine(resultingDate.ToString());
Give it a try and see if it works for you.
This is what will give exact result you are looking for:
convert( varchar(10), getdate(), 112 ) : datetime to string (YYYYMMDD format)
convert( datetime, '20081203', 112 ) : string to datetime (YYYYMMDD format)
Code side:
DateTimeFormatInfo fmt = (new CultureInfo("hr-HR")).DateTimeFormat;
Console.WriteLine(thisDate.ToString("d", fmt)); // Displays 15.3.2008 (use similar formats acc to your requirements)
or
date1.ToString("YYYYMMDD",CultureInfo.CreateSpecificCulture("en-US"))
date1.ToString("YYYYMMDD");
Details at http://msdn.microsoft.com/en-us/library/az4se3k1.aspx