I'm creating in-memory local cache of a network filesystem.
I want every directory/file to have LastDownloadedTime attribute, and then compare it with current time to decide whether the directory/file is too old to be used from cache.
But I'm uncertain whether DateTime.Now() is what I need. What happens if the user changes system time? How can simestamps suitable for my task be obtained in .NET?
Take a look at System.DateTime.UTCNow(). It'll return the UTC time. Just make sure you are consistently calling on both ends (when you store the cache as well as when you test it for expiration).
More info: https://msdn.microsoft.com/en-us/library/system.datetime.utcnow(v=vs.110).aspx
You should use DateTimeOffset. According to the docs:
Uniquely and unambiguously identify a single point in time. The DateTimeOffset type can be used to unambiguously define the meaning of "now", to log transaction times, to log the times of system or application events, and to record file creation and modification times.
If your application is running on a user's machine, though, they could change their system time (as you mentioned). The only way to prevent that is to have your application ping a time server to get an authoritative timestamp.
I think I'm going to use Stopwatch for timestamps, because my filesystem cache is in-memory, it does not survive system reboot. Timestamps are going to be relative to the start of the Stopwatch.
Though, Stopwatch is known to be buggy.
But I consider system clock-dependent solutions to be even more dangerous, as the user may set system clock to some date in the past, messing everything up.
If you are staying within bounds of local server then DateTime.UtcNow is the most convenient option for the task. Yes, if user changes local time, then that will invalidate cache and trigger unnecessary update.
You will need to use NTP (time) servers to avoid that problem. So, instead of using local server UTC time, you will obtain UTC time from NTP server (there are plenty of them available around the world).
Please refer to NTP wikipedia article
Related
How do I expire an exe after certain date/Time. Like I want to expire an exe/Application on date 12-12-2018.
Currently I only know about two ways ::
Computer Date: I have DateTim.Now in C#, So I can compare user system date with my hard-coded date but it is not trustworthy because it checks the date from the user Computer Date which a user can change.
Internet Date: I make a request to Internet to get date but I can't rely on internet because It is possible that user won't connect to internet at the time using my Exe, so i can't make it dependent on internet.
So how do you expire your exe in safe and secure manner.
(I am not talking about license system etc that many stackoverflow Q/A suggested I am just talking about simply way to do this. If it is not possible please do answer also.)
well, it depends a bit on how reliable the system has to be...
of course you can allways say: the code has left your hands -> from now on nothing is reliable ... your code can be tampered with, the hardware is not under your control... so in the end, this task can not be done right, if you consider every possibility
but you can make it a bit harder for someone to tamper with the system...
let's say you have some sort of application state, that is initialized at first start using an internet service that verifies that the software did not expire yet... of course this has to be secured and authenticated with something like TLS and an embedded certificate... (bonus points if you use the bytes from the certificate elsewhere as constants in your program)
now this state has to hold something the program needs to work on, in other words, it is mandatory that this state is affected by changes that are persisted. additionally the state holds the expiry date, and the greatest timestamp your program has seen so far
for example you can have a counter in there that counts operations in your program ... do something, increment the counter, etc
the counter state then is saved along with the data your program is working on, like in a file header, when you write something
of course this information needs some sort of anti-tampering mechanism ... along with the counter state, save the current timestamp and a hash over the file content... then create some sort of signature over the header
when you load that file, verify the signature, the content hash, the timestamp has to be in the past, and the current counter state has to be greater than the saved counter state
the application state is saved the same way on a regular interval and of course you check the state on every startup (expired, greatest known timestamp < current timestamp, signature)
of course someone with brain.exe can poke around a little and dismantle a mechanism like this, but it is a little harder than just reseting a clock
edit:
and of course you can check if there is a filesystem available to write on, that is NTFS formatted, where you can store something hidden in an alternate data stream...
you can also have a config file that you write to AFTER your initial program checks are complete, and compare the last write time of that file to the current system clock to see if it was reset
you can also check for files on the harddrive that are newer than the date the system clock shows you...
I'm reading a lot about timezone, offset, utc, local time, javascript functions, DST, bacon and I 'm trying to put this all together to build a solid/correct structure for my app.
Suppose my app is something like StackOverflow.
That is how I'm doing ...
The server is in another country, so I set it to UTC 00:00.
I'm storing date as DateTimeOffset.
I'm not storing TimeZoneID.
Date is being sent to the client in this format: 2012-07-19T14:30:00-03:00.
I'm using angular filter to convert it to local time.
I have a few questions about it ...
1º Server TimeZone?
About my server (single server) ... should it be running with a "neutral" UTC (+00:00)? And what if, in the future, we move to a farm where servers run on different locations?
2º What should I store?
Currently, I'm storing just date as DateTimeOffset. I'm reading about saving the TimeZoneID but I'm seeing no use at all for this. Am I missing something?
Or should I store date as DateTimeUtc with a TimeZoneID and manually convert every date with the TimeZone class?
3º How to convert to local time?
Is it safe to convert data on the client? Or date conversions should be always on the server side?
4º About DST.
Using my current approach. Will DST be respected?
One very important thing to understand about date/time is that there is no one right way for doing everything. The common answer "use UTC" is not always applicable. Context is very important, and there are different techniques and approaches based on what the values you are working with are representing. If you could elaborate on what they are used for in your application, I will update my answer accordingly. In the meantime, I'll try to address the specific points you have brought up already:
#1 - Server Time Zone
Keeping your server at UTC is a best practice, and it is what you can expect from cloud providers like Azure or AWS also. But it isn't something that you should be dependent on. Your server should be able to be set to any time zone without it affecting your application. As long as the clock is in sync with an NTP server, choice of time zone should not matter.
So how do you ensure that? Simple, just make sure your application avoids all of the following:
DateTime.Now
DateTimeKind.Local
TimeZone (the entire class)
TimeZoneInfo.Local
DateTime.ToLocalTime()
DateTime.ToUniversalTime() (because it assumes the input is local)
Misc. other methods that assume a local input or output, such as TimeZoneInfo.ConvertTimeToUtc(DateTime) (this particular overload doesn't take a time zone, so it assumes the local time zone)
See also my blog post: The Case Against DateTime.Now.
Note that I didn't include DateTimeOffset.Now in the list. Although it's a little bit of a design smell, it is still "safe" to use.
#2 - What to store
I suggest you read my answer to DateTime vs DateTimeOffset. It should clarify some things. Without regurgitating the whole thing, the main point is that while both represent a point in time accurately, a DateTimeOffset provides perspective, while a UTC DateTime does not.
You also asked when you should store a TimeZoneInfo.Id. There are at least two scenarios where this is required:
If you are recording events in the past or present, and you plan on allowing modifications to the recorded timestamps. You need the time zone to determine what the new offset should be, or how the new input converts back to UTC.
If you are scheduling time out into the future, you will need the time zone as part of the recurrence pattern (even for a single occurrence). See here and here also, (while for other languages, the same principles apply).
Again, the exact answer depends on what exactly the timestamps represent. There is no one ring to rule them all.
#3 - Client Safety
If it's a .NET client, sure you can convert there. But I think you are asking about a JavaScript client browser.
"Safe" is a relative term. If you're asking for exact perfectness, then no. JavaScript isn't safe for that, due to an error in the ECMAScript specification (ES1 through ES5.1. It is being worked on for ES6). You can read more in my blog post: JavaScript Date type is horribly broken.
However, if you are working with relatively current data, and the users of your application are not in a part of the world where time zones are volatile, or you don't require precise results 100% of the time, then you can "safely" use JavaScript to convert to the user's local time zone.
You might avoid some of these issues with libraries that implement the IANA TZDB in JavaScript, such as the ones I list here. But many of them are still dependent on JS Date, so they still have issues. (Side note - I'm working on a JS library that will counter this, but it is not ready to share yet).
Conversions on the server side are a much better choice, as long as you can ask the user for their time zone. Most of the time, I think this is doable.
You might consider asking using a map-based timezone picker, such as this one or this one. Both of which will require you use IANA time zones, which for .NET means using Noda Time, which is a great idea anyway (IMHO).
#4 - Daylight Saving Time
With your current approach, DST will be respected within the definition of the current DST rules for the time zone the user has set for their local browser. (Again, refer to my blog post for why this is the case).
A conversion from any value with an offset (whether -03:00 or Z) that passes through the Date object (which I believe an Angular filter will do), will properly convert to the specific unix timestamp.
The errors that would crop up with DST conversions for prior DST rules are because going from the unix timestamp inside the Date object to the local time zone will always assume that the current DST rule is applicable, even if the time fell into a period that had a different rule.
This actually depends on the actual application you're writing, but the most simple/robust approach IMO is to store/compute all your dates using UTC, and convert it back to the local time zone when you display it to the user.
If I use DateTime.Now as part of software licensing authentication to enforce the number of days software can be used, can this be circumvented by simply changing the system clock?
If so is there a better way to get real UTC time?
If I use DateTime.Now as part of software licensing authentication to
enforce the number of days software can be used, can this be
circumvented by simply changing the system clock?
DateTime.Now uses the system clock, so yes it could be circumvented.
If so is there a better way to get accurate system time?
Yes, you could query a time server over the www. But you know, even this could be circumvented because the user can modify his hosts file and replace the address you are using with his own proxy and return whatever time he likes. So it will all depend on how far do you want to get into protecting your software. If you really care about the intellectual property of your software you are better of purchasing a commercial licensing software.
Everytime i have used this method for testing it has affected this, so the answer is yes it does affect it
Yes of course, the DateTime.Now obtains its value from the system clock.
A better way is to use a NTP server on Internet.
In this article on codeproject you could find code that allows a client to connect to a NTP server
This question may be easy and the answer obvious, but I can't seem to be able to find a solution right now.
I built an application which has a big flaw in it. In a property of my User class, I check to see if the user subscription is expired. To do this, I compare the ending date of the subscription with DateTime.Now:
return (DateTime.Compare(DateTime.Now, subEndDate) > 0);
It doesn't take a genius user to realize that all it is needed is to change the Windows date to an earlier one, and then the application won't expire at all. So I think that comparing to DateTime.Now should not be done, is there a better method that I could use in order to validate a subscription date?
Thanks.
Regards,
Call a webservice or check a database to determine if the subscription is still active
Does this actually matter? If your product is purely web based the only time you have to worry about is your server time. If the server time is able to be altered without your consent you probably have larger problems to worry about.
If your product is desktop based, then how much protection do you want build in? If you just want to protect against your casual user the solution you have is probably enough. If someone is determined to pirate your software then they will probably be successful. If you want to make it harder for these users one solution would be to keep a log of all the times the application has been run. This way you can get an idea of they are playing with the clock.
Maybe you could extract the subscription expiration logic out of your client program and put it into an external service, then your client app could connect to a different server and retrieve expiration details based on a user parameter passed in?
There are several NTP servers out there which you can use for free... they return the exact time and your casual user won't have a hand in manipulating those... to access them you have several options - though none built-in:
http://dotnet-snippets.com/dns/simple-network-time-ntp-protocol-client-SID571.aspx
http://www.codeproject.com/KB/IP/ntpclient.aspx
http://www.codeproject.com/KB/datetime/SNTPClient.aspx
http://www.rebex.net/time.net/ (commercial)
I'm developing an application and I need to make a demo version of it that will expire in lets say 30 days.
My idea for now is to store the current time when the application is first started in a simple txt file stored in the projects resource (so it doesen't have to be written on the hard disk or the registry), and every time the program is started check if 30 days have passed.
But, what if the user resets the time to an earlyer state?
Then my app would still start becouse now the "current date" can be 1 day after the "first start"..
Is there any way I can get some info along with the first date (or, insted of) that would assure that specific time that the application is first started?
Thank you for your time.
One of the option is to check the date time from some external server and not from local system. But this is also possible to crack as the user can put a proxy in between which will act as the external server to your app and this proxy can send any time the user want. In case you want the solution for novice users, external server approach is fine, but any smart user can still crack the application. Remember, any code that runs on a client machine can be cracked, you just need to flip the correct bit in the application code :)
I have a simple check in the code of one of my programs when in beta. It pretty much does what you say. In the initial code is a hard coded date. The logic then just tests to see if the current date is earlier than the hard coded date. Pretty primitive and it relies on the users system date. However once it is past the program will not run unless the system date is changed. As I mention I use this for betas not for my production programs that have an evaluation period. For that I use Infralution License Tracker. This is payware but it does allow the setting of evaluation periods and also the actual licensing of the code.
Interesting question - how about encoding the initial datetime somehow - base64 or even encryption of somekind), then also storing the datetime each time your application is run.
That way you can detect inconsistencies by checking each datetime and if there's funny business going on (eg. todays date is older than the last date) you can shut the user out.