- Home /
How to compare two dates?
I am trying to create a future timestamp, store it as a string, and then compare it against the current System time & date. E.g.:
var period = 10; // In minutes
var timeStamp = currentTime + period;
PlayerPrefs.SetInt ( "timeStamp", timeStamp )
if ( currentTime >= timeStamp )
etc.
But the problem is time isn't metric, so how do I do this? Converting it into and out of a standard date format would require a lot of code and seems laborious. Is there a simple approach?
// Clarification edit: Basically, what I want is the farmville-style system. Where a player does an action, then it gives a countdown to when the action will complete.
Answer by zeh · Feb 25, 2013 at 08:47 PM
This is probably one of those instances where it would make more sense for you to tell us what you're trying to accomplish, so people can come up with common solutions, rather than ask an open-ended question.
To more or less answer the question, though, in general, you compare two dates by doing a subtraction of the `Ticks` of two DateTime
objects. This gives you the number of ticks in between those dates, and therefore, the amount of time (a tick is the same as 10,000 miliseconds). DateTime
also has a `subtract` method but I'd guess it's not as useful as direct manipulation of the Ticks value (or just plain harder/longer to use).
For your use, you would probably read the current time (`DateTime.now`), determine which future date you want, and store that. In C#, I believe it would be something like:
long period = 10L * 60L * 1000L * 10000L; // In ticks
long timeStamp = System.DateTime.Now.Ticks + period;
PlayerPrefs.SetLong("timeStamp", timeStamp);
// Later that day (after re-reading timestamp)...
if (System.DateTime.Now.Ticks >= timeStamp) {
// Trigger something
}
Never store dates as strings. It's usually as the object's native value (when possible in some serialization solutions), or instead its numeric primitive (long Ticks in C#, long milliseconds in Java and other languages, etc).
It may sound kind of laborious but if you just start using the primitive/long for everything, it's actually easier to deal with that in the long run. Remember human-readable DateTime
and similar objects are just abstractions of a number; conversions or deconverstions are only needed when creating new instances from the current time or when displaying them I'd say. For everything else, composing with the long number is simpler/quicker.
Edit: for determining whether some action has been completed over time, I'd store the date the task has started, and the time required to complete the task. Then your script would loop through the list of queued tasks, checking which ones have been completed (start + duration < current time). Storing just the "end" date/time also works, but I guess I prefer the first approach because that way if a task has a variable required time you can change the required time rather than trying to manipulate the target/completion time (it's also easier to count task completion %).
That kind of solution is prone to exploitation since all the data and logic would seem to be on the client side. If this is for a multiplayer game (for more roubusts Farmville/social limitation games), you'd need a slightly similar approach, but all controlled by a backend with nothing stored on the client side.
You're right, I should clarify what I'm trying to do…
Basically, what I want is the farmville-style system. Where a player does an action, then it displays a countdown to when the action will complete.
It seems ticks could be my solution. Thanks!
Okay I looked at this more and immediately my first issue is that I can't seem to convert ticks into anything usable. It's way too long of a number for me to parse into an integer or anything. There's no such thing as "PlayerPrefs.SetLong" either.
Yeah, my mistake - I just assumed that `PlayerPrefs` had a setLong()
method, which would be expected. But it doesn't - I'd say it's a huge oversight on that class. The workaround solution - which is somewhat convoluted but goes back to your original plan - is to either store longs as base64-encoded strings(!), or binary representation of dates; coincidentally, this question and answer seems to have a good example of that approach.
Co$$anonymous$$g to think of it, PlayerPrefs
doesn't seem to support booleans or doubles either. Personally, it looks like a nearly useless class for real use. There may be better alternatives out there.
Thanks for the link — really helpful! I think I've got it now. Converting the date object to Binary then storing that as a String, then converting back.
Also helpful was the discovery of the .Add$$anonymous$$inutes() function, which is a part of DateTime. That way I don't have to worry about how to add $$anonymous$$utes / hours / seconds into the timestamp, it just does it all automagically! :)