I get from an web service a date which is written like that :
"Tuesday, November 12, 2013 8:18:14 AM PST"
or
"Tuesday, November 12, 2013 10:36:03 AM PST"
or
"Wednesday, November 13, 2013 5:15:58 AM PST"
...
This date is stored inside an Array and I would like to sort it. But It does not work properly. So I would like to store this written date in a DateTime or another format supported by the language. Than sort it again. I could be also easier to get only days and hours from a DateTime than using a strstr or something like that.
Is it possible (and how) to convert this written date into a DateTime please ?
PS: I already tried using Convert.DateTime("Wednesday, November 13, 2013 5:15:58 AM PST"). But It didn't work.
Thanks
You need to parse it with format "dddd, MMMM d, yyyy h:m:ss tt 'PST'"
string str = "Wednesday, November 13, 2013 5:15:58 AM PST";
DateTime dt = DateTime.ParseExact(str,
"dddd, MMMM d, yyyy h:m:ss tt 'PST'",
CultureInfo.InvariantCulture);
I have used single d, h and m, for day, hour and month since they will accept both single digit and double digits values.
Becuase Convert.DateTime uses current culture information.
The value argument must contain the representation of a date and time
in one of the formats described in the DateTimeFormatInfo topic.
You can use DateTime.ParseExact method with custom datetime format instead.
string s = "Wednesday, November 13, 2013 5:15:58 AM PST";
DateTime dt = DateTime.ParseExact(s,
"dddd, MMMM d, yyyy h:mm:ss tt 'PST'",
CultureInfo.InvariantCulture);
Console.WriteLine(dt);
Output will be;
11/13/2013 5:15:58 AM
Here a demonstration.
For more informations, take a look at;
Custom Date and Time Format Strings
If the date will always end with a 3 letter timezone abbreviation the following will work:
string str = "Wednesday, November 13, 2013 5:15:58 AM PST";
DateTime date = DateTime.Parse(str.Substring(0, str.Length - 4));
Related
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
My C# project is taking xml and extracting pertinent data, one of which pieces is a date time value. The following code works correctly on my desktop running Win8.1 and .NET4. However when I run it through mono, it's failing to parse the data.
using glob = System.Globalization;
DateTimeOffset dt = DateTimeOffset.MinDate;
string[] fmts = new string[]
{
"MMM dd, yyyy hh:mm tt EDT",
"MMM dd, yyyy hh:mm tt EST",
"MMM dd, yyyy hh:mm tt CDT",
"MMM dd, yyyy hh:mm tt CST",
"MMM dd, yyyy hh:mm tt MDT",
"MMM dd, yyyy hh:mm tt MST",
"MMM dd, yyyy hh:mm tt AKST",
"MMM dd, yyyy hh:mm tt AKDT",
"MMM dd, yyyy hh:mm tt HST",
"MMM dd, yyyy hh:mm tt PST",
"MMM dd, yyyy hh:mm tt PDT"
};
var dtString = z.Substring(pos1 + 5, pos2 - pos1 - 1 - 5).Replace("ft", "").Trim();
dtString = dtString.Substring(0, 1).ToUpper() + dtString.Substring(1);
dtString = dtString.Substring(0, dtString.Length - 7)
+ dtString.Substring(dtString.Length - 7).ToUpper();
DateTimeOffset.TryParseExact(dtString, fmts,
glob.CultureInfo.InvariantCulture, glob.DateTimeStyles.None, out dt);
To check if the conversion worked ok, I do this:
if (dt == DateTimeOffset.MinDate)
Console.WriteLine("failed to convert dt = MinValue -> " + dtString);
Here's an example of the data string being processed:
raw: mar 21, 2015 10:30 am cdt
after my formatting: Mar 21, 2015 10:15 AM CDT
It's not specific to the CDT tz - I get the same issue for all timezones.
When I run $ date on the Linux box, it's reporting the same date, time and tz as my desktop, in this format (Mon Mar 23 11:31:16 EDT 2015).
The section is wrapped in a try/catch, but no exceptions are being thrown (also have Console output in there).
I can code around it by changing the string around before TryParse, but it would seem this method was designed so that this is not necessary.
Is this a bug (or am I missing something)? If so where does one report them?
Thanks
A few points:
In the code you posted, the part where you manipulate the dtString variable is meaningless to us, because you didn't include values for pos1 or pos2. It seems quite messy, and in general - that sort of manipulation should be avoided if possible. I'm not sure what it has to do with your question, if anything.
You are using the TryParseExact method, which returns a boolean true on success - so the comparison check is unnecessary. (Also, the field is called MinValue, not MinDate)
Time zone abbreviations are not valid in format strings. The letters in the string could be confused with actual custom formatting values. If you wanted to exclude them, you would place them in single-tick or double-tick quotation marks.
In general, time zone abbreviations should not be used for input. There are just too many ambiguities. For example, this list of abbreviations shows 5 possible interpretations of "CST".
The parsers that come with the DateTime and DateTimeOffset types do not understand time zone abbreviations at all. You claim it works fine on your desktop under .NET 4, but I call BS.
As you can see, it did not interpret the offset as CDT (-05:00). Instead it took the local time zone from my computer, which happens to be PDT (-07:00).
The correct way to deal with this is to parse the date input as a DateTime, then use some other mechanism to determine the offset. If you MUST use the time zone abbreviation, and you are absolutely sure you only have the time zones you showed above, and they're all from the united states, then it would go something like this:
// define the list that you care about
private static readonly Dictionary<string, TimeSpan> Abbreviations = new Dictionary<string, TimeSpan>
{
{"EDT", TimeSpan.FromHours(-4)},
{"EST", TimeSpan.FromHours(-5)},
{"CDT", TimeSpan.FromHours(-5)},
{"CST", TimeSpan.FromHours(-6)},
{"MDT", TimeSpan.FromHours(-6)},
{"MST", TimeSpan.FromHours(-7)},
{"PDT", TimeSpan.FromHours(-7)},
{"PST", TimeSpan.FromHours(-8)},
{"AKDT", TimeSpan.FromHours(-8)},
{"AKST", TimeSpan.FromHours(-9)},
{"HST", TimeSpan.FromHours(-10)}
};
static DateTimeOffset ParseInput(string input)
{
// get just the datetime part, without the abbreviation
string dateTimePart = input.Substring(0, input.LastIndexOf(" ", StringComparison.Ordinal));
// parse it to a datetime
DateTime dt;
bool success = DateTime.TryParseExact(dateTimePart, "MMM dd, yyyy hh:mm tt",
CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
// handle bad input
if (!success)
{
throw new ArgumentException("Invalid input string.", "input");
}
// get the abbreviation from the input string
string abbreviation = input.Substring(input.LastIndexOf(" ", StringComparison.Ordinal) + 1)
.ToUpperInvariant();
// look up the offset from the abbreviation
TimeSpan offset;
success = Abbreviations.TryGetValue(abbreviation, out offset);
if (!success)
{
throw new ArgumentException("Unknown time zone abbreviation.", "input");
}
// apply the offset to the datetime, and return
return new DateTimeOffset(dt, offset);
}
Now it will return the correct output:
string dtString = "Mar 21, 2015 10:15 AM CDT";
DateTimeOffset dto = ParseInput(dtString);
Console.WriteLine(dto);
Also note that if you were really trying to cover all legal US time zones, you should also consider adding HAST, HADT, CHST, SST, and AST to the list.
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.
How can I convert the following strings to a System.DateTime object?
Wednesday 13th January 2010
Thursday 21st January 2010
Wednesday 3rd February 2010
Normally something like the following would do it
DateTime dt;
DateTime.TryParseExact(value, "dddd d MMMM yyyy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dt);
but this doesn't work because of the 'th', 'st' or 'rd' in the string
Update
It appears that DateTime doesn't support formatting the 'th', 'st', 'rd' etc so they need to be stripped before parsing. Rubens Farias provides a nice regular expression below.
What about strip them?
string value = "Wednesday 13th January 2010";
DateTime dt;
DateTime.TryParseExact(
Regex.Replace(value, #"(\w+ \d+)\w+ (\w+ \d+)", "$1 $2"),
"dddd d MMMM yyyy",
DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.None, out dt);
Another approach.
string sDate = "Wednesday 13th January 2010";
string[] sFields = sDate.Split (' ');
string day = sFields[1].Substring (0, (sFields[1].Length - 2));
DateTime date = new DateTime (sFields[3], sFields[2], day);
Another alternative using escape characters for handling (st, nd, rd, and th) without stripping them before the call of DateTime.TryParseExact
string dtstr = "Saturday 23rd January 2016";
DateTime dt;
string[] formats = new string[] {
"dddd d\\s\\t MMMM yyyy", "dddd d\\n\\d MMMM yyyy",
"dddd d\\r\\d MMMM yyyy", "dddd d\\t\\h MMMM yyyy" };
bool result = DateTime.TryParseExact(dtstr, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
Where does "th", "st","nd" or "rd" appear below?
monday
tuesday
wednesday
thursday
friday
saturday
sunday
january
february
march
april
may
june
july
august
september
october
november
december
However you know those 4 will always be followed by a space. So unless I've missed something, a simple
value = value.Replace("August","Augus").Replace("nd ","").Replace("st ","").Replace("nd ","").Replace("rd ","").Replace("Augus","August");
DateTime dt;
DateTime.TryParseExact(value,"DDDD dd MMMM yyyy", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dt);
No credit to me but this looks interesting for general DataTime parsing: http://www.codeproject.com/KB/datetime/date_time_parser_cs.aspx?msg=3299749
I remembered this post on using MGrammar to parse a lot of different ways to express dates and times. It doesn't exactly answer your question, but it might serve as a useful base depending on what your ultimate goal is.
Expanding on Kenny's approach, I added some code to pass integers to the DateTime variable...
string sDate = "Wednesday 13th January 2010";
string[] dateSplit = sDate.Split (' ');
string day = dateSplit[1].Substring(0, dateSplit[1].Length - 2);
int monthInDigit = DateTime.ParseExact(dateSplit[3], "MMMM", CultureInfo.InvariantCulture).Month;
DateTime date = new DateTime(Convert.ToInt16(year), monthInDigit, day);