I have a string in a format like 22 : 19 : 37 where 22 is Days, 19 is hours and 37 is minutes, this is what I have written to validate Hour and Minutes.
string value = "22 : 19 : 37";
string[] time = (value as string).Split(new char[] { ':' });
if (time.Length != 3)
{
Console.WriteLine("Error");
return;
}
int DD = System.Convert.ToInt32(time[0]);
int HH = System.Convert.ToInt32(time[1]);
int MM = System.Convert.ToInt32(time[2]);
// Hour should be less than 24
if (HH > 23)
{
Console.WriteLine("Invalid Hour Error");
return;
}
// Minutes should be less than 60
if (MM > 59)
{
Console.WriteLine("Invalid Minute Error");
return;
}
I don't like the code, is there anyway to improve this.
DateTime.TryParse This I believe is faster and it means you don't have to use try/catches.
e.g:
DateTime temp;
if(DateTime.TryParse(yourString, out temp))
//yay
else
// :(
Try this
string dateString = "22 : 19 : 37";
string format = "dd : HH : mm";
DateTime result;
var provider = System.Globalization.CultureInfo.InvariantCulture;
try {
result = DateTime.ParseExact(dateString, format, provider);
Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException) {
Console.WriteLine("{0} is not in the correct format.", dateString);
}
As this appears to be a TimeSpan rather than a DateTime, here is the variant of #Nkosi. Also using TryParseExact rather than ParseExact. It gets rid of the ugly try catch.
string timeSpanString = "22 : 19 : 37";
// For TimeSpan parsing all separator values need to be escaped with \\
string timeSpanFormat = "dd\\ \\:\\ hh\\ \\:\\ mm";
TimeSpan result;
var provider = System.Globalization.CultureInfo.InvariantCulture;
if (TimeSpan.TryParseExact(timeSpanString, timeSpanFormat, provider, out result))
{
Console.WriteLine("{0} converts to {1}.", timeSpanString, result);
}
else
{
Console.WriteLine("{0} is not in the correct format.", timeSpanString);
}
I think this shows the intent more clearly as #Nkosi code will output the data with a year an month.
I agree with #user3378165. But if cant change your string format you can use a regex expression to check if your string is a valid time string in format HH:MM:SS
A regular expression for this:
^\d{2}:([0-1]\d|2[0-3]):([0-5]\d)$
Next, use Regex object to do the checking
Related
I wrote a code for converting string value to TimeSpan value.
Sometimes it has FormatException not always. It is usually works well.
To subtract string as time, I used DateTime.Parse for each string value.
TimeSpan timespan = DateTime.Parse(logs_temp[i + 1].time).Subtract(DateTime.Parse(logs_temp[i].time));
It is my part of code.
public class log
{
[XmlElement("command")]
public int command { get; set; }
[XmlElement("param")]
public int param { get; set;}
[XmlElement("time")]
public string time { get; set; }
}
List<log> logs = logs_temp.ToList();
// logs and logs_temp have same command and param item. However add timespan bewteewn two commands in
// time item
for (int i = 0; i <= logs_temp.Count - 1; i++)
{
logs[i].command = logs_temp[i].command;
logs[i].param = logs_temp[i].param;
//Get a timespan between two sequencial command log
if (i + 1 < logs_temp.Count)
{ // I could find Format exception there
TimeSpan timespan = DateTime.Parse(logs_temp[i + 1].time).Subtract(DateTime.Parse(logs_temp[i].time));
//add second value as string but cannot
logs[i].time = timespan.TotalSeconds.ToString();
}
}
DateTime.Parse tries to parse it using the current PC culture. If it can't it will throw the format exception. So I guess your supplied time string is different sometimes. So set a break point to check.
Best would be to use DateTime.TryParseExact or the
dateString = "05/01/2009 01:30:42 PM -05:00";
if (DateTime.TryParseExact(dateString, "MM/dd/yyyy hh:mm:ss tt zzz", enUS, DateTimeStyles.None, out dateValue))
Console.WriteLine("Converted '{0}' to {1} ({2}).", dateString, dateValue, dateValue.Kind);
else
Console.WriteLine("'{0}' is not in an acceptable format.", dateString);
I need to accept input paramteters and print date range in console like in the example:
input: "01.01.2017 05.01.2017"
output: "01 - 05.01.2017"
So as you see dates must be separated with dots and printed with dash between them. What is more, if start and end date both has the same month and year, these are printed only once.
Does anyone can suggest good way to achieve this?
Just format date as you need and add aditional check for cases.
DateTime date1 = new DateTime();
DateTime date2 = new DateTime();
//while not valid input dates format...
bool valid = false;
while (!valid)
{
Console.WriteLine("Enter start date:");
string dateEntered1 = Console.ReadLine();
Console.WriteLine("Enter end date:");
string dateEntered2 = Console.ReadLine();
bool isvalidDate1 = DateTime.TryParse(dateEntered1,out date1);
bool isvalidDate2 = DateTime.TryParse(dateEntered2,out date2);
//check if date parsing was sucess
if(isvalidDate1 && isvalidDate2)
{
valid = true;
}
else
{
Console.WriteLine("Dates entered is in incorrect format!");
}
}
string period = "";
if (date1.Month == date2.Month && date1.Year == date2.Year)
{
period = string.Format("{0} - {1}", date1.ToString("dd."), date2.ToString("dd.MM.yyyy"));
}
else
{
period = string.Format("{0} - {1}", date1.ToString("dd.MM.yyyy"), date2.ToString("dd.MM.yyyy"));
}
Console.Write(period);
Console.Read();
I'm writing a C# console application where you enter your name and birthdate in yyyy/mm/dd format to have the console tell you your age in years and months. Now I've got that part figured out and it works. Until I tried to also implement a try and catch exception to check if the date you entered was in the right format. If not it should tell you to try again 3 times before telling you the date format is incorrect and then quitting the app.
Now the problem is the app works sort of, but it tells you the date format is incorrect even when it isn't. Then still continues to give the correct output after looping through the app that asks for name and date of birth 3 times. This is the code I have so far(I know the year month output is a bit messy I just spent way too long testing too much stuff to try and change it now, I am open to improvements and changes though):
namespace CSConsoleDateTimeTypes
{
class Program
{
static int Count = 0;
static void Main(string[] args)
{ EnterDate(); }
static void EnterDate()
{
string userName, enteredDoBString;
Console.WriteLine("Enter your name:");
userName = Console.ReadLine();
Console.WriteLine("Enter your date of birth in the format yyyy/mm/dd:");
enteredDoBString = Console.ReadLine();
string dateString = Console.ReadLine();
parseDateString(dateString);
DateTime enteredDoB = DateTime.Parse(enteredDoBString);
Console.WriteLine("Your DoB is: {0}", enteredDoB);
DateTime dateToday = DateTime.Today;
if (dateToday < enteredDoB)
{
DateTime date4 = dateToday;
dateToday = enteredDoB;
enteredDoB = date4;
}
TimeSpan ts = dateToday - enteredDoB;
//total days (irrelevant to the application though)
Console.WriteLine(ts.TotalDays);
//total years
int years = dateToday.Year - enteredDoB.Year;
int months = 0;
//Total months
if (dateToday.Month < enteredDoB.Month)
{
months = 12 - dateToday.Month + enteredDoB.Month;
}
else
{
months = enteredDoB.Month - dateToday.Month;
}
if (months > 12)
{
Console.WriteLine("Years: {0}, Months: {1}", years - 1, 12 - (months - 12));
}
else if (months < 0)
{
Console.WriteLine("Years: {0}, Months: {1}", years, months - months);
}
else
{
Console.WriteLine("Years: {0}, Months: {1}", years, months);
}
Console.ReadKey();
Console.ReadKey();
}
static void parseDateString(string datestring)
{
try
{
DateTime date3 = DateTime.Parse(datestring, System.Globalization.CultureInfo.InvariantCulture);
date3.ToShortDateString();
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//if date was entered incorrectly 3 times, the application should exit..
Count++;
if (Count < 3)
{
EnterDate();
}
else
{
Console.WriteLine("\aSorry date still not in correct format - Press any key to exit the application");
Console.ReadKey();
}
}
}
}
}
This is the output it gives when I launch the app and it finishes running through all the code after my inputs:
Enter your name:
gerrit
Enter your date of birth in the format yyyy/mm/dd:
1997/02/13
String was not recognized as a valid DateTime.
Enter your name:
gerrit
Enter your date of birth in the format yyyy/mm/dd:
1997/02/13
String was not recognized as a valid DateTime.
Enter your name:
gerrit
Enter your date of birth in the format yyyy/mm/dd:
1997/02/13
String was not recognized as a valid DateTime.
Sorry date still not in correct format - Press any key to exit the application
Your DoB is: 1997/02/13 12:00:00 AM
7294
Years: 20, Months: 0
Your DoB is: 1997/02/13 12:00:00 AM
7294
Years: 20, Months: 0
Your DoB is: 1997/02/13 12:00:00 AM
7294
Years: 20, Months: 0
As you can see it asks for name and date of birth 3 times and still telling me date format is incorrect then it gives the correct output (Your DoB is: 1997/02/13 12:00:00 AM
7294
Years: 20, Months: 0) 3 times
It should ask once and output once but I can't figure out how to do it. Any help would be highly appreciated.
Here is a screenshot of the console output if it helps at all
http://i.imgur.com/qUpF0g2.png
I changed a little your code.
I don't have checked the rest of your code, only to ask the date.
private static void Main(string[] args)
{
EnterDate();
}
private static void EnterDate()
{
Console.WriteLine("Enter your name:");
var userName = Console.ReadLine();
// ask for date
var enteredDoBString = AskForDate();
if (enteredDoBString == null)
return;
DateTime enteredDoB = DateTime.Parse(enteredDoBString);
Console.WriteLine($"Your DoB is: {enteredDoB}");
DateTime dateToday = DateTime.Today;
if (dateToday < enteredDoB)
{
DateTime date4 = dateToday;
dateToday = enteredDoB;
enteredDoB = date4;
}
TimeSpan ts = dateToday - enteredDoB;
// total days (irrelevant to the application though)
Console.WriteLine(ts.TotalDays);
// total years
var years = dateToday.Year - enteredDoB.Year;
var months = 0;
// Total months
if (dateToday.Month < enteredDoB.Month)
{
months = 12 - dateToday.Month + enteredDoB.Month;
}
else
{
months = enteredDoB.Month - dateToday.Month;
}
if (months > 12)
{
Console.WriteLine($"Years: {years - 1}, Months: {12 - (months - 12)}");
}
else if (months < 0)
{
Console.WriteLine($"Years: {years}, Months: {months - months}");
}
else
{
Console.WriteLine($"Years: {years}, Months: {months}");
}
Console.ReadKey();
Console.ReadKey();
}
private static string AskForDate()
{
var count = 0;
while (count++ < 3)
{
try
{
Console.WriteLine("Enter your date of birth in the format yyyy/mm/dd:");
return DateTime.Parse(Console.ReadLine(), System.Globalization.CultureInfo.InvariantCulture).ToShortDateString();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//if date was entered incorrectly 3 times, the application should exit..
}
}
Console.WriteLine("\aSorry date still not in correct format - Press any key to exit the application");
Console.ReadKey();
return null;
}
What I made:
I removed your function parseDateString and create a new called AskForDate. This function, like the name says, ask for the date to the user, and inside this function, the date entered is checked if is valid or not.
I believe that is better to check and ask on same function.
If the date entered by user is correct, the date is returned as ToShortDateString. If the date is incorrectly, the function ask two more times, and on third time, a null is returned.
Then, in the EnterDate function, if null is returned from AskForDate function, the program exits.
I also changed some strings interpolations, and removed some variables.
So I've got a string 00:00:15:185 which I need to tell is greater than 15 seconds.
Time format is HH:m:ss:FFF
This is clearly longer than 15 seconds but I can't compare it properly.
Current code is this:
value = "00:00:15:185";
if (DateTime.Parse(value) > DateTime.Parse("00:00:15:000"){
//do stuff
}
It's giving exceptions when I run it all the time and the program doesn't work when it should
Your string doesn't represent a time, but an amount of time. We have TimeSpan for that.
var value = "00:00:15:185";
if (TimeSpan.ParseExact(value, #"hh\:mm\:ss\:FFF", CultureInfo.InvariantCulture)
> TimeSpan.FromSeconds(15))
{
//do stuff
}
Another option(apart from #rob 's answer), use DateTime.ParseExact
var value = "00:00:15:185";
if (DateTime.ParseExact(value, "HH:mm:ss:fff", CultureInfo.InvariantCulture) >
DateTime.ParseExact("00:00:15:000", "HH:mm:ss:fff", CultureInfo.InvariantCulture))
{
// logic here.
}
DateTime time = DateTime.Now;
String result = time.ToString("HH:mm ");
DateTime firstTimr = DateTime.ParseExact(reader["shift_start_time"].ToString(), "HH:mm:tt", null);
String firstTimr1 = firstTimr.ToString("HH:mm ");
DateTime lastTime = DateTime.ParseExact(reader["Shift_last_time"].ToString(), "HH:mm:tt", null);
String lastTime1 = lastTime.ToString("HH:mm ");
if (DateTime.Parse(result) >= DateTime.Parse(firstTimr1) && (DateTime.Parse(result) <= DateTime.Parse(lastTime1)))
{
`enter code here` MessageBox.Show("First Shit");
}
There is a string 2020-12-27 20:00:00. An application must parse it to DateTime structure. Expected format is yyyy-MM-dd hh:mm:ss.
I use:
DateTime.TryParseExact(timeString, "yyyy-MM-dd hh:mm:ss",
CultureInfo.InvariantCulture, DateTimeStyles.None, out time)
but it doesn't work. TryParseExact returns false.
Anyone knows why?
You need to use HH instead of hh specifier.
HH specifier is for 24-hour clock format (00 to 23) but hh specifier is for 12-hour clock format (01 to 12).
string s = "2020-12-27 20:00:00";
DateTime dt;
if(DateTime.TryParseExact(s, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture,
DateTimeStyles.None, out dt))
{
// 27.12.2020 20:00:00
}
hh is 12 hours format, you should use HH for 24 hours
So your example becomes:
DateTime.TryParseExact(timeString, "yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture, DateTimeStyles.None, out time)
You can use method I wrote for purpose of converting DTs from string of any format:
public static DateTime? parseDate(this string date, string format = #"ddMMyyyy")
{
format += "HHmmss";
DateTime dt;
try
{
string day = date.Substring(format.IndexOf('d'), 2);
string month = date.Substring(format.IndexOf('M'), 2);
string year = date.Substring(format.IndexOf('y'), 4);
string hour = date.Length - 1 > format.IndexOf('H')? date.Substring(format.IndexOf('H'), 2) : "00";
string minute = date.Length - 1 > format.IndexOf('m')? date.Substring(format.IndexOf('m'), 2) : "00";
string second = date.Length - 1 > format.IndexOf('s')? date.Substring(format.IndexOf('s'), 2) : "00";
dt = DateTime.Parse(year + "/" + month + "/" + day + " " + hour + ":" + minute + ":" + second);
}
catch { return null; }
return dt;
}
Usage:
string date = "2014ASDA04QWER05zxc";
DateTime? dt = date.parseDate("yyyyxxxxMMxxxxdd");
Result: 2014/04/05 00:00
However you are right maybe you should just use DateTime.ParseExact with HH instead of hh as my method is overcomplicated for this.
Little comparison of two methods using 20 000 random dates: