I am trying to parse a string timestamp of format "yyyyMMddHHmmss" with DateTime.ParseExact(). The catch is I must allow for an hour value of "24" (i.e. hours can be from 0 to 24, where hour 24 denotes hour 0 of the next day (day + 1, hour = 0) Note: I can't control the input values.) and, of course, that results in an exception.
Are there any settings/properties I can set instead of manually parsing/using regex's? If not, any efficient parsing ideas?
ex.
DateTime.ParseExact("20120911240000", "yyyyMMddHHmmss",
System.Globalization.CultureInfo.InvariantCulture);
if you want to do it manually you can use String.Substring() to detect hour values of "24", then use String.Replace, to set that to "00", then parse your date, and then add a day if that's what an hours value of "24" means
Sam's solution is good, but since you are using yyyyMMddHHmmss I would do something like:
bool addDay = false;
DateTime result;
string dtToParse = "20120911240000";
if (dtToParse[8] == '2' && dtToParse[9] == '4')
{
dtToParse = dtToParse.Substring(0, 8) + "00" + dtToParse.Substring(10);
addDay = true;
}
result = DateTime.ParseExact(dtToParse, "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);
if (addDay) { result = result.AddDays(1); }
There is no simple flag to do what you want.
However, here is the way to create custom datetime parser:
How to create and use a custom IFormatProvider for DateTime?
Related
I have a C# Visual Studio web application that uses Telerik RadTimePickers to collect the start time and end times, formatted as 24 hour time. These two elements get stored in the database as a string formatted as 09:00:00-09:30:00.
Now when the application retrieves the data from the database I need to convert that string into 2 separate times, in the 24 hour format, so I can use those values as the Selected Time for the RadTimePickers.
I use the code below to extract the two dates from the string;
if (Results.TimeOfDay != "-" || Results.TimeOfDay != null)
{
string[] times = Results.TimeOfDay.Split('-');
string time1 = times[0];
RadTimePicker1.SelectedTime = ParseTime(time1);
string time2 = times[1];
RadTimePicker2.SelectedTime = ParseTime(time2);
}
The Code for ParseTime looks like this:
static public TimeSpan ParseTime(string input)
{
TimeSpan output;
var ok = TimeSpan.TryParseExact(input, #"hh\:mm\:tt", CultureInfo.InvariantCulture,out output);
return output;
}
But it is not working, the var ok value returns false and the output value is 1/1/0001 12:00:00 AM.
New to C# and cannot figure out how to fix this problem. Can someone help please
Based on comments I changed the code to parse to this
static public TimeSpan ParseTime(string input)
{
TimeSpan output;
var ok = TimeSpan.TryParseExact(input, #"hh\:mm\:tt", CultureInfo.InvariantCulture,out output);
return output;
}
if (Results.TimeOfDay != "-" || Results.TimeOfDay != null)
This will always be true, because you are asking if .TimeOfDay, or "09:00:00-09:30:00", is not equal to "-". You should use Results.TimeOfDay.Contains("-") instead.
Also,
#"h:mm tt"
This should be #"hh:mm:tt"
Edit: sorry should be #"hh\:mm\:ss"
You can just parse it as a TimeSpan with the following code
TimeSpan.TryParseExact(input, #"hh\:mm\:ss", CultureInfo.InvariantCulture, out output);
Note for TimeSpan you have to use hh rather than HH for DateTime and you have to delimit the colons.
Note you really should also check the return of TryParseExact and do something to handle when the input does not match the format. Otherwise the resulting output will be the default for TimeSpan which is 00:00:00
As other's have mentioned if (Results.TimeOfDay != "-" || Results.TimeOfDay != null) will always be true. If you change it to if (Results.TimeOfDay != "-" && Results.TimeOfDay != null) then you'll skip the parsing when TimeOfDay is null or equal to "-". Although you really should handle all the error cases which would be TimeOfDay is null, TimeOfDay does not contain a - or contains multiples and when the values on each side of the - are not formatted correctly.
I've simplified my code down to this:
string when = "03/03/15 12:00 18:00";
string difference = Convert.ToString(Convert.ToDateTime(when.Substring(when.Length - 5, 5)) - Convert.ToDateTime(when.Substring(when.Length - 10, 10))).substring(difference.Length - 5, 5);
But it's still very complex and also doesn't work :/
Basically I want the string difference to equal 6 because 18 - 12 is 6. It needs to be a little bit more complex because I want to evolve minutes too.
Am I being an idiot? Is it easy?
Just convert your string to a couple of valid DateTime values, and subtract them.
The Hours property will give you a representation of the difference in whole hours, in this case 6.
string when = "03/03/15 12:00 18:00";
string[] portions = when.Split(); // 3 items: "03/03/15", "12:00", "18:00"
string yourDateTimeFormat = "MM/dd/yyHH:mm"; // or "dd/MM/yyHH:mm" if the day is first
// create a valid date from 03/03/15 and 12:00
DateTime fromTime = DateTime.ParseExact(
portions[0] + portions[1], yourDateTimeFormat, CultureInfo.CurrentCulture, DateTimeStyles.None);
// create a valid date from 03/03/15 and 18:00
DateTime toTime = DateTime.ParseExact(
portions[0] + portions[2], yourDateTimeFormat, CultureInfo.CurrentCulture, DateTimeStyles.None);
int differenceInHours = (toTime - fromTime).Hours;
Depending on how much control you have over the input, you may want to add additional logic for checking that the date is valid, or consider using DateTime.TryParseExact instead.
Currently it is evening and couldn't actually test it with morning hours like 7 in the morning.
but a code like this:
DateTime dt = DateTime.Now;
string str = dt.ToString("HH:mm");
So my question is can I be sure that it is always returning time in format like "07:35" and not "7:35" ?
DateTime.Now returns time without formatting. Format applied in the ToString("HH:mm") method. And yes, this format is 24-hour.
Yes because the documentation says:
The "HH" Custom Format Specifier: The "HH" custom format specifier (plus any number of additional "H" specifiers) represents the hour as a number from 00 through 23; that is, the hour is represented by a zero-based 24-hour clock that counts the hours since midnight. A single-digit hour is formatted with a leading zero.
You could test with
DateTime dt = DateTime.Now;
string str = dt.ToString("HH:mm");
Console.WriteLine(str);
DateTime t = new DateTime(2014,3,27,7,5,0);
str = t.ToString("H:mm");
Console.WriteLine(str);
The HH format return always the hour formatted with two digits adding a leading zero when the hour is less than 10, the H format returns the hours formatted with exactly the digits present in the hour part.
You can create an instance of DateTime with desired date and time values using to test various time setting and formats :
var dt = new DateTime(2014, 1, 1, 7, 35, 0);
string str = dt.ToString("HH:mm");
I have a date like this:
equipBooking.BookedFromDteTme.Date = `{12/5/2013 12:00:00 AM}`
and I want to apply time like this, but I do not know how to get AM and PM from the end.
dtStartTimeHour.SelectedItem = equipBooking.BookedFromDteTme.TimeOfDay.Hours;
dtStartTimeMin.SelectedItem = equipBooking.BookedFromDteTme.TimeOfDay.Minutes;
**dtStartTimeAMPM.SelectedItem = equipBooking.BookedFromDteTme.???????.;**
Please help me.
I have tried something like this:
var startDatestr = equipBooking.BookedFromDteTme.TimeFrom.Split(new string[] { ":", ":",":",":" }, StringSplitOptions.RemoveEmptyEntries);
AM/PM = startDatestr[3]
If you just want the string you can do:
equipBooking.BookedFromDteTme.ToString("tt");
Or for a boolean result use:
bool isPM = (equipBooking.BookedFromDteTme.Hour >= 12);
BTW, you don't need to call TimeOfDay - you can get the Hour and Minute property directly from the DateTime:
dtStartTimeHour.SelectedItem = equipBooking.BookedFromDteTme.Hour;
dtStartTimeMin.SelectedItem = equipBooking.BookedFromDteTme.Minute;
dtStartTimeAMPM.SelectedItem = equipBooking.BookedFromDteTme.ToString("tt");
TimeSpan does not store time-of-day, but rather the length of any interval of time. It has no notion of AM/PM.
TimeOfDay returns the amount of time since midnight.
If Hours is more than or equal to 12, that will be PM.
try using dateTime.ToString("tt");
I was simply trying to use the DateTime structure to transform an integer between 1 and 12 into an abbrieviated month name.
Here is what I tried:
DateTime getMonth = DateTime.ParseExact(Month.ToString(),
"M", CultureInfo.CurrentCulture);
return getMonth.ToString("MMM");
However I get a FormatException on the first line because the string is not a valid DateTime. Can anyone tell me how to do this?
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(1);
See Here for more details.
Or
DateTime dt = DateTime.Now;
Console.WriteLine( dt.ToString( "MMMM" ) );
Or if you want to get the culture-specific abbreviated name.
GetAbbreviatedMonthName(1);
Reference
var monthIndex = 1;
return month = DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(monthIndex);
You can try this one as well
You can do something like this instead.
return new DateTime(2010, Month, 1).ToString("MMM");
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(
Convert.ToInt32(e.Row.Cells[7].Text.Substring(3,2))).Substring(0,3)
+ "-"
+ Convert.ToDateTime(e.Row.Cells[7].Text).ToString("yyyy");