2

I have a monitor which displays the current time/date, and a random slideshow. When the slideshow start, it creates a list of all image files in a directory, randomizes it, and then pop pictures from it until it is empty, at which point it will generate a new one. It pops pictures at a specific interval.

I saw a picture which would make a awesome background image, and I want to find it. The problem is that I got about 50 GB of pictures, and I wont search them manually.

So my plan is to find the seed of the random object in the slideshow. If you don't specify a seed in the random objects constructor, it will use the Enviroment.TickCount property, which returns the number of milliseconds since the system started.

I know aproximentally when the picture was at the screen, and processes remember the time they started, so I could in fact calculate the seed of the random object. I also remember the last image in the slideshow sequence, due to a 5 secound delay when it generates a new sequence, so I can easily see if I got the seed right.

However, DateTime.Now does not seem to be precice to the millisecond, so if I could get that sorted out I would have to check a lot less pictures.

Sub Main()
    Dim SystemStartTime = Now.AddMilliseconds(-Environment.TickCount)

    Console.WriteLine(SystemStartTime.Millisecond) REM Prints different numbers each time. They should be equal
    Console.ReadLine()
End Sub
SysDragon
  • 9,692
  • 15
  • 60
  • 89
BlackCap
  • 1,064
  • 9
  • 14
  • "DateTime.Now does not seem to be precice to the millisecond" -> why are you saying that? – varocarbas Aug 01 '13 at 09:26
  • 3
    Take a read of the accepted answer to http://stackoverflow.com/questions/2143140/c-sharp-datetime-now-precision to find out exactly why you'll not be able to solve this particular problem. Sorry. :( – Adrian Wragg Aug 01 '13 at 09:28
  • #varocarbas Have a look at my code. The comment at the end of the forth line says that it will print different numbers each time, which means that DateTime.Now cannot be precise to the millisecond. It seems to be +- 10-15 of the actual value. As I have other factors in my problem, soliving this one would greatly reduce the amount of pictures I'll have to check manually. – BlackCap Aug 01 '13 at 09:35
  • @BlackCap OK, all clear. FYI, the right way to let me know about your answer is with '@' :) – varocarbas Aug 01 '13 at 09:39
  • @AdrianWragg nice link, although it seems to refer to a much smaller (sub-)unit: the micro-second. – varocarbas Aug 01 '13 at 09:40
  • 1
    @varocarbas He mentions microsecond, but only as an example. The main point is that you can't guarantee accuracy if there isn't the precision in the first place. You may be dealing with a system that is not precise to the nearest millisecond. – Adrian Wragg Aug 01 '13 at 09:42
  • @AdrianWragg yes, I got that. But I think that you can get a close-to-perfect accuracy on the milisecond level (for what BlackCap wants at least). – varocarbas Aug 01 '13 at 09:44
  • 1
    @BlackCap I did test your code and got your point. Sorry to say that this testing proceeding is not accurate (and not because of the Adrian Wragg link): the fact of getting different values when executing different times does not imply necessarily that "now" is not accurate, but that the different executions do not have the same duration. Every time you execute your application, there are lots of things involved (other programs running on your computer, for example) which are influential even until the second and beyond. You should perform a different type of test (out of space) – varocarbas Aug 01 '13 at 09:48
  • @BlackCap for example, you might take the time within a loop for a low enough number of iterations (below 5000 for example). This test would offer much more reliability regarding the exact accuracy of "Now". BTW, why are you are writing a VB.NET code and putting the C# tag? – varocarbas Aug 01 '13 at 09:51
  • @varocarbas I have a VB.NET tag aswell, as it is related to both languages. I write in vb because I favor the language, and because c# programmers tend to understand both languages while vb programmers don't. And thank you for writing that out, I'll go and run some tests now :) – BlackCap Aug 01 '13 at 10:00
  • @BlackCap Can I also suggest http://photo.stackexchange.com/questions/14094/is-there-a-free-visual-similarity-image-local-hard-drive-search ? Might be easier :) – Adrian Wragg Aug 01 '13 at 10:06
  • 1
    @blackcap I think that the statement "c# programmers tend to understand both languages while vb programmers don't" is quite imprecise too (and perhaps offenssive for someone). Other thing I forgot to mention: additionally to non-ideal conditions, you are not calculating things properly; you should rely on TimeSpan (to determine the actual period of time between two now events); you are just substracting 1ms to the current time (example: minutes in 10:23 -1 min delivers a different value than minutes in 10:35 - 1 min (what you are doing)). – varocarbas Aug 01 '13 at 10:07
  • @varocarbas Environment.TickCount is not a constant, like for example 1. Environment.TickCount gets the number of milliseconds since the system started, so to get the instant when the system started you could subtract that number from the current time. E.g. The system started 10:00 and the current time is 10:01. Environment.TickCount would be 1000, and 10:01 - 1000ms = 10:00 – BlackCap Aug 01 '13 at 10:21
  • @BlackCap I know that. The problem is that, after substracting the ticks since the start (a variable, like the time required to start the program every time, as explained above), you are taking the miliseconds in the resulting time as reference. As explained: if now is 10:23 milliseconds(10:23 - variable) = some value; if now is 10:40 milliseconds(10:40 - variable) = another value, not related with the previous one. – varocarbas Aug 01 '13 at 10:25
  • @BlackCap - if you could reverse engineer the seed how would you find the picture you are looking for? – dbasnett Aug 01 '13 at 12:27
  • @dbasnett I wrote the program, so I have the code. I know how it works, which I described at the start of my question. There is a specific number of images, and each of them is displayed on the screen for a specific time. So I can calculate how long it takes to display all the pictures, divide it by how long the application have runned, floor the number, multiply it by the number of pictures, and then generate that many numbers with the random object. Then I can produce the random sequence which the application had, and walk aproximentally to where my picture is. That's the idea. – BlackCap Aug 01 '13 at 14:34
  • You're probably better off writing something that will examine each image so that you can narrow down the list. For example, if the picture had a "mostly blue" background, you could write a filter that looks for pictures that have lots of blue in them. That would narrow down the list of images you have to examine manually. Trying to reverse-engineer the random number seed based on the time the program was started is going to be very, very difficult. – Jim Mischel Aug 01 '13 at 15:59
  • Why not save the datetime and random number in a dictionary. Then if you want to find a picture by datetime you could write a query to narrow it down to some datetime range. – dbasnett Aug 01 '13 at 21:09

1 Answers1

0

Environment.TickCount is a bit difficult to use properly. Because it's a 32-bit signed integer, it will max out at 2,147,483,647 ticks, which is approximately 24.9 days. The next tick will be -2,147,483,648, which is negative. So you can't just add it to a DateTime without risking errors. It sounds like your code might run on some kind of kiosk display, which could certainly stay running for months at a time. See these MSDN docs for reference.

Another issue - DateTime.Now returns a local date/time. It is adjusted to the time zone of the computer, which might have fluctuations for daylight saving time. If you were going to base it off of the clock at all, you should probably use DateTime.UtcNow instead.

Regarding precision - while the DateTime type has extremely fine precision (10 million ticks == 1 second), the windows system clock is only accurate to about 10 to 30 milliseconds (depending on your hardware and Windows version). There are no guarantees about how exactly accurate of a reading you will get. Even if you had very fine precision from the clock, you would still need to take clock drift into consideration, and remember that the user can change their clock at any time. Even if you periodically sync the clock over the Internet, that level of accuracy is not guaranteed.

You may want to read this MSDN article. Also, you can read on accuracy vs precision.

As an aside - if you really wanted both high accuracy and high precision, you would need a stratum 0 time source, such as those sold by this company and others. I'm entirely certain that this would be overkill for the application you described.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575