C#: convert string to DateTime - c#

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.

Related

Not able to parse "Sept 4, 2020" or "sept 4, 2020" date string in C#

I have used
DateTime.Parse
DateTime.TryParse
DateTime.TryParseExact
DateTime.ParseExact
nothing is working. Please help
The reason is that the abbreviation of September is Sep not Sept, at least in the cultures i know. Where are you from? So you either need to use a CultureInfo where its Sept or replace them with Sep in your input.
A better(than replace) option is to create a custom CultureInfo:
CultureInfo myCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
myCulture.DateTimeFormat.AbbreviatedMonthNames = GetCustomAbbreviatedMonthNames();
string[] dates = { "Sept 4, 2020", "sept 4, 2020"};
string[] formats = {"MMM d, yyyy"};
foreach (string s in dates)
Console.WriteLine(DateTime.TryParseExact(s, formats, myCulture, DateTimeStyles.None, out DateTime dt) ? $"Valid<{dt}>" : $"invalid<{s}>");
static string[] GetCustomAbbreviatedMonthNames()
{
string[] template = CultureInfo.InvariantCulture.DateTimeFormat.AbbreviatedMonthNames;
// replace the september but also you might want to do it with the other months as well
template[8] = "Sept";
return template;
}
Output:
Valid<04.09.2020 00:00:00>
Valid<04.09.2020 00:00:00>
You can see this other post all about dates in C#: Date Format in Day, Month Day, Year
you can read this too: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Try to use:
string date = DateTime.Now.ToString("MMM dd, yyyy");
the output will be
as of today`s date:
Apr 09, 2021
and here is a full guide about dates formats in C#:
https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1

DateTime standard format for day, month and year

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"

Format date string in a specific pattern

I have a to display Date format in this format
Tuesday April 17 6:12:02 2018
I have tried this
class Program
{
static void Main(string[] args)
{
var today = DateTime.Now.AddDays(-1);
var day = today.Day;
var month = today.Month;
var year = today.Year;
Console.WriteLine(today);
Console.WriteLine(day);
Console.WriteLine(month);
Console.WriteLine(year);
var answer = day + "/" + month + "/" + year;
Console.WriteLine(answer);
Console.WriteLine(today);
}
}
How can I get the Month and Day like Tuesday, Wednesday in full text , also can the date be changed to AM and PM...
I can get the year and date in int.
This was taken from the docs listed in the comments. You basically add in the string format patterns with the format you want to display. Notice there is a difference between uppercase and lowercase formats.
As Mentioned by Soner Gönül, if you are targeting an audience to not be english based then consider adding in a CultureInfo.InvariantCulture field to the toString(). That way the date displayed is not tied to a certain culture. Just don't forget to include System.Globalization.
From the docs:
Invariant culture data is stable over time and across installed cultures and cannot be customized by users. This makes the invariant culture particularly useful for operations that require culture-independent results, such as formatting and parsing operations that persist formatted data
var today = DateTime.Now.AddDays(-1);
Console.WriteLine(today.ToString("dddd MMMM dd hh:mm:ss tt yyyy", CultureInfo.InvariantCulture));
// Monday April 16 12:11:06 PM 2018 <- My time
This is a classic formatting question.
If you wanna get textual (aka string) representation of a DateTime, the most usual way is using ToString method with optional format and culture settings.
Your aimed string contains english-based month and day names. That's why you need to use an english-based culture setting like InvariantCulture.
And putting formats in your string, you just need to follow the rules on custom date and time format strings page.
var answer = DateTime.Now.AddDays(-1).ToString("dddd MMMM dd h:mm:ss yyyy",
CultureInfo.InvariantCulture);

I'm trying to parse Ukrainian date/time strings from a log file

The dates are recorded as follows in the logs:
08 груд. 2017 00:00:06,694
I've been using Linqpad to try to come up with a valid date time mask using the Ukrainian culture, and this is what I've tried:
var dateString = "08 груд. 2017 00:00:06,694";
DateTime date;
DateTime.TryParseExact(
dateString,
"dd MMMM. yyyy HH:mm:ss,fff",
new CultureInfo("uk-UA"),
DateTimeStyles.None,
out date);
Console.WriteLine(date);
This does not work, and the output from this script is:
1/1/0001 12:00:00 AM
This same approach has worked well for me for several other languages, so I'm puzzled as to what is happening here. As best as I can tell, the month is not being parsed correctly. I've try substituting "hrud." for the month value (from: https://www.loc.gov/aba/pcc/conser/conserhold/Mosabbr.html), but that does not work either.
MMMM format specifier for month means "full month name". You can see what are full month names for given culture with:
var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.MonthNames;
For this culture, december full name is "грудень", not "груд". You might think to use "short month name" format specifier MMM. You can look "short names" for month for given culture like this:
var culture = new CultureInfo("uk-UA");
var monthNames = culture.DateTimeFormat.AbbreviatedMonthNames;
However you will see that short name for december is "гру" and still not "груд". So to parse your string with default month names for your culture you need to either do:
var dateString = "08 грудень 2017 00:00:06,694";
DateTime date;
DateTime.TryParseExact(dateString, #"dd MMMM yyyy HH:mm:ss,fff", new CultureInfo("uk-UA"), DateTimeStyles.None, out date);
Or
var dateString = "08 гру. 2017 00:00:06,694";
DateTime date;
DateTime.TryParseExact(dateString, #"dd MMM. yyyy HH:mm:ss,fff", new CultureInfo("uk-UA"), DateTimeStyles.None, out date);
Another option is to adjust culture month names for your case, like this (note that it will not modify global culture settings, only month name for this particular CultureInfo instance, so there is no danger in doing this):
var dateString = "08 груд. 2017 00:00:06,694";
DateTime date;
var culture = new CultureInfo("uk-UA");
var defaultShortNames = culture.DateTimeFormat.AbbreviatedMonthNames;
var defaultShortGenitiveNames = culture.DateTimeFormat.AbbreviatedMonthGenitiveNames;
// obviously modify all month names as necessary
defaultShortNames[11] = "Груд";
defaultShortGenitiveNames[11] = "груд";
culture.DateTimeFormat.AbbreviatedMonthNames = defaultShortNames;
culture.DateTimeFormat.AbbreviatedMonthGenitiveNames = defaultShortGenitiveNames;
// store this modified culture and reuse when necessary
// that MMM format consists of 3 letters is irrelevant - it will still
// work fine with abbreviated month names of 4 characters or more
DateTime.TryParseExact(dateString, #"dd MMM. yyyy HH:mm:ss,fff", culture, DateTimeStyles.None, out date);
As others have mentioned, MMMM is the full month name and MMM is the three-character abbreviated month name, so neither will work out of the box. Rather than hard-code month names or modify the CultureInfo, I'd prefer to pre-process the string to truncate the month to the 3 characters parseable with the MMM custom format string, either with regular expressions (heavyweight) or directly:
var sb = new StringBuilder (date.Length) ;
var nc = 0 ;
foreach (var ch in date)
{
if (char.IsLetter (ch) && nc++ >= 3) continue ;
sb.Append (ch) ;
}
return DateTime.ParseExact ("dd MMM. yyyy HH:mm:ss,fff", ...) ;

custom date format parse

I have some date returned from FTP server like this
Aug 28 11:03
Aug 28 18:06
Sep 6 16:03
Im using this code to parse the time
CultureInfo provider = new CultureInfo("en-US");
_fileDateTime = DateTime.ParseExact(timestring, "MMM dd H:mm", provider);
The first two date work, but the last won't. Does any one have better ideas in parsing these kind of date format?
MMM d H:mm will work with Sep 6 16:03 but in my case its Sep 6 16:03 will not work, note the double space between Sep and 6
The first two date work, but the last won't.
That's because you are using dd for date and the last date returned is 6 and not 06. Use Single d. If last date returned was 06 your format would have worked like a charm.
Its should be like
DateTime.ParseExact(timestring, "MMM d H:mm", provider);
There are multiple issues, one is which is already pointed out in other answers i.e. using single d for date since last date is 6 not 06. The other problem with the last date is that it has multiple spaces in between date and month because of that your format which is taking care of dates with single space is not working. You need to first remove the extra space and then parse using format with single d. Try the following code:
string timestring = "Sep 6 16:03";
//string[] array = timestring.Split(" ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
//timestring = string.Join(" ", array);
timestring = System.Text.RegularExpressions.Regex.Replace(timestring, #"\s+", " ");
CultureInfo provider = new CultureInfo("en-US");
DateTime _fileDateTime = DateTime.ParseExact(timestring, "MMM d H:mm", provider);
Use one d so it expects possible single-digit days (ie, "6" instead of "06").
MMM d H:mm

Categories

Resources