CyanideHavik
CyanideHavik

Reputation: 67

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.

Upvotes: 2

Views: 1414

Answers (2)

John Wu
John Wu

Reputation: 52240

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

Upvotes: 3

Jay
Jay

Reputation: 3355

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

Upvotes: 0

Related Questions