Is there any way to add one millisecond in to current time in objective c . I will fetch the timestamp from server and want to show with millisecond repeatedly ( I dont want to use the system time) .Any help is appreciated .
Thanks in advance .
Read the timestamp into an NSDate. Than use
+ (id)dateWithTimeInterval:(NSTimeInterval)seconds sinceDate:(NSDate *)date
Should work.
You need to use an object of the NSTimer class.
Some sample code:
-(void)startTimer {
theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/1000.0 target:self selector:#selector(updateTimer) userInfo:nil repeats:YES];
//the method updateTimer will be called once every millisecond
}
-(void)updateTimer {
//add one millisecond to the global time variable and display it in a label
}
-(void)stopTimer {
[theTimer invalidate]; //pauses the timer
}
Edit
For using a global Time variable, NSDate is probably the right class.
You can init the object using a time interval, for eg. 600 seconds before now:
NSDate *globalDateTime = [[NSDate alloc] initWithTimeIntervalSinceNow:-600];
To add 1 millisecond to the time:
globalDateTime = [globalDateTime dateByAddingTimeInterval:1.0/1000.0];
And to populate your global time variable in a string:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss"]; // use yyyy-MM-dd if you need to show the year, month or day
NSString *dateTimeString = [dateFormatter stringFromDate:globalDateTime];
The NSTimeInterval class "yields sub-millisecond precision over a range of 10,000 years."
Refer to apple's documentation on NSDate for more details:
Related
I have the following (terible) method that constantly checks the current time, and when a certain time is reached (in this case midnight) an NSLog statement is run once to signify something useful being done:
- (void) checkTime {
while (true){
NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:#"HH:mm"];
NSString *nowDateString = [outputFormatter stringFromDate:now];
if([nowDateString isEqualToString:#"00:00"]){
NSLog(#"Store previous days data..");
BOOL stillMidnight = YES;
while(stillMidnight == YES){
NSDate *latestNow = [[NSDate alloc] init];
NSDateFormatter *latestOutputFormatter = [[NSDateFormatter alloc] init];
[latestOutputFormatter setDateFormat:#"HH:mm"];
NSString *latestString = [latestOutputFormatter stringFromDate:latestNow];
//Check if it is still midnight
if([latestString isEqualToString:#"00:01"]){
//leave while
stillMidnight = NO;
}
}
NSLog(#"No longer midnight");
}
[loopPool drain];
}
}
The above method gets called as follows from the applicationDidFinishLaunchingWithOption method:
[self performSelectorInBackground:#selector(checkTime) withObject:nil];
This code runs the NSLog(#"Store previous days data..") once at midnight, which is what I need, but is there a more elegant solution to this problem?
Thanks,
Jack
You'd be better off:
getting the current date;
working out when midnight was today;
scheduling a one-shot timer to occur one day after that; and
repeating
It's tempting to just schedule a repeating timer that first fires with the date calculated at (3) and every 24 hours hence, but that would fail to allow for daylight savings. So, e.g. (coded directly in here, untested)
- (void)scheduleNextTimedAction
{
// get the date now and the calendar the user is using
// (which will include their time zone, helpfully)
NSDate *dateNow = [NSDate date];
NSCalendar *relevantCalendar = [NSCalendar currentCalendar];
// decompose the current date to components; we'll
// just ask for month, day and year here for brevity;
// check out the other calendar units to decide whether
// that's something you consider acceptable
NSDateComponents *componentsForNow =
[relevantCalendar components:
NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:dateNow];
// we could explicitly set the time to midnight now,
// but since that's 00:00 it'll already be the value
// in the date components per the standard Cocoa object
// creation components, so...
// get the midnight that last occurred
NSDate *lastMidnight = [relevantCalendar dateFromComponents:componentsForNow];
// can we just add 24 hours to that? No, because of DST. So...
// create components that specify '1 day', however long that may be
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
oneDay.day = 1;
// hence ask the calendar what the next midnight will be
NSDate *nextMidnight = [relevantCalendar
dateByAddingComponents:oneDay
toDate:lastMidnight
options:0];
[oneDay release];
// now create a timer to fire at the next midnight, to call
// our periodic function. NB: there's no convenience factory
// method that takes an NSDate, so we'll have to alloc/init
NSTimer *timer = [[NSTimer alloc]
initWithFireDate:nextMidnight
interval:0.0 // we're not going to repeat, so...
target:self
selector:#selector(doTimedAction:)
userInfo:nil
repeats:NO];
// schedule the timer on the current run loop
[[NSRunLoop currentRunLoop]
addTimer:timer
forMode: NSDefaultRunLoopMode];
// timer is retained by the run loop, so we can forget about it
[timer release];
}
- (void)doTimedAction:(NSTimer *)timer
{
NSLog(#"do action");
[self scheduleNextTimedAction];
}
If you want to execute code at an arbitrary point in time, you best set up Local Notifications.
You can use either an UILocalNotification if the timer should also alert the user when your app is not running Push notification guide or NSTimer, which can be initialized with firing date or interval as well as selector to be called. Note that NSTimer will not fire if your app is in the background but in this case rather will fire the moment your app gets active again.
I need to display the exact local time and the time should be running.
Please help, if possible with sample code or explanation.
Thanks.
This returns the current date with Time
[NSDate date];
Now you can use NStimer to fetch the time every one second and display it.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(displayTime) userInfo:nil repeats:NO];
//Time Interval is one second
-(void) displayTime
{
NSDate *currentDate = [NSDate date];
NSDateFormatter *timeFormatter = [[[NSDateFormatter alloc]init]autorelease];
timeFormatter.dateFormat = #"HH:mm:ss a";
NSString *dateString = [timeFormatter stringFromDate: currentDate];
yourlabel.text = dateString;
[timeFormatter release]
}
anyone know or can provide some example code relating to "timeIntervalSinceNow" method...
I need something like... time2(when app eneters foreground) - time1(when app enters background) = time3(the difference in times)... this is so i can use this number(pref in seconds) to calculate the time i have lost while the app has been in background !!
I am having trying trying to create the date objects, receive the object and display/use in a label....
Actually, to answer your original question, myles, you can use timeIntervalSinceNow.
In the statement below, inputDate has been initialized as an NSDate and set to some date (you could just try [NSDate *inputDate = [NSDate date]; to set the date at the current date and time.
NSTimeInterval timeToAlert =[inputDate timeIntervalSinceNow];
The next line is a way to put that NSTimeInterval into a string.
NSMutableString *timeinterval = [NSMutableString string];
[timeinterval appendFormat:#"%f",timeToAlert];
Finally, the app delegate class is typically where code can be written to handle coming in and out of background. Good luck!
timeIntervalSinceNow tells you the offset of an NSDate from the current time. You want timeIntervalSinceDate::
NSDate *appEnteredForeground = ...;
NSDate *appEnteredBackground = ...;
NSTimeInterval difference = [appEnteredBackground timeIntervalSinceDate: appEnteredForeground];
You can calculate the difference between two dates with the timeIntervalSinceDate: method:
//When app enters background:
self.backgroundDate = [NSDate date]; //this should be a property
//...
//When the app comes back to the foreground:
NSTimeInterval timeSpentInBackground = [[NSDate date] timeIntervalSinceDate:self.backgroundDate];
NSTimeInterval is simply a typedef for double, it's measured in seconds. [NSDate date] instantiates an NSDate object with the current date and time.
I have an app that uses a stopwatch-style count up from 0 in HH:mm:ss format. The code looks pretty straightforward to me, and I can't think of a more efficient way to run it.
For some reason, when I run it, there is a very noticeable and consistent (every time I run it, in the same place) lag when the timer gets to 00:00:02. It stays on 00:00:02 for a full second, and then counts on normally. Why would this happen?
-(IBAction)startAndStop;
{
if (!timer) {
NSLog(#"Pressing Start Button");
[startAndStopButton setTitle:#"Stop" forState:0];
startDate = [[NSDate date] retain];
timerLabel.text = #"00:00:00";
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(timerStart)
userInfo:nil
repeats:YES];
} else {
NSLog(#"Pressing Stop Button");
[startAndStopButton setTitle:#"Start" forState:0];
[startDate release];
[timer invalidate];
timer = nil;
[timer release];
}
}
-(void)timerStart
{
NSDate *currentDate = [NSDate date];
NSTimeInterval countInSeconds = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSinceReferenceDate:countInSeconds];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm:ss"];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [df stringFromDate:timerDate];
[df release];
timerLabel.text = timeString;
}
NSTimer does not fire at exact times or time intervals (check the specification for the likely error). Thus it is possible for one late firing and one early firing to occur during the same clock second, when rounded to the nearest second, and you will see a stutter effect.
Instead, use a much faster timer (or CADisplaylink), say at 30 Hz, check the time, and update the label only if the time has changed enough to change the label (one second).
The interval you are passing is in seconds:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html
My guess is that it is getting called immediately, and then every 1 second afterwards, since you are passing 1 second as the timer interval. Try passing something like 1.0/20.0 to update at a higher frame rate.
I have implemented a simple clock like so:
- (void)runTimer {
timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(showActivity)
userInfo:nil
repeats:YES];
}
- (void)showActivity {
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
NSDate *date = [NSDate date];
[df setDateFormat:#"HH:mm"];
[clock setFont:digitalFont];
[clock setText:[df stringFromDate:date]];
}
It's basiclly just a task that is run every second to update the time in a UILabel. Now what if I would like to extend this clock to react on certain times, just like a alarm clock.
Continously checking the value of NSDate seems battery intensive. How would I do this?
The simplest way to achieve this? Just have another NSTimer that is set to fire at the time of the alarm.
NSTimer* myTimer = [[NSTimer alloc] initWithFireDate:(NSDate *)date
interval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats];
You can use initWithFireDate method