I have a TextBox to enter time in the format "%h:%m:%s".
The allowed time inputs:
01:20:00
12:20:00
I am converting the string taken from TextBox using:
DateTime.TryParseExact("00:20:00", "%h:%m:%s",
culture, DateTimeStyles.None, out newData);
But above code converts hour 00 to 12 when providing the data through newData. I want to throw error in this case. Please provide your inputs.
It seems that you should try to parse to a TimeSpan instead of DateTime.
Use the following string.Format pattern to convert to a TimeSpan:
var pattern = #"hh\:mm\:ss";
see MSDN for more details: http://msdn.microsoft.com/en-us/library/ee372287(v=vs.110).aspx
UPDATED
Working Sample code:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DateTime newData;
TimeSpan newSpan;
DateTime.TryParseExact("00:20:00", "%h:%m:%s",
CultureInfo.DefaultThreadCurrentCulture, DateTimeStyles.None, out newData);
Console.WriteLine(newData);
// 8/5/2014 12:20:00 AM
TimeSpan.TryParseExact("00:20:00", #"hh\:mm\:ss",
CultureInfo.DefaultThreadCurrentCulture, TimeSpanStyles.None, out newSpan);
Console.WriteLine(newSpan);
// 00:20:00
Console.WriteLine(newSpan.Hours);
// 0
Console.WriteLine(newSpan.TotalHours);
// 0.33~
Console.ReadLine();
}
}
}
You should be using upper-case "H" for 24-hour time.
Related
I need to parse a string that specifies the environment's timezone. It looks like +0100 or -0530, specifying the offset from the UTC time zone.
In these strings, the plus/minus sign is always there. I want to parse this with the TimeSpan.ParseExact() method, and I'm quite sure that there is a way. The Parse() method knows how to deal with a minus sign, but the ParseExact() method's documentation does not mention anything about signs whatsoever.
So far, the format I'm using is hhmm, but this will need to be prefixed by something that deals with the +/- sign. Can anyone please point me in the right direction?
You could check if it starts with -, then apply the appropriate format string:
string[] timespans = { "-0530", "+0100" };
foreach (string timespan in timespans)
{
bool isNegative = timespan.StartsWith("-");
string format = isNegative ? "\\-hhmm" : "\\+hhmm";
TimeSpanStyles tss = isNegative ? TimeSpanStyles.AssumeNegative : TimeSpanStyles.None;
TimeSpan ts;
if (TimeSpan.TryParseExact(timespan, format, null, tss, out ts))
{
Console.WriteLine("{0} successfully parsed to: {1}", timespan, ts);
}
else
{
Console.WriteLine("Could not be parsed: {0}", timespan);
}
}
Note that i use TimeSpanStyles.AssumeNegative in TryParseExact, otherwise the timespans would be always positive even if they are prepended with a minus.
This should work for timezone offsets:
var dt = DateTime.ParseExact("14-oct-2015 08:22:00 +01:00","dd-MMM-yy HH:mm:ss zzz", culture);
But this only works for DateTime, not TimeSpan, as timezone information is not supported in TimeSpan strings.
Looks like it is not supported. From Custom TimeSpan Format Strings;
Custom TimeSpan format specifiers also do not include a sign symbol
that enables you to differentiate between negative and positive time
intervals. To include a sign symbol, you have to construct a format
string by using conditional logic. The Other Characters section
includes an example.
But looks like NodaTime support this. In Patterns for Duration values page, it has + and - as a characters part.
using NodaTime.Text;
namespace Program
{
class Program
{
static void Main(string[] args)
{
DurationPattern pattern = DurationPattern.CreateWithInvariantCulture("+hhmm");
TimeSpan timeSpan = pattern.Parse("+0100").Value.ToTimeSpan();
}
}
}
Here a demonstration.
I encountered a strange issue. It's Wednesday now, and:
DateTime date;
DateTime.TryParseExact(
"Wed", "ddd", null, System.Globalization.DateTimeStyles.None, out date); // true
DateTime.TryParseExact(
"Mon", "ddd", null, System.Globalization.DateTimeStyles.None, out date); // false
When I change local date on computer to Monday output swaps to 'false-true'.
Why does the parser depend on current date?
I suspect the problem is that you've got a very incomplete date format there. Usually, DateTime.TryParseExact will use the current time and date for any fields that aren't specified. Here, you're specifying the day of the week, which isn't really enough information to get to a real date... so I suspect that the text value is only being used to validate that it's a reasonable date, after defaulting the DateTime to "now". (In the cases where it does manage to parse based on just the day name, you end up with today's date.)
I've just done another test where we specify the day-of-month value as well, and that ends up with interesting results - it appears to use the first month of the current year:
using System;
using System.Globalization;
class Test
{
public static void Main (string[] args)
{
// Note: All tests designed for 2015.
// January 1st 2015 was a Thursday.
TryParse("01 Wed"); // False
TryParse("01 Thu"); // True - 2015-01-01
TryParse("02 Thu"); // False
TryParse("02 Fri"); // True - 2015-01-02
}
private static void TryParse(string text)
{
DateTime date;
bool result = DateTime.TryParseExact(
text, "dd ddd", CultureInfo.InvariantCulture, 0, out date);
Console.WriteLine("{0}: {1} {2:yyyy-MM-dd}", text, result, date);
}
}
Changing the system date to 2016 gave results consistent with finding dates in January 2016.
Fundamentally, trying to parse such incomplete as this is inherently odd. Think carefully about what you're really trying to achieve.
Why not use regex if you are wanting validating part of a date?
https://dotnetfiddle.net/ieokVz
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string pattern = "(Mon|Tue|Wed|Thu|Fri|Sat|Sun)";
string[] values = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun","Bun","Boo","Moo"};
Console.WriteLine("");
foreach(var val in values){
Console.WriteLine("{0} ? {1}",val,Regex.IsMatch(val,pattern));
}
}
}
As per #Jon's comments
https://dotnetfiddle.net/I4R2ZT
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var matches = new HashSet<String>(System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.AbbreviatedDayNames,StringComparer.OrdinalIgnoreCase);
string[] values = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun","Bun","Boo","Moo","Foo","Bar"};
foreach(var val in values){
Console.WriteLine("{0} ? {1}", val, matches.Contains(val));
}
}
}
I have OCR extracted date string due to image quality second slash of date comes as 1,
i.e. date comes as 23/0212014 where 1 before year should be / actually. I have tried to replace 1 with regex but its not working.
DateTime.TryParseExact does not work and code i have tried is:
string mm = "23/0212014";
var rex = new Regex(#"(?:((\d{2}\/\d{2})1(\d{4})))");
mm = rex.Replace(mm, "");
How to convert it to proper date (dd/MM/yyyy)?
DateTime.TryParseExact works fine for me:
using System;
using System.Globalization;
class Test
{
static void Main()
{
string text = "23/0212014";
DateTime result;
if (DateTime.TryParseExact(text, "dd/MM'1'yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None, out result))
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("Failed to parse");
}
}
}
Output:
23/02/2014 00:00:00
(Once you've parsed it as a DateTime you can reformat it however you want, of course.)
I would definitely try to use this rather than regular expressions.
I receive text from a *.csv file in any date format
For example: dd/mm/yy or dd/mm/yyyy or mm/dd/yyyy or 4 may 2010......
How I can convert to just a single type of format: dd/mm/yyyy ?
I'm working on C#, .NET 3.5, WinForms
Thanks in advance
If you're receiving data in multiple formats and you can't identify them, you've got problems. What does "09/07/2010" mean? September 7th or July 9th? This is the first thing to get straight in your mind, and it has nothing to do with technology. You have two contradictory formats - how are you going to deal with them? Sample the file and pick whichever looks most likely? Treat each line separately, favouring one format over another? Ask the user?
Once you've parsed the data correctly, formatting it in the desired way is easy, as per John's answer. Note that you must use "MM" for the month, not "mm" which represents minutes. You should also specify which culture to use (affecting the date separators) assuming you don't just want to take the system default.
DateTime.Parse("your data").ToString("dd/MM/yyyy");
Check out TryParseExact.
public static string FormatDate(string input, string goalFormat, string[] formats)
{
var c = CultureInfo.CurrentCulture;
var s = DateTimeStyles.None;
var result = default(DateTime);
if (DateTime.TryParseExact(input, formats, c, s, out result))
return result.ToString(goalFormat);
throw new FormatException("Unhandled input format: " + input);
}
Example Usage
var formats - new[] { "dd/MM/yy", "dd/MM/yyyy" };
var next = csvReader.Get("DateField");
var formattedDate = FormatDate(next, "dd/MM/yyyy", formats);
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace dateconvert
{
class Program
{
static void Main(string[] args)
{
DateTime x = Convert.ToDateTime("02/28/10");
Console.WriteLine(string.Format(x.ToString("d", DateTimeFormatInfo.InvariantInfo)));
DateTime y = Convert.ToDateTime("May 25, 2010");
Console.WriteLine(string.Format(y.ToString("d", DateTimeFormatInfo.InvariantInfo)));
DateTime z = Convert.ToDateTime("12 May 2010");
Console.WriteLine(string.Format(z.ToString("d", DateTimeFormatInfo.InvariantInfo)));
Console.Read();
}
}
}
String.Format("{0:MM/dd/yyyy}", DateTime.Now);
String.Format("{0:dd/MM/yyyy}", DateTime.Now);
etc.
Source: http://www.csharp-examples.net/string-format-datetime/
You simply want to be using the DateTime.ParseExact together with the DateTime.ToString methods.
The straight DateTime.Parse method has its uses of course, and can be clever for parsing dates that you know are in a specific culture/locale, but since it seems dates given to you may be in an arbitrary format that cannot be recognised, you may want to specifically use ParseExact.
Example:
var myDate = DateTime.ParseExact("07/14/2010", "MM/dd/yyyy",
CultureInfo.CurrentCulture);
var standardDateString = myDate.ToString("dd/MM/yyyy");
in c# i have time in format hhmmss like 124510 for 12:45:10 and i need to know the the TotalSeconds. i used the TimeSpan.Parse("12:45:10").ToTalSeconds but it does'nt take the format hhmmss. Any nice way to convert this?
This might help
using System;
using System.Globalization;
namespace ConsoleApplication7
{
class Program
{
static void Main(string[] args)
{
DateTime d = DateTime.ParseExact("124510", "hhmmss", CultureInfo.InvariantCulture);
Console.WriteLine("Total Seconds: " + d.TimeOfDay.TotalSeconds);
Console.ReadLine();
}
}
}
Note this will not handle 24HR times, to parse times in 24HR format you should use the pattern HHmmss.
Parse the string to a DateTime value, then subtract it's Date value to get the time as a TimeSpan:
DateTime t = DateTime.ParseExact("124510", "HHmmss", CultureInfo.InvariantCulture);
TimeSpan time = t - t.Date;
You have to decide the receiving time format and convert it to any consistent format.
Then, you can use following code:
Format: hh:mm:ss (12 Hours Format)
DateTime dt = DateTime.ParseExact("10:45:10", "hh:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
double totalSeconds = dt.TimeOfDay.TotalSeconds; // Output: 38170.0
Format: HH:mm:ss (24 Hours Format)
DateTime dt = DateTime.ParseExact("22:45:10", "HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
double totalSeconds = dt.TimeOfDay.TotalSeconds; // Output: 81910.0
In case of format mismatch, FormatException will be thrown with message: "String was not recognized as a valid DateTime."
You need to escape the colons (or other separators), for what reason it can't handle them, I don't know. See Custom TimeSpan Format Strings on MSDN, and the accepted answer, from Jon, to Why does TimeSpan.ParseExact not work.
In case you want to work with also milliseconds like this format "01:02:10.055" then you may do as following;
public static double ParseTheTime(string givenTime)
{
var time = DateTime.ParseExact(givenTime, "hh:mm:ss.fff", CultureInfo.InvariantCulture);
return time.TimeOfDay.TotalSeconds;
}
This code will give you corresponding seconds.
Note that you may increase the number of 'f's if you want to adjust precision points.
If you can guarantee that the string will always be hhmmss, you could do something like:
TimeSpan.Parse(
timeString.SubString(0, 2) + ":" +
timeString.Substring(2, 2) + ":" +
timeString.Substring(4, 2)))