This question already has answers here:
unable to parse a string of this format "1/29/2020 12:00:00 AM" into a valid DateTime
(2 answers)
Closed 2 years ago.
I have these 2 string values:
Test1 = "2020-01-29T00:00:00Z"
Test2 = "29/01/2020 00:00:00"
and I am doing this comparison:
(DateTime.ParseExact(Test2.ToString(), "dd/M/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture).ToString("yyyy'-'MM'-'dd'T'00':'00':'00'Z'") != (DateTime.ParseExact(Test1["ProjectDateSinged"].ToString(), "yyyy'-'MM'-'dd'T'00':'00':'00'Z'", CultureInfo.InvariantCulture)).ToString()))
but this will raise the following exception:
Error “String was not recognized as a valid DateTime”
Could anyone find what is wrong with my code?
Expanding my comment into answer, you should update your format string a little bit. For Test2 you should use dd/MM/yyyy hh:mm:ss format.
According to Custom date and time format strings MM is used for month number from 01 to 12, M from 1 to 12. You have 01 month number, so MM should be used.
There is also no AM/PM representation in your date, so tt is not needed as well
Them you'll be able to parse Test2 into the date.
var Test2 = "29/01/2020 00:00:00";
var result = DateTime.ParseExact(Test2, "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture);
For the Test1 you can use yyyy-MM-ddThh:mm:ssK (parse the date including time zone information) or yyyy-MM-ddThh:mm:ss'Z' without time zone information.
To compare the dates you don't need to convert them back to string. You can simply get the date component using Date property of DateTime struct. The code below returns true
var result = DateTime.ParseExact(Test1, "yyyy-MM-ddThh:mm:ss'Z'", CultureInfo.InvariantCulture).Date ==
DateTime.ParseExact(Test2, "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture).Date;
as well as this, by comparing two DateTime instances only
var result = DateTime.ParseExact(Test1, "yyyy-MM-ddThh:mm:ss'Z'", CultureInfo.InvariantCulture) ==
DateTime.ParseExact(Test2, "dd/MM/yyyy hh:mm:ss", CultureInfo.InvariantCulture);
string Test1 = "2020-01-29T00:00:00Z";
string Test2 = "29/01/2020 00:00:00";
DateTime dt = Convert.ToDateTime(Test1, CultureInfo.InvariantCulture);
MessageBox.Show("" + dt.ToString("yyyy-MM-ddT00:00:00Z"));
Used this code then successfully work
By looking at your examples, the formats looks below.. You can write a generalized method by specifying formats. something like below -
private static DateTime ParseDate(string providedDate)
{
DateTime validDate;
string[] formats = { "dd/MM/yyyy hh:mm:ss", "yyyy-MM-dd'T'hh:mm:ss'Z'" };
var dateFormatIsValid = DateTime.TryParseExact(
providedDate,
formats,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out validDate);
return dateFormatIsValid ? validDate : DateTime.MinValue;
}
And call this method to parse the string
var test1 = ParseDate("2020-01-29T00:00:00Z");
var test2 = ParseDate("29/01/2020 00:00:00");
Console.WriteLine(test1 == test2); // result TRUE
Related
I am trying this code (c#):
string input1 = "2009-11-22 01:01:05 +1:30"
string input2 = "2009-11-22 01:01:05"
DateTime date1 = new DateTime();
DateTime date2 = new DateTime();
string format = "yyyy-MM-dd hh:mm:ss [z]"
DateTime orgDate1 = DateTime.ParseExact(input1, format, null);
DateTime orgDate2 = DateTime.ParseExact(input2, format, null);
The purposes are:
recognize the term "[z]" as optional parameter so both input1 and input2 will be parsed correctly.
To get valid DateTime parsed values in orgDate1 and orgDate2.
The problem:
I don't manage to get parsed values, even if ignore the optional requirement:
string input1 = "2009-11-22 01:01:05 +1:30"
DateTime date1 = new DateTime();
string format = "yyyy-MM-dd hh:mm:ss zzz"
DateTime orgDate1 = DateTime.ParseExact(input1, format, null);
I tried many options, like:
DateTime.ParseExact("2009-11-22 00:00:00 1", "yyyy-MM-dd hh:mm:ss z",null)
DateTime.ParseExact("2009-11-22 00:00:00 1", "yyyy-MM-dd hh:mm:ss Z",null)
But always get formatException.
Only this code works:
DateTime.ParseExact("2009-11-22 00:00:00Z", "yyyy-MM-dd hh:mm:ssZ",null)
But it returns the exact UTC time zone while I need to get it as parameter.
all is described above
Ok, after several trials I find that following code works:
DateTime.ParseExact("2009-11-22 00:00:00+1", "yyyy-MM-dd hh:mm:ss z",null)
So remain the other Q - how can I define the format with optional timezone, such that both "2009-11-22 00:00:00+1" and "2009-11-22 00:00:00" will be parsed properly?
edit: since I've had so many comments regarding utilising TryParseExact with a single format instead of an array:
I must test all of the formats within the array - the inputs can potentially be these formats, and my unit tests for these other formats actually work. I MUST use them all.
I am aware that DateTime.TryParse would match the first and not iterate further. Hence I am using TryParseExact as Microsoft shows. It should match exactly. BUT it doesn't work in this scenario.
TLDR: Given a string of the format "dd/MM/yyyy" with value "29/11/2019" DateTime.TryParseExact returns a match with the format "dd/MM/yyyy hh:mm tt" and value 29/11/2019 12:00 AM. Why?
Question: How can I ensure a string of the format "dd/MM/yyyy" returns as a match with the format "dd/MM/yyyy" instead of "dd/MM/yyyy hh:mm tt" when using TryParseExact?
The long explanation of Context;
I have the following problem. I need to parse multiple date formats from strings to datetime values. They (input strings) can appear in the following formats:
{ "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};
To solve this, I wrote a string extension that parses a given input string and returns a bool success and a potential matching format.
private static readonly string[] _DateFormats = new string[] { "dd/MM/yyyy hh:mm tt", "dd/M/yyyy hh:mm tt", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:mm", "dd/MM/yyyy H:m", "dd/MM/yyyy", "dd-MM-yyyy", "d-M-yyyy", "dddd, d MMMM yyyy"};
public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
{
matchingFormat = ""; // defaults
dateTimeValue = new DateTime();
if (string.IsNullOrEmpty(dateTimeString)) return false;
foreach (string format in DateFormats)
{
matchingFormat = format;
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue)) return true;
}
return false;
}
This returns the string input "29/11/2019 successfully" as the DateTime 29/11/2019 12:00 AM with the matching format as "dd/MM/yyyy hh:mm tt", rather than the format matching the original input 29/11/2019.
Given this issue, the only (duct-tape) solution I could think of is:
public static bool StringToDateTime(this string dateTimeString, out DateTime dateTimeValue, out string matchingFormat)
{
matchingFormat = ""; // defaults
dateTimeValue = new DateTime();
if (string.IsNullOrEmpty(dateTimeString)) return false;
foreach (string format in DateFormats)
{
matchingFormat = format;
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
{
// ensure the datetime format is consistent with the dateTimeString passed to us.
if(dateTimeString.Length != matchingFormat.Length)
{
var _matchingFormat = DateFormats.First(d => d.Length == dateTimeString.Length);
matchingFormat = string.IsNullOrEmpty(_matchingFormat) ? matchingFormat : _matchingFormat;
}
return true;
}
}
return false;
}
Which works, but obviously, this has further issues (begetting the formatting of input, etc.). So I'd rather not use this.
System.DateTime cannot exist without the time component, so it's no possible to parse a date to DateTime and not the time component. It will default to the start of day e.g. 12:00 AM, which is the same result as calling dateTime.Date(). This will allow you to compare two dates without considering the time of day.
If having or storing the time element really bothers you then you can either create your own struct to store the date or consider using something like NodaTime that provides a date only struct.
Also, Dotnet 6 will introduce DateOnly and TimeOnly structs to do exactly this. You can read more about it on the MS devblogs.
You are passing the whole array of formats, so it will match any of them.
Since you are in a foreach over DateFormats, you only need to match against the current value.
So replace this line
if (DateTime.TryParseExact(dateTimeString, DateFormats, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;
with this
if (DateTime.TryParseExact(dateTimeString, format, AUSCulture, DateTimeStyle, out dateTimeValue))
return true;
I have a list of DateTime as strings: dd.MM.yyyy H:mm:ss (The time is 24 hours format but the hour is single digit: 6 instead of 06)
14.12.2016 6:20:21
15.12.2016 8:30:00
16.12.2016 12:30:00
17.12.2016 14:33:00
18.12.2016 18:10:00
I am trying to parse exact the string values as a DateTime object like this:
DateTime.ParseExact(dt, "dd.MM.yyyy H:mm:ss", CultureInfo.InvariantCulture) (dt is the string value from the list)
The problem is I get an error saying the string is not a valid DateTime ...
With the current format, the first and second values in the list work fine, when it get's to the third 'boooom' I get the error.
Am I missing something in my format?
Use the overload of DateTime.ParseExact that accepts an array of valid formats:
string[] formats = { "dd.MM.yyyy H:mm:ss", "dd.MM.yyyy HH:mm:ss" };
var result = DateTime.ParseExact(dt, formats, CultureInfo.InvariantCulture, 0);
UPDATE: As others have noted, H should match both one-digit and two-digit hours, so something else is going on. The following code runs successfully on my system (.NET 4.5.2):
string dt = "16.12.2016 12:30:00";
var result = DateTime.ParseExact(dt, "dd.MM.yyyy H:mm:ss", CultureInfo.InvariantCulture);
I had to parse exact the using Hour, Minute, and Second then use the ToString method to convert to a Month, day, and year format
$myStringDate=[Datetime]::ParseExact($item.myDateObject,'MM/dd/yyyy H:mm:ss',$null).ToString('MM/dd/yyyy')
In my application , i have a control which is displaying current time in HH:mm:ss format. My question is if format is HH mm ss then, how this format is converted back to HH:mm:ss format
ex
03-08-2016 10:30:45 ==> my required format
03-08-2016 10 30 45 ==> current format. or it may be any other format
How can i get required format?...
DateTime class has a .ToString() method which accepts format string as it's argument. Please have a look at this
You can get your required format as follows:
var now = DateTime.Now;
var formattedDate = now.ToString("dd-MM-yyyy HH mm ss");
Let the dateInput be the date time object, and the dateFormatString be the required format. then you can use the .ToString() method to get the formatted date string; This can be achieved by using the following code:
string dateFormatString="dd-MM-yyyy HH:mm:ss";
string formattedDateString = dateInput.ToString(dateFormatString);
Suppose your current date time format dd-MM-yyyy HH mm ss like 03-08-2016 10 30 45 then you can convert your current format to dd-MM-yyyy HH:mm:ss as follow
var dt = DateTime.ParseExact("03-08-2016 10 30 45", "dd-MM-yyyy HH mm ss", CultureInfo.InvariantCulture);
string newdate = dt.ToString("dd-MM-yyyy HH:mm:ss");
using same mechanism you can convert any format to another
Let's say you can get the string value from your control that displays in MM-dd-yyyy HH mm ss format, you can use DateTime.ParseExact Method to convert it back to a DateTime variable.
var datetime = DateTime.ParseExact(controlDT.Text, "MM-dd-yyyy HH mm ss", CultureInfo.InvariantCulture);
var newDateTimeString = datetime.ToString("MM-dd-yyyy HH:mm:ss");
Easy way around. Try this:
DateTime date = DateTime.Now;
string dt = date.ToString("dd-MM-yyyy HH:mm:ss");
The output produced will be (as per your required format):
03-08-2016 05:25:47
Convert like this:
var date= DateTime.Now;
var Yourrequeired= date.ToString("dd-MM-yyyy HH: mm: ss");
private string format = "dd/MM/yyyy HH:mm:ss";
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format, CultureInfo.InvariantCulture);
I am getting error when executing this line string was not recognized as a Valid Date Time.
I have tried this also but it not works
DateTime fromdate = DateTime.ParseExact(GetFromScanDateTextBox.Text, format,null);
Your format string must be "d/M/yyyy", take a look at this.
Basically
MM : The month, from 01 through 12.
while
M : The month, from 1 through 12.
The same for the day part.
You are telling DateTime.ParseExact that you are expecting a string with format dd/MM/yyyy HH:mm:ss but you are giving it a string with format d/M/yyyy.
You need to change your format to just d/M/yyyy.
Also I suggest using DateTime.TryParseExact to verify the validity of your string instead of using exceptions.
var okay = DateTime.TryParseExact(
input,
new[] { "dd/MM/yyyy HH:mm:ss", "d/M/yyyy" },
new CultureInfo("en-GB"),
DateTimeStyles.None,
out dateTime);
If your input string is liable to change, TryParseExact allows you to define multiple formats as shown above, or alternatively, if it is always going to be with your current culture, just do DateTime.TryParse and do away with defining the format.
var okay = DateTime.TryParse(input, out dateTime);
If your format is always month/date/year and particularly in this case(if your date is 3rd Sept 2013) you can use:
string format = "MM/dd/yyyy";
string dateTime = "9/3/2013";
dateTime = (dateTime.Split('/')[0].Length == 1 ? "0" + dateTime.Split('/')[0] : dateTime.Split('/')[0]) + "/" + (dateTime.Split('/')[1].Length == 1 ? "0" + dateTime.Split('/')[1] : dateTime.Split('/')[1]) + "/" + dateTime.Split('/')[2];
DateTime fromdate = DateTime.ParseExact(dateTime, format, CultureInfo.InvariantCulture);
Do not provide the HH:MM:SS part in the format part
string format = "dd/MM/yyyy";
DateTime fromdate = DateTime.ParseExact(test.Text, format, CultureInfo.InvariantCulture);