I'm using the WMP (AxWindowsMediaPlayer) in a C# project and would like to extract the exact time stamp up to 0.1 or 0.01 seconds. Is there any way how to accomplish that?
The following won't work as it's too imprecise :-/
player.Ctlcontrols.currentPositionString
I don't think that having a timer running simultaneously is a good solution because I would have to stop and resume it every time the user pauses the video, and it will eventually become wrong after a few pauses and resumes.
Have you tried using the currentPosition property which returns a double in seconds from start instead of the currentPositionString which returns a string MM:ss format.
The string format will only give you precision to the closest integer value of the second. The currentPosition property which is a double should be giving you fractions of a second.
References
currentPositionString http://msdn.microsoft.com/en-us/library/windows/desktop/dd564739(v=vs.85).aspx
currentPosition http://msdn.microsoft.com/en-us/library/windows/desktop/dd564740(v=vs.85).aspx
Related
I have a GUI working on the front end. But on the back end I have a little problem with my math. Code is trying to calculate how much time has gone with only starting and ending hours. (There are no info on days). So I think I found the way to calculate the hours spent on paper. But in C# I failed I think because of local variable stuff.
float start = float.Parse(textBox1.Text);
float end = float.Parse(textBox2.Text);
float hours_spent = end - start;
if (start > end) {
hours_spent = 24.00f -start + end;
}
First part is working correctly but when I give the start bigger than end, it gives me random numbers.
EDIT: When i gave 14.00 as an input and 13.00 as an output i get -76
and for input 14.00 output 12.00 i get -176 and for 18.50 to 10.25 i get -801. It is not random i can see that too my bad on choosing the words. But i dont get it what is wrong
When i gave 14.00 as an input and 13.00 as an output i get -76
You are parsing in a part of the world where . is not the decimal separator but is a common "group" separator. That is, a number like one hundred thousand plus a quarter is written 100.000,25, and not as it would be in the United States, 100,000.25. Parse assumes that the string is in the format of the current user's locale unless you tell it otherwise.
Therefore you are parsing the strings into values 1400 and 1300. Their difference is -100, which is less than 0, so you add 24 to -100 and get -76.
Same for your other case. You have 1850 and to 1025, subtract them to get -825, add 24 and you get -801.
There's nothing "random" at all here; everything is working as expected.
There is a lesson here: work backwards. You got -76. How'd that happen? You must have added 24 to something. What added to 24 gives you -76? -100. How did we get -100? And so on.
Start over. You should not be parsing floats in the first place. If this is a decimal quantity then you should be parsing a decimal, and if you know that it will always have . as the decimal separator, you should say so when you parse it. (Hint: use the version of TryParse that takes a NumberStyles and set the style correctly.)
If, on the other hand, you know that this is two integers separated by a period, then you should not be parsing it as a decimal or a float. You should be parsing an integer, then a period, then an integer.
If this is hours then a period then minutes, then again, you should not be using any of the above. Use a date and time parser to parse dates and times.
In short: use the right tool for the job you actually have to do.
Other problems with your code:
Use TryParse, not Parse, when dealing with user input. You don't know that there is a valid number in there, but Parse will crash if it gets bad input.
Your math is probably wrong. If someone puts in 100 and 200, do you really want -76 as the output?
Take a step back and ask yourself what the real business process is that you're trying to build here. Write that business process down carefully and then implement that process, not an approximation of it. Your business process probably does not say "parse a float using the rules of the current locale" but that's the code you wrote. Write code that means exactly what you intend it to mean.
UPDATE: Comments on the question indicate just how deep a hole you've gotten yourself into:
If entry time is 13.55 and exit time is 14.05 what should be the expected logical result ? It should be 10 (minutes) or 50 (numeric difference) ?
I am expecting 10 as minutes
Then absolutely you should not be parsing as float or decimal! Parsing as float or decimal is obviously completely wrong because 1.1 and 1.10 are the same value as a number, but nine minutes different if it is "hours.minutes", and you can't tell which case you are in by parsing as a number.
Again, you need to stop writing code, erase everything you've written so far, and start over. You're in a hole: stop digging deeper, fill in the hole, and get back to ground level.
You need to figure out exactly what format your strings are in, and parse exactly that format and nothing else.
So, write a specification that poses and then answers questions about what is allowed and what is not. Are negative values allowed? What if the number of minutes is more than 60? What if the minutes or hours are missing entirely? And so on.
Once you have a specification, write test cases that verify the spec. Then write an implementation, and run your tests. The code is more likely to be correct if you write the tests first.
I'm going to completely ignore providing a didactic answer in favor of trying to sidestep the problem.
Avoid writing your own parsing code. Instead, replace all your TextBoxes with DateTimePickers with Format set to Time. Then pull out the time by calling the .Value.TimeOfDay property. TimeOfDay is a TimeSpan, so it supports simple arithmetic.
Warning: Watch out when pulling these results using the provided properties. For example, 150 minutes can be translated as either 2 .Hours and 30 .Minutes or to 150 .TotalMinutes .
I'm trying to make a game something like don't starve where I have a variable called hunger. I want this to decrease overtime and if it goes to zero then the player's health starts decreasing as well. Also I would like it to deplate faster if you are sprinting (sprint is already working). The main question is simply how to decrease the hunger variable faster and faster overtime based on the last time you've eaten.
Something like this:
As a variant:
Assuming your game got some kind of manager thread which monitors passing time and all global events are launched from there
Figure out formula for derivative of that function - it can be discrete. Store not only current value of "hunger" but alsotime stamp of last time of having food. Here, you can also have some kind of parameter, "food quality" that would affect speed? Difference between current time and timestamp gives you value to integrate your hunger decrease function by substracting result from "hunger".
Steps of check might be irregular, then just derivative and passed time is not enough... e.g. if there was time skip because of sleeping (though such time skips might be emulated by increasing pace of monitor thread). you have to store value of time of last step was done.
A just need a stable count of the current program's progression in milliseconds in C#. I don't care about what timestamp it goes off of, whether it's when the program starts, midnight, or the epoch, I just need a single function that returns a stable millisecond value that does not change in an abnormal manner besides increasing by 1 each millisecond. You'd be surprised how few comprehensive and simple answers I could find by searching.
Edit: Why did you remove the C# from my title? I'd figure that's a pretty important piece of information.
When your program starts create a StopWatch and Start() it.
private StopWatch sw = new StopWatch();
public void StartMethod()
{
sw.Start();
}
At any point you can query the Stopwatch:
public void SomeMethod()
{
var a = sw.ElapsedMilliseconds;
}
If you want something accurate/precise then you need to use a StopWatch, and please read Eric Lippert's Blog (formerly the Principal Developer of the C# compiler Team) Precision and accuracy of DateTime.
Excerpt:
Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.
If you don't need an accurate time, and you don't care about precision and the possibility of edge-cases that cause your milliseconds to actually be negative then use DateTime.
Do you mean DateTime.Now? It holds absolute time, and subtracting two DateTime instances gives you a TimeSpan object which has a TotalMilliseconds property.
You could store the current time in milliseconds when the program starts, then in your function get the current time again and subtract
edit:
if what your going for is a stable count of process cycles, I would use processor clocks instead of time.
as per your comment you can use DateTime.Ticks, which is 1/10,000 of a millisecond per tick
Also, if you wanted to do the time thing you can use DateTime.Now as your variable you store when you start your program, and do another DateTime.Now whenever you want the time. It has a millisecond property.
Either way DateTime is what your looking for
It sounds like you are just trying to get the current date and time, in milliseconds. If you are just trying to get the current time, in milliseconds, try this:
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
I've inserted a variable of type Double in the application/settings file and I'm using a "while" loop to do a small calculation:
double final=0;
double cost = application.settings.default.cost; // 0.15
while(true)
{
Thread.Sleep(1000); //speeded up version of 60000 (1 minute)
final+=cost;
//code that waits for the user to quit the loop
}
the result after 1 hour should be 9.00 but it's calculating to something like 24.00 :/
however, if I hardcode the value in to the code, I get the desired result of 9.00
double final=0;
double cost = 0.15
while(true)
{
Thread.Sleep(1000); //speeded up version of 60000 (1 minute)
final+=cost;
//code that waits for the user to quit the loop
}
Any ideas?
Thread.Sleep(1000); does not mean that your code is executed exactly every second.
If you run your code this way 10 times for 1 hour you will get 10 different results.
This was discussed here as well:
How accurate is Thread.Sleep(TimeSpan)?
(although there Thread.Sleep is used with a TimeSpan. The main issue stays the same)
Edit:
I don't know what exactly your are calculating. But calculating costs in this way is not a good approach as it is very inaccurate.
Better take a timestamp when you start calculating your costs and take another one when you are finished. Take the difference of both timestamps and you can calculate the costs quite accurately. Your method gets more and more inacurrate the longer your code us running.
This question is about System.Threading.Thread.Sleep(int). I know there is no method for a decimal value, but I really need to work with decimals.
I have a device which takes 20.37 milliseconds to turn by 1 degree. So, I need to put the code to sleep for an appropriate multiplication of 20.37 (2 degrees = 20.37*2 etc). Since the thread class got no decimal sleep method, how can I do this?
That does not work that way. Sleep will grant you that the thread sats idle for x time, but not that it won't stay idle for more. The end of the sleep period means that the thread is available for the scheduler to run it, but the scheduler may chose to run other threads/processes at that moment.
Get the initial instant, find the final instant, and calculate the current turn by the time passed. Also, do not forget to check how precise the time functions are.
Real-time programming has some particularities in its own as to advice you to seek for more info in the topic before trying to get something to work. It can be pretty extensive (multiprocessing OS vs monoprocessing, priorities, etc.)
Right, as pointed out in the comments, Thread.Sleep isn't 100% accurate. However, you can get it to (in theory) wait for 20.27 milliseconds by converting the milliseconds to ticks, and then making a new TimeSpan and calling the method with it, as follows:
Thread.Sleep(new TimeSpan(202700))
//202700 is 20.27 * TimeSpan.TicksPerMillisecond (which is 10,000)
Again, this is probably not going to be 100% accurate (as Thread.Sleep only guarantees for AT LEAST that amount of time). But if that's accurate enough, it'll be fine.
You can simply divide the integer - I just figured that out.
I needed less than a milisecond of time the thread sleeps so I just divided that time by an integer, you can either define a constant or just type in:
System.Threading.Thread.Sleep(time / 100);
Or what number you want.
Alternatively, as mentioned, you can do it like:
int thisIsTheNumberYouDivideTheTimeBy = 100;
Thread.Sleep(time / thisIsTheNumberYouDivideTheTimeBy);
Its actually quite simple. Hope that helped.
By the way, instead of
System.Threading.Thread.Sleep(x);
you can just type
Thread.Sleep(x);
unless you haven't written
using System.Threading;
in the beginning.
I had the same problem. But as a work around, i substitute the float vslie but convert to int value in the passing. The code itself rounds off for me and the thread sleeps for that long. As i said, its a work around and i'm just saying, not that it's accurate
You can use little bit of math as a workaround.
Let´s assume, that you don´t want to be extremely precise,
but still need overall float precise sleep.
Thread.Sleep(new Random().Next(20,21));
This should give you ~20.5 sleep timing. Use your imagination now.
TotalSleeps / tries = "should be wanted value", but for single sleep interval, this will not be true.
Dont use new Random() make an instance before.