I have the following code
public static void Main()
{
DateTime D = new DateTime();
D = DateTime.Now;
string s1 = D.ToString("ddMMMMyyyy");
Console.WriteLine(s1);
Console.WriteLine(DateTime.TryParseExact(s1, "ddMMMyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out D));
Console.ReadKey();
}
Could someone please help me realise the obvious mistake I am making.
I converted DateTime.Now into a string in a custom format and tried to convert it back, but TryParseExact is returning false.
Short answer: MMMM does not equal MMM.
A Sidenote: parsing such strings with CultureInfo.InvariantCulture will only recognize English names, it seems that it will fail on machines with other languages.
Related
I have been trying to convert this string to a DateTime object in C#
2019-09-23T08:34:00UTC+1
I've tried using DateTime.Parse but it is throwing an exception for
"String was not recognized as a valid DateTime."
I'm sorry but you seem like a victim of garbage in, garbage out.
That's an unusual format, that's why before I suggest a solution for you, first thing I want to say is "Fix your input first if you can".
Let's say you can't fix your input, then you need to consider a few things;
First of all, if your string has some parts like UTC and/or GMT, there is no custom date and time format specifier to parse them. That's why you need to escape them as a string literal. See this question for more details.
Second, your +1 part looks like a UTC Offset value. The "z" custom format specifier is what you need for parse it but be careful, this format specifier is not recommended for use with DateTime values since it doesn't reflect the value of an instance's Kind property.
As a solution for DateTime, you can parse it like I would suggest;
var s = "2019-09-23T08:34:00UTC+1";
DateTime dt;
if(DateTime.TryParseExact(s, "yyyy-MM-dd'T'HH:mm:ss'UTC'z", CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal, out dt))
{
Console.WriteLine(dt);
}
which gives you 2019-09-23 07:34:00 as a DateTime and which has Utc as a Kind property.
As a solution for DateTimeOffset - since your string has a UTC Offset value you should consider to parse with this rather than Datetime
-, as Matt commented, you can use it's .DateTime property to get it's data like;
var s = "2019-09-23T08:34:00UTC+1";
DateTimeOffset dto;
if(DateTimeOffset.TryParseExact(s, "yyyy-MM-dd'T'HH:mm:ss'UTC'z", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dto))
{
Console.WriteLine(dto.DateTime);
}
which gives you the same result DateTime but Unspecified as a .Kind property.
But, again, I strongly suggest you to fix your input first.
Use TryParseExact to convert the string to datetime. Here is the sample code to covert the given format(s) to datetime
private static DateTime ParseDate(string providedDate) {
DateTime validDate;
string[] formats = {
"yyyy-MM-ddTHH:mm:ss"
};
var dateFormatIsValid = DateTime.TryParseExact(
providedDate, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out validDate);
return dateFormatIsValid ? validDate: DateTime.MinValue;
}
Then, use this function to convert the string. I am replacing UTC+1 to empty string
static void Main(string[] args) {
string strdatetime = "2019-09-23T08:34:00UTC+1";
DateTime dateTime = ParseDate(strdatetime.Replace("UTC+1", ""));
Console.WriteLine(dateTime);
}
I have a date/time return from a C# method is in string,
string dateTime = "2018-6-18 20:50:35"
Now I would like to convert this into another string representation like,
string convertDT = "2018-6-18 08:50:35 PM"
Is this possible?
Seems like I can do something like,
var formattedTime = dateTime.ToString("h:mm tt", CultureInfo.InvariantCulture);
but not working. Suggestion please!
Just parse the string into a new DateTime object and then call ToString() with the right formats:
string dateTime = "2018-6-18 20:50:35";
DateTime parsedDateTime;
if(DateTime.TryParse(dateTime, out parsedDateTime))
{
return parsedDateTime.ToString("yyyy-M-d hh:mm tt");
}
The benefit of my answer is that it contains validation (DateTime.TryParse()), it results in a couple extra lines of code but you can now accept all input and not worry about an exception being thrown.
Even better would be to refactor this logic into its own method that you can re-use:
public static bool TryChangeDateTimeFormat(string inputDateString, string outputFormat, out string outputDateString)
{
DateTime parsedDateTime;
if(DateTime.TryParse(inputDateString, out parsedDateTime))
{
outputDateString = parsedDateTime.ToString(outputFormat);
return true;
}
outputDateString = string.Empty;
return false;
}
This returns a bool of whether or not the conversion was successful and the out variable will be modified depending on the result.
Fiddle here
Without adding any validation,
var string24h = "2018-6-18 20:50:35";
var dateTime = DateTime.Parse(string24h);
var formattedTime = dateTime.ToString("h:mm tt", CultureInfo.InvariantCulture);
Use DateTime.ParseExact and then ToString
Sure, you can use the DateTime class to parse the original string and then output a differently formatted string for the same date:
string result = DateTime.Parse(dateTime).ToString("h:mm tt", CultureInfo.InvariantCulture);
var dateTime = "2018-6-18 20:50:35";
var dt = Convert.ToDateTime(dateTime);
var amPmDateTime = dt.ToString(#"yyyy-MM-dd hh:mm:ss tt", CultureInfo.InvariantCulture);
To give you exactly your format you would use
string convertDT = DateTime.Parse(dateTime).ToString("yyyy-MM-dd hh:mm:ss tt");
You can change the format between the quotes however you would like. For example yyyy/MM/dd or something. Just remember MM is 2 spots for months and mm is 2 spots for minutes.
So if you put
string convertDT = DateTime.Parse(dateTime).ToString("yyyy-mm-dd hh:mm:ss tt");
You are going to get year - minutes - days.
Using ASP.NET Forms, I'm encountering a problem with converting a 12 hour time into a timespan. Below I'm combining DateTime with TimeSpan as the user chooses a date and then a time. The fields are controlled by javascript.
DateTime DateResult = DateTime.TryParse(txtDate.Text, out DateResult) ? DateResult : DateTime.Today;
TimeSpan TimeResult = TimeSpan.TryParseExact(txtTime.Text, "h:mm tt", CultureInfo.InvariantCulture, out TimeResult) ? TimeResult : new TimeSpan();
DateResult = DateResult.Add(TimeResult)
So parsing the date works fine, but Timespan doesn't. One example:
Date Entered: 08/03/2018
Time Entered: 3:00 AM
Values are gettined passed okay but time fails so DateResult becomes "08/03/2018 00:00" but not "08/03/2018 03:00". I have also tried using the method TimeSpan.TryParse but no luck with that one.
I've also made sure that the format is correct by manually entering the time in the database behind the scenes. The gridview has a column that shows the full date in this format "dd/MM/yyyy h:mm tt", and works.
Anyone please share some light? Ideally, I would like to avoid any third party plug-ins.
Parse them together
Simplest thing is to just concatenate the strings before parsing as a single DateTime, e.g.
var dateEntered = #"08/03/2018";
var timeEntered = #"3:00 am";
DateTime result;
var completeDateString = dateEntered + " " + timeEntered;
var ok = DateTime.TryParse(completeDateString, out result);
if (!ok) result = DateTime.Today;
Console.WriteLine(result);
Output:
8/3/2018 3:00:00 AM
Ta da
If you have to parse them separately
If you'd like to work with the fields separately, you still can (I guess you'd have to do this if you want the time format to be exact but the date portion to be flexible, as it is in your example). But TimeSpan.TryParseExact is really different from DateTime.Parse. The format codes are different; it doesn't support the ":" character (except as a literal with an escape, e.g. "\:"), for example, or the "tt" formatting specifier. I'm guessing the concept of am/pm has to do with an absolute point in time, not a relative time offset, so isn't provided for. But you can still parse the textbox as a DateTime and use its time portion.
You can probably shorten this a bit but this example gives you everything you need:
static public DateTime ParseDateTime(string input)
{
DateTime output;
var ok = DateTime.TryParse(input, out output);
if (ok) return output;
return DateTime.Today;
}
static public TimeSpan ParseTime(string input)
{
DateTime output;
var ok = DateTime.TryParseExact(input, #"h:mm tt", CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.NoCurrentDateDefault, out output);
return output.Subtract(output.Date);
}
public static void Main()
{
var dateEntered = #"08/03/2018";
var timeEntered = #"3:00 am";
DateTime dateResult = ParseDateTime(dateEntered);
TimeSpan timeResult = ParseTime(timeEntered);
DateTime finalResult = dateResult.Add(timeResult);
Console.WriteLine(finalResult);
}
Output:
8/3/2018 3:00:00 AM
Code on DotNetFiddle
See ParseExact or https://msdn.microsoft.com/en-us/library/system.timespan.tryparseexact(v=vs.110).aspx for TryParseExact should work for both DateTime as well as TimeSpan inter alia
Fyi it's called the meridian and see also AM/PM to TimeSpan
I am trying to use DateTime.ParseExact on a timestamp that uses the format M/d/yyyy HH:mm:ss:fff and the compiler is telling me that this is not going to happen.
An example of my timestamp is:
3/26/2013 14:37:05:553
...and an example of my code is, where _CultureInfo is en-us.
DateTime someDateTime = DateTime.ParseExact("3/26/2013 14:37:05:553","M/d/yyyy HH:mm:ss:fff", _CultureInfo.DateTimeFormat);
See below image of what's going on... am I missing something?
New Edit
I've tried a couple more things with still no luck:
Changing :fff to .fff
Changing _CultureInfo.DateTimeFormat to System.Globalization.CultureInfo.InvariantCulture and changing the d to dd as suggested below
Below is something you can throw into a Console and run to see exactly how this is behaving on my end.
class Program
{
static void Main(string[] args)
{
CsvImporter importer = new CsvImporter();
DateTime readtime = importer.Parse(#"""3/26/2013 14:37:07:238,00:00:01.6850000,23.138,23.488,23.175""");
Console.WriteLine(readtime.ToString());
}
}
class CsvImporter
{
public Char[] _SeparatorChars = new Char[] { ',' };
public DateTime Parse(string text)
{
System.Globalization.CultureInfo _CultureInfo = System.Globalization.CultureInfo.CurrentCulture;
string txt = text.Replace('"', ' ');
string[] columns = txt.Split(_SeparatorChars);
return DateTime.ParseExact(columns[0], "M/dd/yyyy HH:mm:ss:fff", _CultureInfo.DateTimeFormat);
//return DateTime.ParseExact(columns[0], "M/dd/yyyy HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture);
}
}
Try this (Changed d to dd and CultureInfo.InvariantCulture )
DateTime someDateTime = DateTime.ParseExact("3/26/2013 14:37:05:553", "M/dd/yyyy HH:mm:ss:fff", CultureInfo.InvariantCulture);
The issue is with string txt = text.Replace('"', ' ');
This is turning column[0] into [space]3/26/2013 14:37:05:553 instead of 3/26/2013 14:37:05:553 like I'd expect.
Changing this line to string txt = text.Replace(#"""", ""); solves the problem.
Whenever you call ParseExact, make sure you're using an unambiguous format string. In .NET, the / character in a format string is the system date separator, not an actual slash. Same for the : character in times.
To parse a string with your structure, escape out the slashes and colons with backslashes, like:
DateTime.ParseExact(s, #"M\/d\/yyyy HH\:mm\:ss\:fff", null)
// or
DateTime.ParseExact(s, "M\\/d\\/yyyy HH\\:mm\\:ss\\:fff", null)
This will tell the parser that you specifically want the forward-slash and colon, regardless of your system preferences or current culture.
The following case:
There is a string that has this format "2012-02-25 07:53:04"
But in the end, i rather want to end up with this format "25-02-2012 07:53:04"
I think i have 2 options. 1 would be to reformat the string and move it all around, but i dont think this is a clean way of doing this.
A other way that i was thinking about is to save the source string to a date parameter, and then write the date parameter back to a string in a certain date format.
But is this even possible to do ?
Do this:
DateTime.Parse("2012-02-25 07:53:04").ToString("dd-MM-yyyy hh:mm:ss");
Keep in mind this isn't culture-aware. And if you do need to store the intermediate result you could do that just as easily:
var myDate = DateTime.Parse("2012-02-25 07:53:04");
var myDateFormatted = myDate.ToString("dd-MM-yyyy hh:mm:ss");
Lastly, check out TryParse() if you can't guarantee the input format will always be valid.
Others have suggested using Parse - but I'd recommend using TryParseExact or ParseExact, also specifying the invariant culture unless you really want to use the current culture. For example:
string input = "2012-02-25 07:53:04";
DateTime dateTime;
if (!DateTime.TryParseExact(input, "yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out dateTime))
{
Console.WriteLine("Couldn't parse value");
}
else
{
string formatted = dateTime.ToString("dd-MM-yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
Console.WriteLine("Formatted to: {0}", formatted);
}
Alternatively using Noda Time:
string input = "2012-02-25 07:53:04";
// These can be private static readonly fields. They're thread-safe
var inputPattern = LocalDateTimePattern.CreateWithInvariantInfo("yyyy-MM-dd HH:mm:ss");
var outputPattern = LocalDateTimePattern.CreateWithInvariantInfo("dd-MM-yy HH:mm:ss");
var parsed = inputPattern.Parse(input);
if (!parsed.Success)
{
Console.WriteLine("Couldn't parse value");
}
else
{
string formatted = outputPattern.Format(parsed.Value);
Console.WriteLine("Formatted to: {0}", formatted);
}
Parse as DateTime then reformat it. Be careful: use always an IFormatProvider!
Yes, it is quite possible. All you need to do is use DateTime.Parse to parse the string into a DateTime struct and then use ToString() to write the date back out to another string with the format you want.
You can parse this as a date object and then provide the formatting you want when using the date.ToString method:
date.ToString("dd-MM-yyyy hh:mm:ss");
Yes, you can use custom DateTime format strings to parse and reformat DateTime objects.
DateTime date = DateTime.ParseExact("2012-02-25 07:53:04", "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
string formattedDated = date.ToString("dd-MM-yyyy HH:mm:ss");