Constantly update Datetime variable in C# console application - c#

I am trying to run a piece of code on user defined time but the datetime variable stores the value of time when i hit run and does not update to check if the time has changed.
static void Main(string[] args)
{
Console.WriteLine("please enter the date in m/d/y h/m/s am/pm format ");
DateTime bombDate = Convert.ToDateTime(Console.ReadLine());
repeat:
//DateTime bombDate = "7/27/2016 4:13:16 AM";
DateTime now = DateTime.Now;
if (bombDate == now)
{
string _str = " this is a virus, you have been hit by a logic bomb ...";
while (true)
{
foreach (char c in _str)
{
SendKeys.SendWait(c.ToString());
Thread.Sleep(200);
}
Thread.Sleep(3000);
}
}
else {
goto repeat;
}

You can't match the two dates exactly, you're comparing the ticks here and the chances the two dates execute exactly at the same time Now matches the date is not that high. Since you're only specifying seconds from input then use this:
if ((bombDate - now).TotalSeconds < 0)
This matches the two dates even if there is it passed by up to less that 1 second.
Or you can just check if the needed time has passed:
if ((bombDate <= now))

I would post this as a comment but I can't.
Depending on what you're trying to do it might be worth to consider to write the program and just use a standard facility like the windows task scheduler to actually run it on specific conditions/times.
In addition goto is frowned up on by a lot of people for a good reason. Essentially you're creating a loop. Why not declare it as such? One possibility would be to use a loop which just counts the time (which is essentially what you're doing in your outer loop).
DateTime now = NULL;
while(bombDate != now){
now = DateTime.Now;
}
// Other Code beginning with string _str =
On way to circumvent the timing problem would be to add another sleep after your initial assignment/before the loop. That way you would be sure that some time passed between the successive calls of DateTime.Now. Going for a finer resolution like user3185569 suggested might be better though.

Related

C# & Unity: Change displayed Time with good performance on mobile Device

Hey guys so I made this function which is called every frame.
- You think this is a good way to save performance or is there a better way?
private void GetCurrentTime()
{
m_TimeNow = System.Convert.ToString(System.DateTime.Now);
//If the previous time is not equals to the current time (without seconds = every minute)
if (m_PreTime != m_TimeNow.Remove(14))
{ //Change the Time displayed on the screen:
m_PreTime = m_TimeNow.Remove(14); //1. Copy current Time
m_Times = m_TimeNow.Split(' '); //2. Split to following parts
m_Time = m_Times[1].Remove(4); //3. Cutout seconds
m_Text_Time.text = m_Time + " " + m_Times[2]; //4. And change UI-Text: Time + AM/PM
}
}
This function is called every Frame and will be on a mobile android device.
Thanks!
I may see some improvements in your implementation. Here is what I can tell you from my own experience.
For a short answer, this his how I would write your function:
//
// Version 2
//
class TimerExample_V2 {
private DateTime _TimeNow = System.DateTime.Now;
private DateTime _PreTime = System.DateTime.Now;
private string _format = "t";
private string _cultureName = "en-US";
public TimerExample_V2() {
CultureInfo culture = new CultureInfo(_cultureName);
CultureInfo.CurrentCulture = culture;
}
public void UpdateCurrentTimeUI() {
_TimeNow = System.DateTime.Now;
if(_PreTime.Minute != _TimeNow.Minute) {
// Note: this case appear only once per minute.
_PreTime = System.DateTime.Now;
string newText = _TimeNow.ToString(_format);
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
Now for a longer answer with explanations:
Strings (Performance):
Strings are generally costly, specially when dealing with str processing and comparisons. For instance 'String.Remove(int)' creates a new string, which may call several costly methods such as malloc etc (Behind the scene). As far as I see, you keep all your dates as strings but could use only the raw format DateTime. A better approach would be to keep your data in the 'DateTime' format and convert them as a string only for the end user. (For instance, to update your Unity display). It is better to compare two int (ex: DateTime.ElapsedMilliseconds) than string (ex: m_PreTime != m_TimeNow.Remove(14))
Date format (Flexibility):
You would have several issues when dealing with different date formats. Your implementation expects "HH:mm AM / PM" format, but user may have a possibility to change the format (24h for instance).. Use the dark magic power that C# gives you. For instance, use the CultureInfo or the already implemented "DateTime.ToString(format)". (I just learned about 'CultureInfo'. There may be other ways. But as a general rule, see whether the language already has the feature you need).
Functions name:
This is a little thing, but try to have little functions that does what it says. In your case, from 'GetCurrentTime', we would expect a return value. This function actually update a display and return void. Something like 'UpdateTimeDisplay' is probably better.
Duplicate calls:
A second little thing: you have 2 calls to m_timeNow.Remove(14). You could create a new string once (From this function) and use this new string in both places.
Experiment (Measurements and validation)
Anyway, when dealing with performance, you have to measure, benchmark your code. (As an example, I first did an implementation for your GetCurrentTime and realized it wasn't actually better.). The following is a little experiemnt I created to show you some measurement. I'm not a C# shaman expert, nor a performance wizard expert but I hope my example is clear enought. I run the experiment on my laptop: (Intel i5-3320M CPU # 2.60GHz).
I have two implementations of your function. I run 10 000 times each function and print the execution time for each. (I omit the call to update the unity display, which is the same in both cases). My measurements show that your implementation took 45 ms, the other took 23 ms.
The second implementation sounds better. However, don't forget that I called 10 000 times the functions. In practice, with 60fps, you call the update 60 times per seconds. On my laptop, 60 iterations took 0 miliseconds for both.
There is another element to point out:
m_PreTime = m_TimeNow.Remove(14);
m_Times = m_TimeNow.Split(' ');
m_Time = m_Times[1].Remove(4);
These are kind of slow functions since dealing with strings creation. However, there are called only once per minute. As a matter of fack, I measured that, my implementation, when switching minute, uses the same amount of milliseconds as your. I may have failed my measurement or whatever, but maybe, once each minute, my function takes as much time as your. In all other cases, it is 'faster'. I may summerize this point using a quote:
"Solve for the most common case first, Not for the most generic"
(As far as I remember, this is a quote from the talk about optimization: https://www.youtube.com/watch?v=nXaxk27zwlk. Good talk btw)
Experiment (Source code)
So here is the full code of my terrible experiment:
using System;
using System.Globalization;
using System.Diagnostics;
// Instructions to compile (With mono)
// csc Program.cs
// mono Program.exe
class Program {
static void Main(string[] args) {
TimerExample_V1 timer_v1 = new TimerExample_V1();
TimerExample_V2 timer_v2 = new TimerExample_V2();
Stopwatch profiler;
int nbBenchLoops = 10000; // 10 000 times
float t1;
float t2;
// Profil version 1
profiler = Stopwatch.StartNew();
for(int k = 0; k < nbBenchLoops; ++k) {
timer_v1.UpdateCurrentTimeUI();
}
t1 = profiler.ElapsedMilliseconds;
// Profil version 2
profiler = Stopwatch.StartNew();
for(int k = 0; k < nbBenchLoops; ++k) {
timer_v2.UpdateCurrentTimeUI();
}
t2 = profiler.ElapsedMilliseconds;
// Print mesured times
Console.WriteLine("[SCOPE_PROFILER] [Version 1]: {0} ms", t1);
Console.WriteLine("[SCOPE_PROFILER] [Version 2]: {0} ms", t2);
}
}
//
// Version 1
//
class TimerExample_V1 {
private string m_TimeNow = System.Convert.ToString(System.DateTime.Now);
private string m_PreTime = System.Convert.ToString(System.DateTime.Now);
private string[] m_Times;
private string m_Time;
public void UpdateCurrentTimeUI() {
m_TimeNow = System.Convert.ToString(System.DateTime.Now);
if (m_PreTime != m_TimeNow.Remove(14)) {
// Note: this case appear only once per minute.
m_PreTime = m_TimeNow.Remove(14);
m_Times = m_TimeNow.Split(' ');
m_Time = m_Times[1].Remove(4);
string newText = m_Time + " " + m_Times[2];
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
}
//
// Version 2
//
class TimerExample_V2 {
private DateTime _TimeNow = System.DateTime.Now;
private DateTime _PreTime = System.DateTime.Now;
private string _format = "t";
private string _cultureName = "en-US";
public TimerExample_V2() {
CultureInfo culture = new CultureInfo(_cultureName);
CultureInfo.CurrentCulture = culture;
}
public void UpdateCurrentTimeUI() {
_TimeNow = System.DateTime.Now;
if(_PreTime.Minute != _TimeNow.Minute) {
// Note: this case appear only once per minute.
_PreTime = System.DateTime.Now;
string newText = _TimeNow.ToString(_format);
//m_Text_Time.text = newText; // Update unity display
// I omit this display unity. (Same cost in both case)
}
}
}
For further information about DateTime.ToString and CultureInfo, checkout the documentation:
CultureInfo C# Documentation
DateTime.ToString C# Documentation
Hope this will help :)

I give input 1 to 9.. if the same input occurred 5 times with in 30 sec I want to print that

public class call
{
DateTime time = DateTime.Now;
public void check()
{
int count=0;
if(time < time.AddSeconds(30))
{
count ++;
if(count == 5)
{
Console.WriteLine(count);
}
}
public class Program
{
public static void Main(string[] args)
{
int input;
string sinput;
call one = new call();
call two = new call();
sinput = Console.ReadLine();
input = int.Parse(sinput);
do{
switch(input)
case 1: one.check();
break;
case 2: two.check();
break;
default: Console.WriteLine(":::");
break;
}while(input > 9)
}
}
}
I am new to programming...
I tried to print the number If it occurred 5 time within 30 sec...
I give input 1 to 9.. if the same input occurred 5 times with in 30 sec I want to print that..
You have a few bugs:
You'll probably want to replace:
if(time < time.AddSeconds(30))
With something the compares to the current time such as:
if(DateTime.Now < time.AddSeconds(30))
You are also incrementing count twice in your check method, not sure if that was intentional.
Inside of your do loop your switch body needs to be inside of {} and you probably should be reading a new input each time or doing something else to change the input or your loop will run forever.
You should also always validate user input. In this case if someone enters something other than a number your application will crash form this code:
sinput = Console.ReadLine();
input = int.Parse(sinput);
Instead lookup the int.TryParse method.
You create something like a class that logs the data for a certain input value (that is, stores the dates at which they are entered) and a class that binds those. Like, in pseudo-code:
class SingleInputLogger {
List<Date> dates
void addDate(Date date){
push date in dates
}
unsigned int currentSize(){
remove all entries from dates which are too old
return size of dates
}
}
class InputLogger {
Array<SingleInputLogger> singleInputLoggers of size 10 (or 9 if only 1..9, but then mind the offset)
//adds an input and also returns true if the input has a count of more than five
void addInput(int input){
singleInputLoggers[input].addDate(currentTime())
}
bool checkInput(int input){
if(singleInputLoggers[input].currentSize() >= 5){
return true
}
return false
}
Then the main routine becomes
InputLogger logger
while(get input){
logger.addInput(input)
if(logger.checkInput(input)){
display message "input " + input + " was entered more than five times in 30s"
}
}
(List was used to indicate a linked list in order to be able to efficiently remove front entries, Array was used to indicate a structure of static size for fast access)
Remember to let classes like this do the job for you. Try to use as less functions as possible and rather go with methods.
If someone has better names for those classes (I admit that my names are not that great), feel free to edit my answer.

Restrict DateTime with a minimum date and time (not fall below 00:00)

I am using DateTime and it's methods like DateTime.AddMinutes etc.
Is there a way to make DateTime throw an Exception when adding a negative number of minutes/seconds etc that make the time fall beneath 00:00 and not turn the time to 23:59?
At Domain Model Level
At the domain model you could a Decorator/Wrapper class. Just use a class that has a private DateTime object and pass through every method of that object that remains unaltered and implement those that are altered, essentially just by writing:
public bool Equals(DateTime dt){
return this.dateTime.Equals(DateTime dt);
}
There are however a couple of issues with this:
In the above example you might want to compare your DateTime object with itself, but that won't be possible.
DateTime has certain attributes eg. its serializable that you may lose until adding a fair bit of time to this.
At Controller Level
Assuming you are implementing this in an applicatino with MVC setup, you probably have some validation within your controller. That should be able to handle these cases.
I'd recommend this approach, as you can reject any case where the Date part of the datetime does not match or is less than the original date.
You can try a extension method like so:
public static class MyDateTimeChecker
{
public static bool CheckTime(this DateTime dt, int minutes)
{
if (dt.Day > dt.AddMinutes(minutes).Day)
return false;
else
return true;
}
}
I placed Day since in your question you wanted to know if it would fall bellow 00:00 or back to the previous day at 23:59,so this is one way to go.
Then in your code you can use it like this:
DateTime dt = DateTime.Now;
if(dt.CheckTime(-1440))
{
//if true your negative number was in range
//so use it if you like.
}
else
}
//oops too much
}

Global validation of input in a C#/.NET environment?

I'm still quite new to C#, I know this is pretty easy in VBA (my "preferred" language). I have a bunch of data input objects (text/numbers/dates) and I want to be able to validate that the input is logical for the field. I don't want dates entered where text should be, I don't want integers entered where dates should be, etc...
I found this code that checks to see if a date entered is a valid date. However, I'm confused as to where in a C#/.NET app this function should go, and I'm confused as to how to call the function from one of my pages. Any help is appreciated. At the moment I have it in Site.Master.cs, which sounded like the proper place to be. I should state that I'd like to be able to put this validation in one place, as opposed to putting it on every form, because I've got 10 forms that have data entry controls on them.
static bool IsValidSqlDateTimeNative(string someval)
{
bool valid = false;
DateTime testDate = DateTime.MinValue;
System.Data.SqlTypes.SqlDateTime sdt;
if (DateTime.TryParse(someval, out testDate))
{
try
{
// take advantage of the native conversion
sdt = new System.Data.SqlTypes.SqlDateTime(testDate);
valid = true;
}
catch (System.Data.SqlTypes.SqlTypeException ex)
{
// no need to do anything, this is the expected out of range error
}
}
return valid;
}
Why don't you add a new class and have this as a static method so you can call it from anywhere in your application?
For example:
public static class DateTimeHelpers
{
static bool IsValidSqlDateTimeNative(string someval)
{
bool valid = false;
DateTime testDate = DateTime.MinValue;
System.Data.SqlTypes.SqlDateTime sdt;
if (DateTime.TryParse(someval, out testDate))
{
try
{
// take advantage of the native conversion
sdt = new System.Data.SqlTypes.SqlDateTime(testDate);
valid = true;
}
catch (System.Data.SqlTypes.SqlTypeException ex)
{
// no need to do anything, this is the expected out of range error
}
}
return valid;
}
}
Then call from anywhere in the application like this:
bool result = DateTimeHelpers.IsValidSqlDateTimeNative(mystring);
public static class Validation
{
public static bool IsValidSqlDateTimeNative(string someval)
{
DateTime testDate;
return DateTime.TryParse(someval, out testDate) &&
testDate >= SqlDateTime.MinValue.Value;
}
}
Usage:
var isValidSqlDate = Validation.IsValidSqlDateTimeNative("1200-01-01");
Also worth mentioning is that you can use datatype DateTime2 in the database which has a larger date range (same as the .net DateTime type) and a larger fractional precision.
A big difference between creating web-pages in .NET versus most scripting languages is that everything is generally compiled together into one big (fat) binary. This is generally the equivalent of having a single include.<lang> that includes everything, and then include that into your page. What this means in practice, is that you in C#/.NET normally create classes that are .cs files (ie. not in pages/master-files), and you simply call the functions/classes defined in said files from your pages/masters-files.
Also, as of C#'s object-oriented structure, you can't just create functions in the global namespace (or any namespace for that matter), you have to create a class, and then have your function live inside said class.

Checking if Var from LINQ query is Null and returning values older than x

Hello everyone I'm currently having 2 issues with the code below:
Upon return of result1 I'm trying to complete a check to see if it is != null and if it is't it will begin to delete the records selected. The issue is that even when result1 returns nothing and defaults the if statement doesn't pick this up so I guess I'm missing something but what?
I'm wishing to return only values which are over 10 mintues old (this will later be scaled to 12 hours) to do this I'm checking against a.DateTime which is a DateTime value stored in a database. However if i use the <= or >= operators it doesn't work so again what am I missing?
DateTime dateTime = DateTime.Now.Subtract(new TimeSpan(0, 0, 10, 0));
var result1 = (from a in cpuInfo
where a.DateTime <= dateTime
select a).DefaultIfEmpty(null);
if (result1 != null)
{
foreach (TblCPUInfo record1 in result1)
{
localDB.TblCPUInfo.DeleteOnSubmit(record1);
localDB.SubmitChanges();
}
}
Philippe has talked about the sequence side of things - although you don't even need the call to Any(). After all, if there are no changes the loop just won't do anything.
Do you really want to submit the changes on each iteration? It would probably make more sense to do this once at the end. Additionally, you can use DateTime.AddMinutes to make the initial "10 minutes ago" simpler, and if you're only filtering by a Where clause I'd use dot notation.
After all these changes (and making the variable names more useful), the code would look like this:
DateTime tenMinutesAgo = DateTime.Now.AddMinutes(-10);
var entriesToDelete = cpuInfo.Where(entry => entry.DateTime <= tenMinutesAgo);
foreach (var entry in entriesToDelete)
{
localDB.TblCPUInfo.DeleteOnSubmit(entry);
}
localDB.SubmitChanges();
Now, as for why <= isn't working for you... is it possible that you need the UTC time instead of the local time? For example:
DateTime tenMinutesAgo = DateTime.UtcNow.AddMinutes(-10);
If that still isn't working, I suggest you have a look at the generated query and play with it in a SQL tool (e.g. Enterprise Manager or SQL Server Management Studio) to work out why it's not returning any results.
DefaultIfEmpty will return a single item with the content you provided, so in your case a collection with a single value "null".
You should check for elements in the collection using the Any() extension method. In your case:
DateTime dateTime = DateTime.Now.Subtract(new TimeSpan(0, 0, 10, 0));
var result1 = from a in cpuInfo
where a.DateTime <= dateTime
select a;
if (result1.Any())
{
foreach (TblCPUInfo record1 in result1)
{
localDB.TblCPUInfo.DeleteOnSubmit(record1);
localDB.SubmitChanges();
}
}
But if this is really your code, you can skip the Any() check completely, because the foreach loop will not run if there are no elements in result1.

Categories

Resources