Unable to convert a string to DateTime? - c#

Inside a function, I need to find the difference between 2 dates in seconds. If the difference is more than 30 seconds i return False otherwise it returns True , first one I read it from database and Second one is the current DateTime.Now
Here is the snippest of code I'm using that does the work while dr.GetValue(0).ToString() holds the current value in the database :
if (dr.Read())
{
DateTime nowDate = Convert.ToDateTime(DateTime.Now.ToString("M/dd/yyyy H:mm:ss tt"));
DateTime then = DateTime.ParseExact(dr.GetValue(0).ToString(), "M/dd/yyyy H:mm:ss tt", CultureInfo.InvariantCulture);
TimeSpan diff = nowDate - then;
int timeDifference = diff.Seconds;
if (timeDifference > 30)
{
myConn.Dispose();
return false;
}
else {
myConn.Dispose();
return true;
}
}
When i execute the code above i get a message error : string was not recognized as valid DateTime
And here is the line that is causing the error :
DateTime then = DateTime.ParseExact(dr.GetValue(0).ToString(), "M/dd/yyyy H:mm:ss tt", CultureInfo.InvariantCulture);
The time is stored in the database in this format : 2013-02-18 14:06:37
But when I execute the following line (for debugging purposes) :
MessageBox.Show(dr.GetValue(0).ToString());
I see a message box that shows the date in this format : 2/18/2013 2:06:37 PM
How to find the difference in seconds between the current time and the time stored in dr.GetValue(0).ToString()
Any help would be highly appreciated

You want h, not H. h is the hour in 12-hour format, H is the hour in 24-hour format. Since your example hour is 2 PM (not 14 PM) it's the 12-hour format you want.
Also:
You're converting your now-time to a string and back - don't bother!
You're counting Seconds not TotalSeconds - this is incorrect because e.g. a 60-second period gives a Seconds value of 0.
DateTime nowDate = DateTime.Now;
DateTime then = DateTime.ParseExact(
dr.GetValue(0).ToString(), "M/dd/yyyy h:mm:ss tt",
CultureInfo.InvariantCulture);
TimeSpan diff = nowDate - then;
double secondsDifference = diff.TotalSeconds;
You should even be able to do something along the lines of
DateTime then = dr.GetDateTime(0);
and avoid the string-parsing altogether, but the H/h difference is the reason you get the specific exception you asked about.

if, as it looks like, your date is a datetime in the database, you can probably simplify the two lines to this:
DateTime nowDate = DateTime.Now;
DateTime then = (DateTime)dr.GetValue(0);
(although I'm making a lot of assumptions here)

Your code really should be very simple:
if (dr.Read())
{
DateTime then = dr.GetDateTime(0);
TimeSpan diff = DateTime.Now - then;
int timeDifference = diff.TotalSeconds;
}
One thing to note - you really shouldn't be calling myConn.Dispose(); in your if/else. Wrap your connection and readers in a using statement.

I think your server has Application server has some other date format set. What you can try is this:
Convert.ToDate(value,System.Globalization.CultureInfo.GetCultureInfo("en-US").DateTimeFormate);
Hope this will solve the error.Haven't tested it so hope for best

Related

Convert DateTime 1/20/2022 8:48:30 PM to 20/01/2022 8:48:30 PM C#

I basically have two DateTime variables
DateTime dateToday = WorldTimeAPI.Instance.GetCurrentDateTime();
DateTime dateFinish;
dateToday gets current date from the web, with this format 1/20/2022 8:48:30 PM.
dateFinish has this other format 20/01/2022 8:48:30 PM, the day first, and then the month, everything else is the same.
I want to be able to parse one of them to match the other one in terms of format so that I can compare them both to know if todays date is greater than date finish by doing this:
if(dateToday.CompareTo(dateToEndMission) > 0)
{do stuff}
I tried looking at documentation but it has so many different formats that I just couldnt figure out the exact way to do it.
To compare two dateTime values in an if statement you can do:
if(firstDate.Date > secondDate.Date)
{
//Do something...
}
Try and keep things as simple as possible.
As stated above you can compare date time with the > operator. But I would go further and ask why you're using that api to get the current date and time when you could just use this
DateTime today = DateTime.Now;
This should fix your problem, because you should be initialising date time in the same way now. If not, then I suggest you take a look at this other questions answers:
Convert DateTime to a specified Format
You can try the ParseExact method
DateTime dateToday = DateTime.Now;
DateTime dateFinish = DateTime.ParseExact("20/01/2022 10:56:09", "dd/MM/yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
if (dateToday > dateFinish)
{
// do something
}

Convert 12 hour time to Timespan C#

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

DateTime.Parse - changes format

I'll try to illustrate an example:
var dateNow = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
produces: 10/01/2014 21:50:34
var dateNowParse = DateTime.Parse(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"));
produces: 10/01/2014 9:50:34 PM
QUESTION:
How to parse the date, and keep formatting like: dd/MM/yyyy HH:mm:ss, with an 24 hour format, without any PM
Thank you!
Update 1
Sorry maybe my question wasn't so clear, i'll try to explain the real situation below.
Please do not focus on real meaning of DateTime.Now, suppose we have a string variable in the format of 10/01/2014 21:50:34, and then I try to parse it, and store the result in another variable. What I am willing to achieve is to keep the result in a DateTime variable which has the exact formatting 10/01/2014 21:50:34.
Now here is a snippet:
var stringDate = "10/01/2014 22:50:30";
DateTime parsedDate = DateTime.Parse(stringDate, CultureInfo.InvariantCulture);
//parsedDate result is: 10/01/2014 10:50:30 PM
What is frustrating me is:
In the stringDate the 22:50 hour says that the string is formatted to the 24 hour clock. (the 12 clock format uses hours counter up to 12)
If I used 22:50, Isn't logically that the output should'nt use any AM PM and 12 hour format?
How to parse the date, and keep formatting
You need to keep the format alongside the DateTime if you want to. A DateTime does not have any concept of being in a particular format. The value of the DateTime returned by Parse isn't "10/01/2014 9:50:34 PM" - it's that particular date and time, but not a string representation.
You could have a type which maintains the two together - or if you always want to format in the same way, just specify that format explicitly when you format, without keeping it as data with the DateTime value.
Personally I would try to stick to DateTime.ParseExact where feasible, as I find it easier to predict what it will do - but it does depend on your input. If it's input with a particular format that you're expecting, ParseExact really is the way forward, potentially with the invariant culture to avoid any cultural differences.
I would store the date now as a date
DateTime dateNow = DateTime.Now;
then when you need to display it with that formatting
String strNow = dateNow.ToString("dd/MM/yyyy HH:mm:ss");
If you have a date coming in with a format say in a String variable strNow and want to put it in the DateTime I would make sure to catch format exceptions
DateTime dateNow;
try {
dateNow = DateTime.ParseExact(strNow, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);
}
catch (FormatException) {
//Log something or set a default date.
}
DateTime.ParseExact(DateTime, Format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite);
for example:
DateTime.ParseExact(strNow, "dd/MM/yyyy HH:mm:ss", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite);

How I can get the difference by time string and Datetime now?

i want to calculate a checktime to the time now and get the hours.
I have a string "time" for example...
Jun 06 2013 07:23:06
and with DateTime.Now I get the Time now. The Problem is now that i can't calculate the difference :(
I need them in my Project where I get from the License Server the time from a user and I want to show the difference to now. I want show this in hours.
You can use the Parse method of the DateTIme class to parse a string as a date and the subtract that from now.
TimeSpan diff = DateTime.Now - DateTime.Parse(dateString);
var hours = diff.Hours
The above exsmple of course requires the date to be in a specific format. You can if needed use DateTIme.ParseExact and specify a specific format yourself
You need to first convert your string to DateTime. here you have custom format so you can use DateTime.ParseExact or DateTime.TryParseExact method as below
DateTime dt;
if (DateTime.TryParseExact("Jun 06 2013 07:23:06", "MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
// get difference
var inDays = (DateTime.Now - dt).Days;
}
You can use TimeSpan.Hours property like;
Gets the hours component of the time interval represented by the
current TimeSpan structure.
string dateString = "Jun 06 2013 07:23:06";
var differenceHours = (DateTime.Now - DateTime.Parse(dateString)).Hours;
Console.WriteLine(differenceHours);
Here a DEMO.
If you want to convert your custom formatted string to DateTime, you can use DateTime.ParseExact which need exact format matching between string and datetime.
Converts the specified string representation of a date and time to its
DateTime equivalent. The format of the string representation must
match a specified format exactly or an exception is thrown.
u may try it
DataTime diff = DateTime.Now - Convert.ToDataTime(dateString);
var hours = diff.Hours

Convert time span value to format "hh:mm Am/Pm" using C#

I have a value stored in variable of type System.TimeSpan as follows.
System.TimeSpan storedTime = 03:00:00;
Can I re-store it in another variable of type String as follows?
String displayValue = "03:00 AM";
And if storedTime variable has the value of
storedTime = 16:00:00;
then it should be converted to:
String displayValue = "04:00 PM";
You can do this by adding your timespan to the date.
TimeSpan timespan = new TimeSpan(03,00,00);
DateTime time = DateTime.Today.Add(timespan);
string displayTime = time.ToString("hh:mm tt"); // It will give "03:00 AM"
Very simple by using the string format
on .ToSTring("") :
if you use "hh" ->> The hour, using a 12-hour clock from 01 to 12.
if you use "HH" ->> The hour, using a 24-hour clock from 00 to 23.
if you add "tt" ->> The Am/Pm designator.
exemple converting from 23:12 to 11:12 Pm :
DateTime d = new DateTime(1, 1, 1, 23, 12, 0);
var res = d.ToString("hh:mm tt"); // this show 11:12 Pm
var res2 = d.ToString("HH:mm"); // this show 23:12
Console.WriteLine(res);
Console.WriteLine(res2);
Console.Read();
wait a second, there is a catch, the system Culture !!, the same code executed on windows set to different language
especially with different culture language will generate different result.
for example in windows set to Arabic language the result Will be like this :
// 23:12 م
م means Evening (first letter of مساء) .
in windows set to German language i think it will show // 23:12 du.
you can change between different format on windows control panel under windows regional and language -> current format (combobox) and change... apply it, do a rebuild (execute) of your app and watch what i'm talking about.
so how can you force showing Am and Pm prefix in English event if the culture of the current system isn't set to English ?
easy just by adding two lines ->
the first step add using System.Globalization; on top of your code
and modify the previous code to be like this :
DateTime d = new DateTime(1, 1, 1, 23, 12, 0);
var res = d.ToString("HH:mm tt", CultureInfo.InvariantCulture); // this show 11:12 Pm
InvariantCulture => using default English Format.
another question I want to have the pm to be in Arabic or specific language, even if I use windows set to English (or other language) regional format?
Solution for Arabic Exemple :
DateTime d = new DateTime(1, 1, 1, 23, 12, 0);
var res = d.ToString("HH:mm tt", CultureInfo.CreateSpecificCulture("ar-AE"));
this will show // 23:12 م
event if my system is set to English region format.
you can change "ar-AE" if you want to another language format. there is a list for each language.
exemples :
ar ar-SA Arabic
ar-BH ar-BH Arabic (Bahrain)
ar-DZ ar-DZ Arabic (Algeria)
ar-EG ar-EG Arabic (Egypt)
.....
You can add the TimeSpan to a DateTime, for example:
TimeSpan span = TimeSpan.FromHours(16);
DateTime time = DateTime.Today + span;
String result = time.ToString("hh:mm tt");
Demo: http://ideone.com/veJ6tT
04:00 PM
Standard Date and Time Format Strings
Doing some piggybacking off existing answers here:
public static string ToShortTimeSafe(this TimeSpan timeSpan)
{
return new DateTime().Add(timeSpan).ToShortTimeString();
}
public static string ToShortTimeSafe(this TimeSpan? timeSpan)
{
return timeSpan == null ? string.Empty : timeSpan.Value.ToShortTimeSafe();
}
string displayValue="03:00 AM";
This is a point in time , not a duration (TimeSpan).
So something is wrong with your basic design or assumptions.
If you do want to use it, you'll have to convert it to a DateTime (point in time) first. You can format a DateTime without the date part, that would be your desired string.
TimeSpan t1 = ...;
DateTime d1 = DateTime.Today + t1; // any date will do
string result = d1.ToString("hh:mm:ss tt");
storeTime variable can have value like
storeTime=16:00:00;
No, it can have a value of 4 o'clock but the representation is binary, a TimeSpan cannot record the difference between 16:00 and 4 pm.
You will need to get a DateTime object from your TimeSpan and then you can format it easily.
One possible solution is adding the timespan to any date with zero time value.
var timespan = new TimeSpan(3, 0, 0);
var output = new DateTime().Add(timespan).ToString("hh:mm tt");
The output value will be "03:00 AM" (for english locale).
You cannot add AM / PM to a TimeSpan. You'll anyway have to associate the TimaSpan value with DateTime if you want to display the time in 12-hour clock format.
TimeSpan is not intended to use with a 12-hour clock format, because we are talking about a time interval here.
As it says in the documentation;
A TimeSpan object represents a time interval (duration of time or elapsed time) that is measured as a positive or negative number of days, hours, minutes, seconds, and fractions of a second. The TimeSpan structure can also be used to represent the time of day, but only if the time is unrelated to a particular date. Otherwise, the DateTime or DateTimeOffset structure should be used instead.
Also Microsoft Docs describes as follows;
A TimeSpan value can be represented as [-]d.hh:mm:ss.ff, where the optional minus sign indicates a negative time interval, the d component is days, hh is hours as measured on a 24-hour clock, mm is minutes, ss is seconds, and ff is fractions of a second.
So in this case, you can display using AM/PM as follows.
TimeSpan storedTime = new TimeSpan(03,00,00);
string displayValue = new DateTime().Add(storedTime).ToString("hh:mm tt");
Side note :
Also should note that the TimeOfDay property of DateTime is a TimeSpan, where it represents
a time interval that represents the fraction of the day that has elapsed since midnight.
To avoid timespan format limitations, convert to datetime.
Simplest expression would be:
// Where value is a TimeSpan...
(new DateTime() + value).ToString("hh:mm tt");
Parse timespan to DateTime and then use Format ("hh:mm:tt"). For example.
TimeSpan ts = new TimeSpan(16, 00, 00);
DateTime dtTemp = DateTime.ParseExact(ts.ToString(), "HH:mm:ss", CultureInfo.InvariantCulture);
string str = dtTemp.ToString("hh:mm tt");
str will be:
str = "04:00 PM"
You can try this:
string timeexample= string.Format("{0:hh:mm:ss tt}", DateTime.Now);
you can remove hh or mm or ss or tt according your need
where
hh is hour in 12 hr formate,
mm is minutes,ss is seconds,and tt is AM/PM.
Parse timespan to DateTime. For Example.
//The time will be "8.30 AM" or "10.00 PM" or any time like this format.
public TimeSpan GetTimeSpanValue(string displayValue)
{
DateTime dateTime = DateTime.Now;
if (displayValue.StartsWith("10") || displayValue.StartsWith("11") || displayValue.StartsWith("12"))
dateTime = DateTime.ParseExact(displayValue, "hh:mm tt", CultureInfo.InvariantCulture);
else
dateTime = DateTime.ParseExact(displayValue, "h:mm tt", CultureInfo.InvariantCulture);
return dateTime.TimeOfDay;
}
At first, you need to convert time span to DateTime structure:
var dt = new DateTime(2000, 12, 1, timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds)
Then you need to convert the value to string with Short Time format
var result = dt.ToString("t"); // Convert to string using Short Time format
Because this situation is as annoying as it is common... I created a helper class, which I have released in a NuGet package. This could be a private method and can be used in MVC views as well as in back-end C# code.
public static string AsTimeOfDay(TimeSpan timeSpan, TimeSpanFormat timeSpanFormat = TimeSpanFormat.AmPm)
{
int hours = timeSpan.Hours;
int minutes = timeSpan.Minutes;
string AmOrPm = "AM";
string returnValue = string.Empty;
if (timeSpanFormat == TimeSpanFormat.AmPm)
{
if (hours >= 12)
{
AmOrPm = "PM";
}
if (hours > 12)
{
hours -= 12;
}
TimeSpan timeSpanAmPm = new TimeSpan(hours, minutes, 0);
returnValue = timeSpanAmPm.ToString(#"h\:mm") + " " + AmOrPm;
}
else
{
returnValue = timeSpan.ToString(#"h\:mm");
}
return returnValue;
}

Categories

Resources