UnixTimestamps always off in ios - ios

I've tried countless ways of getting the current timestamp and no matter what I do the timestamp is always off.
What is the proper way to get the right timestamp
NSLog(#"%#",NSTimeIntervalSince1970);
Was the closest one however, it's still not right. Any suggestions?

NSTimeIntervalSince1970 is a #define and gives you the number of seconds between 1970 & 1/1/2001. i.e. it'll always be the same. you want to do something like [[NSDate date] timeIntervalSince1970];

Related

Response Time in Robot Framework

Is there any way to know the time taken for each action to finish in Robot Framework???
Like For example, I want to rotate screen 90 degrees 10 times, how to time it or how to average the time taken by these actions??
The simplest solution is to get the current time, run your keyword or keywords, then get the current time again, Then, subtract the starting time from the ending time.
Robot framework provides a DateTime module that has functions to support this. For example, Get current date can return the current date and time. Subtract date from date can return a timedelta which can be formatted to days, hours, minutes, seconds, and milliseconds.
You can see it in your report.
http://robotframework.org/QuickStartGuide/report.html
Elapsed Time: 00:00:00.284
It is also available at Keyword Level in the Test Execution Log.
${date1} = Get Current Date
TestCase_To_Rotate_Screen_10_Times
${date2} = Get Current Date
${actiontime} = Subtract Date From Date ${date2} ${date1}

How to correctly format a NSTimeInterval as a time period, respecting i18n?

Given an NSTimeInterval representing a period of time, how do I create a human-readable string that expresses that time period in a way that respects i18N?
For example, if the NSTimeInterval is equal to 10823.23435 seconds, then some reasonable ways of rendering that as a string for those in the US might be:
3:23
3 hours, 23 seconds
etc.
(I.e., stuff you'd see on a stopwatch.)
Presumably other locales might use different renderings.
I'm aware of NSDateFormatter and NSNumberFormatter, but it's not clear to me if or how to use one of these for this problem.
I'm also aware of FormatterKit, but that only does relative time periods (e.g., "3 minutes ago"). I'm looking for absolute time periods.
It is trivial to cook up my own locale-specific solution, but has this problem been solved properly already?
Thanks.
For iOS 8 there are NSDateComponentsFormatter & NSDateIntervalFormatter, they may work for your application.
Docs are lacking see NSHipster: NSFormatter
and
Foundation/NSDateIntervalFormatter.h

Is current time persisted across all iPhones?

I just have a quick question about how date and time works in iOS and Objective-C. If I make a call like NSDate *today = [NSDate date] on two separate devices, will they both return the exact same time? I am trying to have multiple phones sync up using the current time and I just want to make sure that they will have the same current time (if it's a matter of milliseconds I'm not worried but more than a second off will probably not work).
Thanks in advance!
Since NSDate stores a time internally as an NSTimeInterval, which is a typedef for double. It has in the sub-microsecond resolution for times within a decade or more of the date of this question.
This means that even if your two devices have closely synchronized clocks, you are unlikely to get exactly the same NSDate by calling [NSDate date] on both devices.
You can check whether two dates are within a second of each other like this:
NSTimeInterval diff = date0.timeIntervalSinceReferenceDate - date1.timeIntervalSinceReferenceDate;
if (fabs(diff) < 1) {
// dates less than one second apart
}

iOS Development - Check Internet Time

I am developing an app that has refills lives every 5 minutes. What is the best way to check the time since the last refill so that the user cannot trick the system by changing the time on their device?
For an example, look at Candy Crush. Changing the system time on there gives you extra lives, and this is what I need preventing.
How about running an [NSTimer scheduledTimerWithTimeInterval:300.0
target:self
selector:#selector(giveLife:)
userInfo:nil
repeats:YES];
That should execute giveLife every 5 minutes and there you can give the extra life.
As far as I can tell, NSTimer will not be affected by changing the clock time once it has started.
I would suggest You do something similar as it is in Clumsy ninja.
SHORT
Every time application becomes active [applicationDidBecomeActive:] - You try to get internet time.
If device time timestamp is smaller than stored timestamp - don't allow to continue. (Ask to connect to internet).
Implement a feature to save timestamp of the last regeneration cycle. Thus - even if user succeeds getting faster live refills, Once he reverts back to original time and continues game - it will show that next live refill will be way in the future at the time user was last using application, not 5 minutes. (To punish cheaters) (But maybe set a max limit, if last regenerate time is bigger than 5 minutes from current time, then set it to 1 hour? still a punish, but not so big to lose a player.
LONG
(Based on what I could distinguish)
Every time application becomes active - You try to get internet time. At that point - You don't need to check the time anymore while the app is opened, until the next time application becomes active again.
In clumsy ninja, they allow to use app even if internet is not available. So - if I activate airplane mode (for example), adjust time to be few hours forward, and open application - it sees that internet is not available, and thus cannot compare time. And - the things (punch bag, balls, etc) I had to wait to be repaired - are now repaired. Yay.
But If I do the same thing again many many times and finally I want to set back to original date and time - and open application, it will know that there is something not right. It probably stores some last opened timestamps, and if that time is bigger than actual device time - then user probably is doing something bad. And - alert appears - App must connect to server in order to continue.
Another downfall of moving time forward (for user, but great for developer) is - that there are some things, which will auto-regenerate after a while, but needs to be "picked" in order to initiate regenerating again. In clumsy ninja, chicken generates an egg once in a while. If Egg is not picked up, it still holds a timestamp, when it should be / was generated. So - imagine, user successfully forwards time many times (until it is already 1 day ahead of original time) - and now he wants to set the time back to original time, so that clock would actually show correct time. After user does that - when app is opened, time is synced but the generating egg will now show, that it will be ready after 1 day - last saved timestamp. But this could also be used for all items, which require time to be available. Why the clumsy ninja has not used this thing to all items? Maybe they are afraid, that if user sees, that nothing is available for a long time - user will stop playing. Thus - better have a cheater user, than no user at all.
NSURL *url = [NSURL URLWithString:#"http://www.timeapi.org/utc/now"];
NSString *str = [[NSString alloc] initWithContentsOfURL:url usedEncoding:Nil error:Nil];
str = [str stringByReplacingOccurrencesOfString:#"T" withString:#" "];
str = [str stringByReplacingOccurrencesOfString:#"+01:00" withString:#""];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *date = [dateFormat dateFromString:str];

How do I store the time part of NSDateComponents?

I want to store times type value (but not the date) in Core Data. Which data type should I use?
Possible options:
Three integer attributes for hour, minutes, seconds.
One string attribute for "HH:MM:SS".
One integer attribute for the number of seconds since midnight.
The best representation depends on what type of queries involving the time you want to
execute. The first option is better if you want to search for a given hour, minute or second. The other options are better if you have to search for time intervals.
My approach would probably be to convert it to an HHMMSS format, either as an integer or a string. NSDate isn't appropriate because it is stored as a interval since an epoch (seconds since 1970)
The date portion of an NSDate is inherently part of time. NSDate is a NSTimeInterval number of seconds positive or negative since the reference date. With a locale and a timezone you can get an appropriate localized display string on the fly.
In most cases it makes far more sense to store the number behind the NSDate returned by timeIntervalSinceReferenceDate
It's small and portable and correct.
Then recreate an NSDate with dateWithTimeIntervalSinceReferenceDate:
Then use an NSDateFormatter with NSLocale and NSTimeZone to get an appropriate value for display to users.
It's an unwieldy and cumbersome set of tools that actually help you do it right.
The good news is all the effort you expend in doing this pays off in making it easier next time and giving you code that will do the right thing and have a backing value that is actually really easy to store and manipulate.
Additionally by using the API correctly you will lose no precision and have more possibilities open to you.
Trying to do it with format strings alone seems easy and simple but is the road to bad code.

Resources