Intercepting user Date Time change

P

pamela fluente

I would need a method within my program to intercept
a user attempt to change the time or date of the pc.

In such a case a need to inform him and prevent the change time date
change
while the program is running .

How can i do that ? Any example ?

-P


(reason: this is a trading application where the pc is assumed to be
previously synchronize it with an internet Time server
no time change has to be made while running, not even accidentally)
 
A

Arne Vajhøj

I would need a method within my program to intercept
a user attempt to change the time or date of the pc.

In such a case a need to inform him and prevent the change time date
change
while the program is running .

How can i do that ? Any example ?
(reason: this is a trading application where the pc is assumed to be
previously synchronize it with an internet Time server
no time change has to be made while running, not even accidentally)

The obvious solution is what you already have been pointed to: removing
the privilege to do it.

If that is not possible, then you need to really fiddle with Windows.

Basically you need to intercept:
http://msdn.microsoft.com/en-us/library/ms724942.aspx

And C# and VB.NET are not the right languages for that. You
should use C++. Unmanged ofcourse.

And maybe you can use a framework like this:
http://research.microsoft.com/en-us/projects/detours/

Arne
 
P

pamela fluente

The obvious solution is what you already have been pointed to: removing
the privilege to do it.

If that is not possible, then you need to really fiddle with Windows.

Basically you need to intercept:
   http://msdn.microsoft.com/en-us/library/ms724942.aspx

And C# and VB.NET are not the right languages for that. You
should use C++. Unmanged ofcourse.

And maybe you can use a framework like this:
   http://research.microsoft.com/en-us/projects/detours/

Arne

Thanks.

The problem is that those users are the administrators of their
machines
and rightly using them for the purpose of trading.

What i would probably need is some way to do that programmatically:
inform ad prevent
time changes while program is running.
(If they want to change time, they can shut down the program.)

But i am not sure i that would work and how to do that by API

P
 
A

Armin Zingler

Am 13.02.2011 15:46, schrieb pamela fluente:
The problem is that those users are the administrators of their
machines
and rightly using them for the purpose of trading.

What i would probably need is some way to do that programmatically:
inform ad prevent
time changes while program is running.
(If they want to change time, they can shut down the program.)

But i am not sure i that would work and how to do that by API

Even though I agree with the previous posters, here's what
I was about to post before reading their replies:

IMO the key question is: Why does your program have a problem with
date/time changes done by the user but not with changes due to
synchronization with a timer server? Both can change the time in a
non-linear way. Why is the one better/worse than the other?

What if daylight saving time becomes (in)active during the process?
Or do you use UTC times?

One possible approach: At application startup, retrieve DateTime.Now
and Environment.TickCount. Later, whenever you need the current time,
do not retrieve DateTime.Now again. Instead, calculate the current
DateTime by adding (environment.tickcount - StartupTickCount) to the
startup DateTime. Be aware that environment.Tickcount wraps after
~49 days. The drawback is that changes by synchronizing with the
time server don't have an effect. (but non-linear date/time changes
during the lifetime of your application aren't allowed anyway - or
are they?)

Another approach is comparing the timespan between two calls of
environment.tickcount to the timespan between two calls of datetime.now.
If the deviation exceeds a certain threshold, you could assume that
the user has changed the time manually. UTC time should be used
for that.
 
A

Arne Vajhøj

The problem is that those users are the administrators of their
machines
and rightly using them for the purpose of trading.

What i would probably need is some way to do that programmatically:
inform ad prevent
time changes while program is running.
(If they want to change time, they can shut down the program.)

But i am not sure i that would work and how to do that by API

You could have your .NET app call some native code that hooked
into that API call and disabled that.

But you would need a programmer with pretty good Windows
internals skills to do that in a safe way.

It is not a very good solution.

The traditional solution would be to just inform the users
that playing with time is reason for immediately termination
of employment.

The alternative would be to code your app in such a way
that it is not affected by changes in time.

Like:
now = time program start + (Environment.TickCount now -
Environment.TickCount at program start)

Arne
 
S

StrandElectric

The traditional solution would be to just inform the users
that playing with time is reason for immediately termination
of employment.
Hardly 100% effective if the time *must not* be changed. Maybe someone
wanted to be terminated anyway or for some types of people such a 'no!'
warning must be ignored -- it is irresistable!
 
A

Arne Vajhøj

Hardly 100% effective if the time *must not* be changed. Maybe someone
wanted to be terminated anyway or for some types of people such a 'no!'
warning must be ignored -- it is irresistable!

Not 100% effective.

But there are many other bad things an unhappy employee could
do with a trading system.

Arne
 
P

pamela fluente

ahahah Very funny

thanks to all :))

About the question why the automatic synchronization will not
generally harm
(as could one user putting the system 1 day before)
is because we start with a system already correctly synchronized, and
any
adjustment (if any at all) will be too small to be influential.

The time used is always NY time. No matter how the program is running.

So when the program creates a price chart using real time data feed
it will use the computer time to generate the NY time.

The price charts have time on abscissa (x=time y=price). The price
curve is drawn by using GDI+

If the user changes the time, for instance 5 hours back, he will mess
up all the
price chart, because the new prices arriving will be associated with
past prices.

Same problem for orders. That is why i wanted to prevent time changes:
it would create a real mess.

I was hoping there was some API snippet, that maybe someone in the
past used for a similar purpose.

P
 
A

Armin Zingler

Am 13.02.2011 20:28, schrieb pamela fluente:
thanks to all :))

About the question why the automatic synchronization will not
generally harm
(as could one user putting the system 1 day before)
is because we start with a system already correctly synchronized, and
any
adjustment (if any at all) will be too small to be influential.

The time used is always NY time. No matter how the program is running.

So when the program creates a price chart using real time data feed
it will use the computer time to generate the NY time.

The price charts have time on abscissa (x=time y=price). The price
curve is drawn by using GDI+

If the user changes the time, for instance 5 hours back, he will mess
up all the
price chart, because the new prices arriving will be associated with
past prices.

Same problem for orders. That is why i wanted to prevent time changes:
it would create a real mess.

I was hoping there was some API snippet, that maybe someone in the
past used for a similar purpose.

If the real time data does not have a time stamp, I'd go with the
environment.tickcount approach to store with the data and use
it as the criterion on the x axis. DateTime can be stored and displayed
additionally, but just as an informational text. This also solves
the (rare) problem of changed local times due to DST (NY is
EST/EDT?). As you said that DateTime is only important throughout the
lifetime of your application, this should work. Otherwise you'd need
a more reliable time source than the local computer.
 
P

pamela fluente

Am 13.02.2011 20:28, schrieb pamela fluente:

















If the real time data does not have a time stamp, I'd go with the
environment.tickcount approach to store with the data and use
it as the criterion on the x axis. DateTime can be stored and displayed
additionally, but just as an informational text. This also solves
the (rare) problem of changed local times due to DST (NY is
EST/EDT?). As you said that DateTime is only important throughout the
lifetime of your application, this should work. Otherwise you'd need
a more reliable time source than the local computer.

Thanks Armin.

If we had a time stamp, the problem would not exists.

I use the timezone object to convert local time to NY time (est/edt).

There is no day light problem because that is corrected automatically
by .NET timezones.

The problem is with user changing the time.

Time is not just informational text, but it's the price position on X
axis.
So if time is changed the whole chart is messed up (because the prices
will go back and forth when time restored).
And the chart corruption would be permanent (even, impossible to fix).
Also order time data will be corrupted.

Pam
 
A

Armin Zingler

Am 13.02.2011 22:23, schrieb pamela fluente:
Thanks Armin.

If we had a time stamp, the problem would not exists.

I wanted to say "*As* the real time data does not have..." :)
I use the timezone object to convert local time to NY time (est/edt).

But NY time is also local time.
There is no day light problem because that is corrected automatically
by .NET timezones.

Imagine it's 01:59 AM on the day in November(?) on which time is
switched back one hour. So, two minutes later it's 01:01 AM. This would
confuse your chart too even that it's local time. So, *if* you are
using a DateTime value for the x scale, you should use UTC time.
Still you can _display_ the local time:

____01:58___01:59____01:00___01:01___


I'd make use of the DateTimeOffset type instead of DateTime because
you can additionally display the offset. The Kind property of a DateTime
value can only say that it's "local", but it doesn't make a statement
about the offset - whereas the DateTimeOffset type does.
The problem is with user changing the time.

I know. :)
Time is not just informational text, but it's the price position on X
axis.

I know. :) That's why I meant you should....
So if time is changed the whole chart is messed up (because the prices
will go back and forth when time restored).
And the chart corruption would be permanent (even, impossible to fix).
Also order time data will be corrupted.

.... use environment.tickcount as the - obviously - only reliable linear time
source. In other words...:

Public Class Main

Public Shared ReadOnly StartupDateTime As DateTime = DateTime.Now
Public Shared ReadOnly StartupTickCount As Integer = Environment.TickCount

Shared Function GetNow() As DateTime

Return StartupDateTime + TimeSpan.FromMilliseconds(Environment.TickCount - StartupTickCount)

End Function

End Class

Instead of getting DateTime.Now, always call Main.GetNow().

However, I haven't verified the influence of Standby or Hibernation on
Environment.TickCount yet.
 
T

Tom Shelton

pamela fluente formulated the question :
I would need a method within my program to intercept
a user attempt to change the time or date of the pc.

In such a case a need to inform him and prevent the change time date
change
while the program is running .

How can i do that ? Any example ?

-P


(reason: this is a trading application where the pc is assumed to be
previously synchronize it with an internet Time server
no time change has to be made while running, not even accidentally)

The system sends out a WM_TIMECHANGE (&H1E) message to all running
applications when the time has been adjusted:

Option Strict On
Option Explicit On

Public Class Form1

Protected Overrides Sub WndProc(ByRef m As
System.Windows.Forms.Message)

If m.Msg = &H1E Then
Debug.WriteLine("Time changed")
End If
MyBase.WndProc(m)

End Sub
End Class


Start in Debug mode, and then change your system date time.... This
happens no matter how the time is changed. This happens even if it is
changed from another application.

HTH
 
P

pamela fluente

Am 13.02.2011 22:23, schrieb pamela fluente:

Thanks a lot Armin, a lot of good information! Very helpful

For the day light saving hour shift, i think i have not seen this
issue, because probably this happens when markets are closed (tick
data not arriving)
in the US. (Trading restarts on Sundays around 18:00 edt)

cf: http://www.timeanddate.com/worldclock/timezone.html?n=179

I did not know about DateTimeOffset, I have to take a look. :)


Pam
 
P

pamela fluente

pamela fluente formulated the question :




The system sends out a WM_TIMECHANGE (&H1E) message to all running
applications when the time has been adjusted:

Option Strict On
Option Explicit On

Public Class Form1

    Protected Overrides Sub WndProc(ByRef m As
System.Windows.Forms.Message)

        If m.Msg = &H1E Then
            Debug.WriteLine("Time changed")
        End If
        MyBase.WndProc(m)

    End Sub
End Class

Start in Debug mode, and then change your system date time....  This
happens no matter how the time is changed.  This happens even if it is
changed from another application.

HTH

Thanks a lot Tom :))

this is another piece of beautiful information!

Well ... this is already something: i could perhaps stop the data flow
if the time is going backward, and ask the user to undo the time
change (if it's in the past).

Sounds reasonable ? ... (the only problem would be perhaps with time
for possible orders occurring in the meantime ... )


-Pam
 
P

pamela fluente

Sounds reasonable ? ... (the only problem would be perhaps with time

Anyway using Armin function i should not need to make any correction
nor block the data, as the tickcount
would not be affected by time changes. Right ?

Can i safely relay on the Armin's trick

StartupDateTime + TimeSpan.FromMilliseconds(Environment.TickCount -
StartupTickCount)

or is there something else i should be aware of ?

If this works fine i could just use it in place of the Now() and
transform to NY (edt) time...

TimeZoneInfo.ConvertTime(Now, TimeZoneInfo_LOCAL, TimeZoneInfo_EDT)
 
A

Arne Vajhøj

Anyway using Armin function i should not need to make any correction
nor block the data, as the tickcount
would not be affected by time changes. Right ?

Can i safely relay on the Armin's trick

StartupDateTime + TimeSpan.FromMilliseconds(Environment.TickCount -
StartupTickCount)

or is there something else i should be aware of ?

If this works fine i could just use it in place of the Now() and
transform to NY (edt) time...

TimeZoneInfo.ConvertTime(Now, TimeZoneInfo_LOCAL, TimeZoneInfo_EDT)

It sounds fine to me.

Remember that Environment.TickCount wraps around when the computer
has been running for approx. 25 days.

Arne
 
A

Armin Zingler

Am 14.02.2011 01:02, schrieb pamela fluente:
Thanks a lot Armin, a lot of good information! Very helpful

You're welcome! This is always nice to read! :)


Still I'm not happy with these solutions.^^
My first choice is restricting the user right to change
the time. I have missed the point why this is not possible.
As the use can change the time, the time server is useless
(for your application) anyway.

Would it be possible that your application itself retrieves
the time from a reliable source _each time_ you need it (or
even different sources if it's important)? So, whenever you
receive a data sample, you also query a reliable source (or
sources) for the current time. This makes your application
independent from the system time.



....thinking...coding...thinking...



This is ALL useless! Why? Because you don't have the guarantee
of a correct DateTime.Now even when you start your application!
Therefore, the Environment.tickcount approach doesn't make
sense, too. The intervals might be correct - subject to standby/
hibernation issues - but the time itself is still not correct.
Consequently, you MUST access an external time source from within
your application as the local source is not reliable.

Simple but true. Am I wrong?
 
T

Tom Shelton

Armin Zingler presented the following explanation :
Am 14.02.2011 01:02, schrieb pamela fluente:

You're welcome! This is always nice to read! :)


Still I'm not happy with these solutions.^^
My first choice is restricting the user right to change
the time. I have missed the point why this is not possible.
As the use can change the time, the time server is useless
(for your application) anyway.

I agree... Why do the user's have to have local admin rights?
Would it be possible that your application itself retrieves
the time from a reliable source _each time_ you need it (or
even different sources if it's important)? So, whenever you
receive a data sample, you also query a reliable source (or
sources) for the current time. This makes your application
independent from the system time.

ntp is not that difficult a protocol :) And there are lots of
timeservers..... Might not be a bad option except, I fear the latency
penalty of aquiring the time from a remote source, might be too much
for hte OP to bear.
 
A

Armin Zingler

Am 14.02.2011 03:03, schrieb Tom Shelton:
ntp is not that difficult a protocol :) And there are lots of
timeservers..... Might not be a bad option except, I fear the latency
penalty of aquiring the time from a remote source, might be too much
for hte OP to bear.

If updating the application internal base datetime from the external
source is done in intervals in the background, latency shouldn't
be an issue.

now = datetime from last ntp update + ticks since last update

Any pitfalls?

The only one I can think of is standby/hibernation. But if
this can be reliably handled by handling Microsoft.Win32.SystemEvents.PowerModeChanged,
this shouldn't be an issue, too. Well, there's still a small chance
that the event occurs a little too "late". I mean, between waking up
from hibernation and the occurrance of the PowerModeChanged,
our new "Now" function could have been called, and it would
return a too small value. But, a) the situation is VERY rare,
b) all datetimes are still in order and thus shouldn't harm anything.

(Is environment.tickcount reset after hibernation? :) )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top