Related
Is there any standard DateTime format for showing "[day] [month] [year]"?
I do not wish to use custom format strings, because it takes away the ability to have order of "day" and "month" depending on the country.
For example, for "en-us" it's "November 22", in France day is first, so it's "22 Novembre"
Just to display day and month like this, I know I can use "M" standard format string.
But how I can write "November 22, 2018" ?
Do I need to concatenate two strings like this:
$"{dt.ToString("M")}, {dt.ToString("yyyy")}"
Is there another way?
It does seem a little odd that the full option isn't available. The closest I can suggest is to use custom formatting, but rather than supply your own, grab DateTimeFormatInfo.LongDatePattern and strip out any occurrence of "dddd" (and its surrounding space/punctuation).
That should give you the variation you want across cultures while removing the weekday.
Examples:
en-US => dddd, MMMM dd, yyyy => MMMM dd, yyyy => November 22, 2018
fr-FR => dddd d MMMM yyyy => d MMMM yyyy => 22 novembre 2018
As I can understand the solution for your problem could be to create a new CultureInfo object.
I've tested it.
CultureInfo us = new CultureInfo("en-US");
string usDate = us.DateTimeFormat.ShortDatePattern;
CultureInfo fr = new CultureInfo("fr-FR");
string frDate = fr.DateTimeFormat.ShortDatePattern;
Console.WriteLine(usDate);
Console.WriteLine(frDate);
//Apply the country format here.
var localDate = DateTime.Now.ToString(frDate);
Console.WriteLine(localDate);
So the format output will be as the location format you provide.
M/d/yyyy ---> USA format.
dd/MM/yyyy ---> France format.
22/11/2018 ---> France format applied to the current date.
For more information redirect to:
CultureInfo Class
$"{dt.ToString("MMMM dd, yyyy")}"
This will show it as November 22, 2018 assuming that dt is assigned this date.
Also, check out Custom Date Time Format String.
You can obtain the LongDatePattern from the current culture, then remove the day-of-week (dddd) and surrounding characters with a regular expression. Below, I am assuming that commas, periods, and spaces are the only separators, but if you encounter others you may want to modify the regex accordingly.
string longDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern;
string modifiedDatePattern = Regex.Replace(longDatePattern, #"[,.]?\s?d{4}[,.]?\s?", "");
Console.WriteLine(longDatePattern); // "dddd, MMMM d, yyyy"
Console.WriteLine(modifiedDatePattern); // "MMMM d, yyyy"
Now you have a custom format you can apply:
string s = DateTime.Now.ToString(modifiedDatePattern);
Console.WriteLine(s); // "November 22, 2018"
Why can't it parse this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")
It can't parse that string because "UTC" is not a valid time zone designator.
UTC time is denoted by adding a 'Z' to the end of the time string, so your parsing code should look like this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");
From the Wikipedia article on ISO 8601
If the time is in UTC, add a 'Z'
directly after the time without a
space. 'Z' is the zone designator for
the zero UTC offset. "09:30 UTC" is
therefore represented as "09:30Z" or
"0930Z". "14:45:15 UTC" would be
"14:45:15Z" or "144515Z".
UTC time is also known as 'Zulu' time,
since 'Zulu' is the NATO phonetic
alphabet word for 'Z'.
Assuming you use the format "o" for your datetime so you have "2016-07-24T18:47:36Z", there is a very simple way to handle this.
Call DateTime.Parse("2016-07-24T18:47:36Z").ToUniversalTime().
What happens when you call DateTime.Parse("2016-07-24T18:47:36Z") is you get a DateTime set to the local timezone. So it converts it to the local time.
The ToUniversalTime() changes it to a UTC DateTime and converts it back to UTC time.
Just use that:
var myDateUtc = DateTime.SpecifyKind(DateTime.Parse("Tue, 1 Jan 2008 00:00:00"), DateTimeKind.Utc);
if (myDateUtc.Kind == DateTimeKind.Utc)
{
Console.WriteLine("Yes. I am UTC!");
}
You can test this code using the online c# compiler:
http://rextester.com/
I hope it helps.
or use the AdjustToUniversal DateTimeStyle in a call to
DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)
You need to specify the format:
DateTime date = DateTime.ParseExact(
"Tue, 1 Jan 2008 00:00:00 UTC",
"ddd, d MMM yyyy HH:mm:ss UTC",
CultureInfo.InvariantCulture);
To correctly parse the string given in the question without changing it, use the following:
using System.Globalization;
string dateString = "Tue, 1 Jan 2008 00:00:00 UTC";
DateTime parsedDate = DateTime.ParseExact(dateString, "ddd, d MMM yyyy hh:mm:ss UTC", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
This implementation uses a string to specify the exact format of the date string that is being parsed. The DateTimeStyles parameter is used to specify that the given string is a coordinated universal time string.
It's not a valid format, however "Tue, 1 Jan 2008 00:00:00 GMT" is.
The documentation says like this:
A string that includes time zone information and conforms to ISO 8601. For example, the first of the following two strings designates the Coordinated Universal Time (UTC); the second designates the time in a time zone seven hours earlier than UTC:
2008-11-01T19:35:00.0000000Z
A string that includes the GMT designator and conforms to the RFC 1123 time format. For example:
Sat, 01 Nov 2008 19:35:00 GMT
A string that includes the date and time along with time zone offset information. For example:
03/01/2009 05:42:00 -5:00
I've put together a utility method which employs all tips shown here plus some more:
static private readonly string[] MostCommonDateStringFormatsFromWeb = {
"yyyy'-'MM'-'dd'T'hh:mm:ssZ", // momentjs aka universal sortable with 'T' 2008-04-10T06:30:00Z this is default format employed by moment().utc().format()
"yyyy'-'MM'-'dd'T'hh:mm:ss.fffZ", // syncfusion 2008-04-10T06:30:00.000Z retarded string format for dates that syncfusion libs churn out when invoked by ejgrid for odata filtering and so on
"O", // iso8601 2008-04-10T06:30:00.0000000
"s", // sortable 2008-04-10T06:30:00
"u" // universal sortable 2008-04-10 06:30:00Z
};
static public bool TryParseWebDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
formats = formats ?? MostCommonDateStringFormatsFromWeb;
return TryParseDateStringExactToUTC(out date, input, formats, styles, formatProvider);
}
static public bool TryParseDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
styles = styles ?? DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; //0 utc
formatProvider = formatProvider ?? CultureInfo.InvariantCulture;
var verdict = DateTime.TryParseExact(input, result: out date, style: styles.Value, formats: formats, provider: formatProvider);
if (verdict && date.Kind == DateTimeKind.Local) //1
{
date = date.ToUniversalTime();
}
return verdict;
//0 employing adjusttouniversal is vital in order for the resulting date to be in utc when the 'Z' flag is employed at the end of the input string
// like for instance in 2008-04-10T06:30.000Z
//1 local should never happen with the default settings but it can happen when settings get overriden we want to forcibly return utc though
}
Notice the use of '-' and 'T' (single-quoted). This is done as a matter of best practice since regional settings interfere with the interpretation of chars such as '-' causing it to be interpreted as '/' or '.' or whatever your regional settings denote as date-components-separator. I have also included a second utility method which show-cases how to parse most commonly seen date-string formats fed to rest-api backends from web clients. Enjoy.
Just replace "UTC" with "GMT" -- simple and doesn't break correctly formatted dates:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC".Replace("UTC", "GMT"))
Not sure why, but you can wrap DateTime.ToUniversalTime in a try / catch and achieve the same result in more code.
Good luck.
The user is supposed to enter date in format: %m %d %Y
What I need to do is convert the date to: 11 11 2013 ( which is today`s date). I have not worked much with dates. Is there some method that does this conversion out of the box? I looked through DateTime options but couldn't find what I need.
Edit:
From the answers received it seems that it is not very clear what I am asking.
In our software the user can insert dates in format like this:
http://ellislab.com/expressionengine/user-guide/templates/date_variable_formatting.html
I am trying to parse this user input and return the today date. So from the link above:
%m - month - “01” to “12”
%d - day of the month, 2 digits with leading zeros - “01” to “31”
%Y - year, 4 digits - “1999”
I was wondering if there is a method that takes %m %d %Y as an input and returns the corresponding today date in the specified format ( which is 11 11 2013 today). Or at least something close to that.
Hope it is more clear now.
EDIT 2:
After digging a little bit more I found that what I am looking for is an equivalent of C++ strftime in C#.
http://www.cplusplus.com/reference/ctime/strftime/
But for some reason I cannot see an example this to implemented in C#.
You can use DateTime.TryParseExact to parse a string to date and DateTime-ToString to convert it back to string with your desired format:
DateTime parsedDate;
if (DateTime.TryParseExact("11 11 2013", "MM dd yyyy", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out parsedDate))
{
// parsed successfully, parsedDate is initialized
string result = parsedDate.ToString("MM dd yyyy", System.Globalization.CultureInfo.InvariantCulture);
Console.Write(result);
}
My go-tos for DateTime Input and Output:
http://www.dotnetperls.com/datetime-parse for input (parsing)
http://www.csharp-examples.net/string-format-datetime/ for output (formatting)
string dateString = "01 01 1992";
string format = "MM dd yyyy";
DateTime dateTime = DateTime.ParseExact(dateString, format, CultureInfo.InvariantCulture);
Edit since his edit makes my above answer irrelevant (but will leave there for reference):
From what you're saying, you want to output today's date in a dynamically-defined format?
So if I want to see month, date, year, I say "MM dd YY" and you return it to me?
If so:
DateTime dt = DateTime.Today; // or initialize it as before, with the parsing (but just a regular DateTime dt = DateTime.Parse() or something quite similar)
Then
String formatString = "MM dd YY";
String.Format("{0:"+ formatString+"}", dt);
Your question is still quite unclear, though.
Use ParseExact:
var date = DateTime.ParseExact("9 1 2009", "M d yyyy", CultureInfo.InvariantCulture);
I want to parse strings with date that can have different formats like:
"21.12.12", "4,12,2011", "30 Jun 11", "16 12 2013" , "April 2013", "12. April 2012", "12, März 2011".
I have this code:
string[] ll = {"en-US", "de-DE"};
date = "4,12,2011";
foreach (string l in ll) {
if (DateTime.TryParse(date, new CultureInfo(l),
DateTimeStyles.None, out pDate)) {
return pDate;//.ToString("dd.MM.yyyy");
}
}
And I have problems with dates like this:
"21.12.12" is parsed like "21 December 2012", and it is OK
"4,12,2011" is parsed like "12 April 2011", it is not OK, I need "4 December 2011"
How to set order for Day and Month?
It must be Day before Month.
To specify the format(s) of the string you are passing, you should use the ParseExact method.
Use DateTime.ParseExact, it has also an overload tha allows to pass a string[[] for all allowed formats.
string[] dates = new[] { "21.12.12", "4,12,2011", "30 Jun 11", "16 12 2013", "April 2013", "12. April 2012", "12, März 2011" };
CultureInfo germanCulture = CultureInfo.CreateSpecificCulture("de-DE"); // you are using german culture
string[] formats = new[] { "dd/MM/yy", "d,MM,yyyy", "dd MMM yy", "dd MM yyyy", "MMMM yyyy", "dd. MMMM yyyy", "dd, MMMM yyyy"};
foreach (string dateString in dates)
{
DateTime dt = DateTime.ParseExact(dateString, formats, germanCulture, DateTimeStyles.None);
Console.WriteLine(dt.ToString());
}
I have used german culture because your date-strings contain german month names. So this code works even if the current culture is different.
All of the test dates that you gave actually parse correctly in the de-DE culture that you specify. The problem comes that you try to parse it in the american culture first where they use mm.dd.yyyy style formats.
The correct solution in general is to always make sure you know what culture you are using when parsing the string rather than guessing. If you have to guess you will get these kinds of problems at times.
In this case though it looks like they are all acceptable de-DE date strings so you can just parse them as that without needing the loop of trying different cultures (which as mentioned is probably never likely to be a perfect result).
According to your code
string[] ll = {"en-US", "de-DE"};
you initially try parse DateTime with "en-US" culture; so the "4,12,2011" will be parsed
as americans do - MM/DD/YYYY - month the first (12 April). Change order in your array
string[] ll = {"de-DE", "en-US"};
and "4,12,2011" will be 4 December
This is specific for the en-US culture. It may be strange for us Europeans, but Americans really write month before day in dates. You may use en-GB instead - it will handle the same names of months and the European order.
Why can't it parse this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")
It can't parse that string because "UTC" is not a valid time zone designator.
UTC time is denoted by adding a 'Z' to the end of the time string, so your parsing code should look like this:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");
From the Wikipedia article on ISO 8601
If the time is in UTC, add a 'Z'
directly after the time without a
space. 'Z' is the zone designator for
the zero UTC offset. "09:30 UTC" is
therefore represented as "09:30Z" or
"0930Z". "14:45:15 UTC" would be
"14:45:15Z" or "144515Z".
UTC time is also known as 'Zulu' time,
since 'Zulu' is the NATO phonetic
alphabet word for 'Z'.
Assuming you use the format "o" for your datetime so you have "2016-07-24T18:47:36Z", there is a very simple way to handle this.
Call DateTime.Parse("2016-07-24T18:47:36Z").ToUniversalTime().
What happens when you call DateTime.Parse("2016-07-24T18:47:36Z") is you get a DateTime set to the local timezone. So it converts it to the local time.
The ToUniversalTime() changes it to a UTC DateTime and converts it back to UTC time.
Just use that:
var myDateUtc = DateTime.SpecifyKind(DateTime.Parse("Tue, 1 Jan 2008 00:00:00"), DateTimeKind.Utc);
if (myDateUtc.Kind == DateTimeKind.Utc)
{
Console.WriteLine("Yes. I am UTC!");
}
You can test this code using the online c# compiler:
http://rextester.com/
I hope it helps.
or use the AdjustToUniversal DateTimeStyle in a call to
DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)
You need to specify the format:
DateTime date = DateTime.ParseExact(
"Tue, 1 Jan 2008 00:00:00 UTC",
"ddd, d MMM yyyy HH:mm:ss UTC",
CultureInfo.InvariantCulture);
To correctly parse the string given in the question without changing it, use the following:
using System.Globalization;
string dateString = "Tue, 1 Jan 2008 00:00:00 UTC";
DateTime parsedDate = DateTime.ParseExact(dateString, "ddd, d MMM yyyy hh:mm:ss UTC", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
This implementation uses a string to specify the exact format of the date string that is being parsed. The DateTimeStyles parameter is used to specify that the given string is a coordinated universal time string.
It's not a valid format, however "Tue, 1 Jan 2008 00:00:00 GMT" is.
The documentation says like this:
A string that includes time zone information and conforms to ISO 8601. For example, the first of the following two strings designates the Coordinated Universal Time (UTC); the second designates the time in a time zone seven hours earlier than UTC:
2008-11-01T19:35:00.0000000Z
A string that includes the GMT designator and conforms to the RFC 1123 time format. For example:
Sat, 01 Nov 2008 19:35:00 GMT
A string that includes the date and time along with time zone offset information. For example:
03/01/2009 05:42:00 -5:00
I've put together a utility method which employs all tips shown here plus some more:
static private readonly string[] MostCommonDateStringFormatsFromWeb = {
"yyyy'-'MM'-'dd'T'hh:mm:ssZ", // momentjs aka universal sortable with 'T' 2008-04-10T06:30:00Z this is default format employed by moment().utc().format()
"yyyy'-'MM'-'dd'T'hh:mm:ss.fffZ", // syncfusion 2008-04-10T06:30:00.000Z retarded string format for dates that syncfusion libs churn out when invoked by ejgrid for odata filtering and so on
"O", // iso8601 2008-04-10T06:30:00.0000000
"s", // sortable 2008-04-10T06:30:00
"u" // universal sortable 2008-04-10 06:30:00Z
};
static public bool TryParseWebDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
formats = formats ?? MostCommonDateStringFormatsFromWeb;
return TryParseDateStringExactToUTC(out date, input, formats, styles, formatProvider);
}
static public bool TryParseDateStringExactToUTC(
out DateTime date,
string input,
string[] formats = null,
DateTimeStyles? styles = null,
IFormatProvider formatProvider = null
)
{
styles = styles ?? DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; //0 utc
formatProvider = formatProvider ?? CultureInfo.InvariantCulture;
var verdict = DateTime.TryParseExact(input, result: out date, style: styles.Value, formats: formats, provider: formatProvider);
if (verdict && date.Kind == DateTimeKind.Local) //1
{
date = date.ToUniversalTime();
}
return verdict;
//0 employing adjusttouniversal is vital in order for the resulting date to be in utc when the 'Z' flag is employed at the end of the input string
// like for instance in 2008-04-10T06:30.000Z
//1 local should never happen with the default settings but it can happen when settings get overriden we want to forcibly return utc though
}
Notice the use of '-' and 'T' (single-quoted). This is done as a matter of best practice since regional settings interfere with the interpretation of chars such as '-' causing it to be interpreted as '/' or '.' or whatever your regional settings denote as date-components-separator. I have also included a second utility method which show-cases how to parse most commonly seen date-string formats fed to rest-api backends from web clients. Enjoy.
Just replace "UTC" with "GMT" -- simple and doesn't break correctly formatted dates:
DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC".Replace("UTC", "GMT"))
Not sure why, but you can wrap DateTime.ToUniversalTime in a try / catch and achieve the same result in more code.
Good luck.