first sorry for my bad English
i want to make an order in my program when it come 12:00 AM in my PC
i try with this code
string Time = "00:00 AM";
while (true)
{
if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
{
Console.ForegroundColor = ConsoleColor.Blue;
// Update Days -1 Where Service = 1
sqlCon.exec("update HelperSystem set Days = Days-1 where Service=1 and Days != 0");
Meldung("Updated HelperSystem Table Days -1");
// Update Service = 0 Where Days = 0
sqlCon.exec("update HelperSystem set Service = 0 where Days = 0");
Meldung("Updated HelperSystem Table Service = 0 Where Days = 0");
// Update Days -1 Where Service = 1
sqlCon.exec("update AutoEvent set Days = Days-1 where Service=1 and Days != 0");
Meldung("Updated AutoEvent Table Days -1");
// Update Service = 0 Where Days = 0
sqlCon.exec("update AutoEvent set Service = 0 where Days = 0");
Meldung("Updated AutoEvent Table Service = 0 Where Days = 0");
Console.ResetColor();
Thread.Sleep(120000);
}
Thread.Sleep(1);
}
and when i try with breakpoint return value 12:00 AM but didn't do anything
If you're trying to match times using a formatted string then you should ensure you're comparing against the same format. You should do something like this:
string timeFormat = "hh:mm tt";
string Time = (new DateTime(1970, 1, 1, 0, 0, 0)).ToString(timeFormat); //12:00 AM
while (true)
{
if (Time == DateTime.UtcNow.ToString(timeFormat))
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
Thread.Sleep(120000);
}
Thread.Sleep(1);
}
However, this approach isn't great. You really have nothing ensuring that the process will actually execute at the right time of day to ensure equality works. In this case you'd be very unlucky as it only has to run once in the 60 seconds that the time text is correct, but there is no guarantee. You really should compare against a specific time.
This is better:
DateTime Time = DateTime.UtcNow.AddDays(1.0).Date;
while (true)
{
if (DateTime.UtcNow > Time)
{
Time = DateTime.UtcNow.AddDays(1.0).Date;
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
}
Thread.Sleep(1);
}
There's no need for the messy Thread.Sleep(120000); in this code.
However, you still have the Thread.Sleep(1); call which is bad.
I'd suggest using a library that has been designed for this kind of thing. Try Microsoft's Reactive Framework (NuGet "System.Reactive") and then you can do this:
IDisposable subscription =
Observable
.Timer(DateTimeOffset.UtcNow.AddDays(1.0).Date, TimeSpan.FromDays(1.0))
.Subscribe(x =>
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Run.");
Console.ResetColor();
});
When you're closing down your app just call subscription.Dispose(); and it'll cleanly stop.
Change string Time = "4:30 AM"; to "04:30 AM"
public static void Main()
{
string Time = "4:30 AM";
while (true)
{
Console.WriteLine("{0}",DateTime.UtcNow.ToString("hh:mm tt"));
// Prints 04:30 AM - so that is why it does not match 4:30 AM
if (Time == DateTime.UtcNow.ToString("hh:mm tt"))
{
Console.ForegroundColor = ConsoleColor.Blue;
// Update Days -1 Where Service = 1
Console.WriteLine("I am In");
Console.ResetColor();
}
Thread.Sleep(1000);
}
}
Related
I am learning c# and I was trying to test my abilities by making a short game using the .net framework console. I want to make it so that if you don't type "(the thing the player needs to type)" within x amount of time, then they fail, and they go to the death screen.
I have tried looking up stuff like the System.Threading.CountdownEvent, Systen.Threading.Timer and System.Timers.Timer etc, but all the tutorials don't help.
tutorialfight:
if (fight == "Y")
{
Console.WriteLine("Goblin: 'You seem week, hit me first!'");
}
else if (fight == "N")
{
Console.WriteLine("This is the tutorial, you have no choice, Would you like to fight? (Y/N)");
fight = Console.ReadLine();
goto tutorialfight;
}
else
{
Console.WriteLine("Type Y for yes or N for no");
fight = Console.ReadLine();
goto tutorialfight;
}
int goblinhp = 5;
Console.WriteLine("Misery: 'Type what is says to do some damage. If you fail, you take some damage, and if you dont kill the enemy within the amount of time allowed, you die!'");
Console.WriteLine("Type 'x3hu' in 10 seconds to deal 1 damage");
string x3hu = Console.ReadLine();
if (x3hu != "x3hu")
{
Console.WriteLine("Your health went down 3 points!");
health = health - 3;
Console.WriteLine("Health: " + health);
Console.WriteLine("Misery: 'Dont worry, you've still got loads of health left!'");
}
else
{
goblinhp = goblinhp - 1;
Console.WriteLine("Goblin health: " + goblinhp);
Console.WriteLine("Misery: 'Great job!'");
}
It seems like you already have a grasp of what you need:
Some way of detecting Console input is available to read
Some way of setting a timeout for user input
You should be able to accomplish this by using the Console.KeyAvailable property and tracking the elapsed time of a Stopwatch.
The pseudo code would go something like this:
Console.WriteLine("You have 10 seconds to press attack (x)");
var timeout = 10;
StopWatch.Start();
while(Stopwatch.Elapsed.Seconds < timeout && !Console.KeyAvailable)
{
// wait
}
// process which event happened first
The conditions and looping logic could vary but this should be enough to get you headed in the right direction :)
KeyAvailable documentation
Stopwatch documentation
I made a simple solution based on Dawid Owens' answer.
class Program
{
static async Task Main(string[] args)
{
var timeout = 10;
var textToWrite = "Hello World!";
bool isTimeIsUp = false;
bool returnPressed = false;
StringBuilder enteredText = new StringBuilder();
Console.WriteLine($"You have {timeout} seconds to write: '{textToWrite}'");
Stopwatch stopwatch = Stopwatch.StartNew();
while (!returnPressed)
{
while (!isTimeIsUp && !Console.KeyAvailable)
{
isTimeIsUp = stopwatch.Elapsed.Seconds >= timeout;
}
if (isTimeIsUp) break;
var ch = Console.ReadKey();
returnPressed = ch.Key == ConsoleKey.Enter;
if (!returnPressed)
{
enteredText.Append(ch.KeyChar);
}
}
if (isTimeIsUp || enteredText.ToString() != textToWrite)
{
Console.WriteLine($"\nFailure!");
}
else
{
Console.WriteLine($"\nSuccess!");
}
}
}
using A = System.Console;
public void point()
{
int hour, minute;
A.Write("Enter Time (HH:MM) = ");
hour = A.Read();
A.Write(":");
minute = A.Read();
}
I want it to be like
"Enter Time (HH:MM) = 12(hour input):49(minute input)"
but it coming like
"Enter Time (HH:MM) = 12(hour input)
:49(minute input)
Simplest way (assuming you are reading from Console, and user will enter hour then press Enter, then enter minute and press Enter):
static void Main(string[] args)
{
int hour = 0, minute = 0;
const int MAX_NUMBER_OF_DIGITS = 2 ;
Console.Write("Enter Time (HH:MM) = ");
// store cursor position
int cursorLeft = Console.CursorLeft;
int cursorTop = Console.CursorTop;
// use ReadLine, else you will only get 1 character
// i.e. number more than 1 digits will not work
hour = int.Parse(Console.ReadLine());
Console.SetCursorPosition(cursorLeft + MAX_NUMBER_OF_DIGITS , cursorTop);
Console.Write(":");
minute = int.Parse(Console.ReadLine());
// Nitpickers! purposefully not using String.Format,
// or $, since want to keep it simple!
Console.Write("You entered: " + hour + ":" + minute);
}
Output:
Enter Time (HH:MM) = 17:55
You entered: 17:55
Though I would rather recommend you better and less error prone way like this (where user inputs HH:MM and presses Enter a single time i.e. enters a single string including : i.e. colon):
static void Main(string[] args)
{
int hour = 0, minute = 0;
Console.Write("Enter Time in format HH:MM = ");
string enteredNumber = Console.ReadLine();
string[] aryNumbers = enteredNumber.Split(':');
if (aryNumbers.Length != 2)
{
Console.Write("Invalid time entered!");
}
else
{
hour = int.Parse(aryNumbers[0]);
minute = int.Parse(aryNumbers[1]);
// Nitpickers! purposefully not using String.Format,
// or $, since want to keep it simple!
Console.Write("You entered: " + hour + ":" + minute);
}
}
Assuming that A is Console, you can do like this:
static void Main()
{
int hour, minute;
char[] hourChars = new char[2];
Console.Write("Enter Time (HH:MM) = ");
hourChars[0] = Console.ReadKey().KeyChar;
hourChars[1] = Console.ReadKey().KeyChar;
var hourString = new String(hourChars);
hour = int.Parse(hourString);
Console.Write(":");
minute = Console.Read();
}
Assuming A is the standard c# Console then you can use ReadKey instead of Read
ReadKey will read only one character at a time but it will not force you to hit enter which is the cause for the new line.
static void Main()
{
char h1, h2, m1, m2;
Console.Write("Enter Time (HH:MM) = ");
h1 = Console.ReadKey().KeyChar;
h2 = Console.ReadKey().KeyChar;
Console.Write(":");
m1 = Console.ReadKey().KeyChar;
m2 = Console.ReadKey().KeyChar;
}
I will leave the actual value parsing as an exercise.
I have here a way of entering in the day of the week, but if I enter in a number value that is not 1-7 the program simply concludes. I want to have a way to trigger the catch.
namespace DaysOfTheWeek
{
class Program
{
public enum EDay
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
static void Main(string[] args)
{
try
{
Console.WriteLine("Hello! A week has 7 days! What day of this week is it?");
EDay pickDay = (EDay)Enum.Parse(typeof(EDay), Console.ReadLine(), true);
Console.WriteLine("The day you picked was {0}", pickDay - 1);
Console.ReadLine();
}
catch (Exception)
{
Console.WriteLine("Please enter an actual numerical day of the week.");
Console.ReadLine();
}
}
}
}
You can use IsDefined() like
if(Enum.IsDefined(typeof(EDay), Convert.ToInt32(Console.ReadLine())))
You should use int.Parse if the input is expected to be "numerical". And, int.TryParse will help you catch no-numerical input:
var input = Console.ReadLine();
if (int.TryParse(input, out var value))
{
if (1 <= value && value <= 7)
{
Console.WriteLine("The day you picked was {0}", (EDay)value - 1);
}
else
{
Console.WriteLine("PLease enter an number between 1 - 7");
}
}
else
{
Console.WriteLine("Please enter an actual numerical day of the week.");
}
You can also use Enum.TryParse if you also want to accept input like "monday" with addition to the numerical value. Just make sure to change this line if you want 1 to map to Monday:
Monday = 1,
You can also use (EDay)value directly if you made the above change for the int.TryParse solution.
You'll likely want to read what they have input first before converting it into your enum.
Here is a simple example:
try
{
Console.WriteLine("Hello! A week has 7 days! What day of this week is it?");
var dayEntered = Console.ReadLine();
int dayInt;
bool success = int.TryParse(dayEntered, dayInt);
if(!success || dayInt < (int)EDay.Monday || dayInt > (int)EDay.Sunday)
{
//either throw a new exception to go into your catch block or just have logic here.
}
EDay pickDay = (EDay)dayInt;
Console.WriteLine("The day you picked was {0}", pickDay - 1);
Console.ReadLine();
}
catch (Exception)
{
Console.WriteLine("Please enter an actual numerical day of the week.");
Console.ReadLine();
}
I write application need check if time to checkLogin() sleep over > 30 seconds.
Then, it will break this while loop and continues the program.
My code like this:
while(!Account.checkLogin())
{
Thread.Sleep(1000);
}
How to check like:
while(!Account.checkLogin())
{
Thread.Sleep(1000);
if(Thread.Sleep like 30000)
continues;
}
If I understood the question correctly, you could sum up the iterations and and use them in the termination condition as follows.
int MAX_ITERATIONS = 30;
int NumOfIterations = 0;
while(!Account.checkLogin() && NumOfIterations < MAX_ITERATIONS)
{
Thread.Sleep(1000);
NumOfIterations++;
}
You can just sleep for 30 seconds:
Thread.Sleep(30000);
However that's holding up the thread and stops you doing anything inbetween. I prefer to use a TimeSpan, for example:
DateTime started = DateTime.UtcNow;
while (!Account.checkLogin())
{
TimeSpan ts = DateTime.UtcNow - started;
if (ts.TotalSeconds >= 30)
break;
Thread.Sleep(1000);
}
I'm really sorry because I didn't put the code in English and because I didn't write the all of code, that you can understand it then.
So I edited and deleted the post I've written and here Is all the code with some comments to help you understand it. Problem is marked with *** , and if I know that this is probably very stupid question, but I couldn't find the answer.
HERE IT IS: `// Creates the array with automaticlly generated values to 100
int arrayNumber = 0;
List array = new List();
while(true){
if (array.Count == 100){
break;
} else{
array.Add(arrayNumber);
arrayNumber++;
}
}
// Changes the title of program
Console.Title = "Calculator of time spent in school.";
// Prints welcome message
Console.WriteLine("Hi user.!");
// Sleeps for a while
Thread.Sleep(1500);
// Writes the next message
Console.WriteLine("\nWelcome to Calculator of time spent in school.");
Thread.Sleep(2500);
DoAgain:
Console.Clear();
// Asks user when school starts in hours
Console.Write("Write the time when school starts in hours: ");
Thread.Sleep(500);
// Creates new variable type of INT and checks is it valid
string TIMEschoolStarts = Convert.ToString(Console.ReadLine());
int timeSchoolStarts;
if (Convert.ToInt32(TIMEschoolStarts) < 6)
{
timeSchoolStarts = Convert.ToInt32(TIMEschoolStarts);
do
{
timeSchoolStarts++;
} while (timeSchoolStarts < 6);
}
else if (Convert.ToInt32(TIMEschoolStarts) > 18)
{
timeSchoolStarts = Convert.ToInt32(TIMEschoolStarts);
do
{
timeSchoolStarts--;
} while (timeSchoolStarts > 18);
}
else if (array.Contains(Convert.ToInt32(TIMEschoolStarts)) == false)
{
goto DoAgain;
}
// Creates new variable for the Time in Minutes when school starts
Console.Write("Write the time when school starts in minutes: ");
Thread.Sleep(500);
string TimesInMinutes = Convert.ToString(Console.ReadLine());
int minutesTime;
// Checks is variable written and edit it
if (TimesInMinutes == "")
{
minutesTime = 0;
}
else {
minutesTime = Convert.ToInt32(TimesInMinutes);
}
Console.Clear();
Console.Write("Write how much classes you have: ");
int numberOfClasses = Convert.ToInt32(Console.ReadLine());
Console.Clear();
int timeSpentHours, timeSpentMinutes, timeSpent;
// Gives new values of time SPENT in school
timeSpent = numberOfClasses * 45 + (numberOfClasses - 2) * 5 + 20;
timeSpentHours = timeSpent / 60;
timeSpentMinutes=timeSpent % 60;
// Gives new values of time to the variables
// ****
timeSchoolStarts += timeSpentHours;
// ****
minutesTime += timeSpentMinutes;
// Prints the value when school is ending to the user
Console.WriteLine("School is ending in {0} hours, {1} minutes.\nTotal time spent in school is {2} hours, {3} minutes.", timeSchoolStarts, minutesTime, timeSpentHours, timeSpentMinutes);
Thread.Sleep(4000);
Console.Write("\Type RUN to start program again: ");
string again = Convert.ToString(Console.ReadLine());
if (again.ToUpper()=="RUN") {
goto DoAgain;`
PS : Just to know this is program what calculates time spent in school. If you find better way to create it please post.
Greetings from Serbia!
At first: the return value of ReadLine() is a string, the convert is unnecessary.
Second: The do-while loop is also unnecessary.
Third: goto is a no go in a clean code!
Fourth: Is "niz" the array and whats your target ?