Setting UIDateTime Picker time zone - ios

I have rather unusual requirement, but anyway..
#property (weak, nonatomic) IBOutlet UIDatePicker *dateDatePicker;
When I get reading of dateDatePicker.date it returns NSDate set to current system's time zone. But I want it to be in different specific time zone.
So, pretend right now it's 3:50pm Central Time.
dateDatePicker.date returns 3:50pm CST
I want to have something like this:
[dateDatePicker setTimeZone:#"EST"]
NSDate *ESTDate = dateDatePicker.date;
... and then I'd like debugger to show "2:50pm CST" - because 3:50pm in EST IS 2:50CST

This may be simpler that you think. If your date is 3:50pm CST, and you want it to be 2:50pm CST, just subtract an hour:
date = [date dateByAddingTimeInterval:-3600];
Of course, the local time zone might not always be CST, so you can get the difference between the two time zones and use that instead of hard coding -3600:
NSString *targetTimeZoneName = #"US/Eastern";
NSInteger localOffset = [[NSTimeZone localTimeZone] secondsFromGMTForDate:date];
NSInteger targetOffset = [[NSTimeZone timeZoneWithName:targetTimeZoneName] secondsFromGMTForDate:date];
NSInteger timeZoneDelta = localOffset - targetOffset;
date = [date dateByAddingTimeInterval:timeZoneDelta];

UIDatePicker's timeZone property is not a string, as you are using it. You have to pass it an NSTimeZone object.
Also, NSDates do not have a timezone. Its just a moment in history and its string representation depends on the time zone. Use an NSDateFormatter to format the date object for the timezone you want.

Related

iOS: Voice Over doesn't read proper for ".03 hours" text

I have a text in either of below formats:
.03 hours
0.03 - 0.05 hours
In above cases accessibility should read in below format:
dot zero three hours
zero dot zero three (character name) zero dot zero five hours
But in real scenario it is reading like below:
three hours
zero dot zero three zero dot five hours
Like i mentioned above the number format is getting from json response as string type and it might be in any format like 0.03 hours, .03 hours, .03 - .05 hours, 4 - 5 hours
to fix the issue, I have tried many solutions like below but no luck
hoursLabel.accessibilityAttributedLabel = NSAttributedString(string: hoursLabel.text ?? "", attributes: [NSAttributedString.Key.accessibilitySpeechPunctuation: NSNumber(value: true)])
Can any one help me out, how to fix this scenario.
In may case it should work in all other units like .03 (unit)
the number format is getting from json response as string type and it might be in any format like 0.03 hours, .03 hours, .03 - .05 hours, 4 - 5 hours
First of all, you should rearrange the incoming data so as to have the same defined format. Then, you just have to set up this format to be read out as desired by VoiceOver.
Hereunder, an ObjC code snippet from this complete 'date, time and numbers' explanation:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel * hourLabel;
#end
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"0.HH"];
NSDate * date = [dateFormatter dateFromString:#"0.05"];
_hourLabel.text = [NSDateFormatter localizedStringFromDate:date
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterShortStyle];
NSDateComponents * hourComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitHour
fromDate:date];
_hourLabel.accessibilityLabel = [NSDateComponentsFormatter localizedStringFromDateComponents:hourComponents
unitsStyle:NSDateComponentsFormatterUnitsStyleSpellOut];
}
#end
Unless I misunderstood your need, you should reach your purpose using this rationale.

NSTimeIntervalSinceDate gives 86,399 seconds between consecutive days, why?

In iOS, Xcode9, and Obj-C, I am trying to find out how much time has elapsed in days between two dates. I know the NSTimeIntervalSince method yields a result in seconds. But it seems that when I calculate the seconds between consecutive days (like 11-2-2016 and 11-3-2016), I am 1 second short, yielding 86,399. If I calculate seconds between larger intervals, I am always a second short.
11-2-2016 to 11-4-2016: 172,799 (two 24-hour days but missing a second)
11-2-2016 to 11-5-2016: 259,199 (three 24-hour days but missing a second)
Here's my code:
#property (strong, nonatomic) NSDate *firstDate;
#property (strong, nonatomic) NSDate *secondDate;
#synthesize firstDate, secondDate;
int secondsIntervalFirstDatetoSecondDate = (fabs([firstDate timeIntervalSinceDate:secondDate]));
NSLog(#"seconds between firstDate and secondDate %i", secondsIntervalFirstDatetoSecondDate);
firstDate and secodDate are NSDate
They are entered by the user using a datePicker and date formatting is set as
[formatter setDateFormat:#"MM-dd-yyyy"];
I've searched for an answer but could find none.
First post for a newbie, sorry for any etiquette errors, I'll try to improve.
When you create a UIDatePicker and put it in "date" mode, the time is the time the date picker was created. If you're creating two pickers, they're going to be created at slightly different times. Even a very small difference in those times can lead to a 1-second difference.
You should never compute time-differences this way. There are not 86,400 seconds in a day. "How many days are between two points in time" is complicated, and you should use the tools designed for it: NSDateComponents and NSCalendar.
NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSInteger diffInDays = [[calendar components:NSCalendarUnitDay
fromDate:[calendar startOfDayForDate:date1]
toDate:[calendar startOfDayForDate:date2]
options:0] day];

How to get the exact time of specific timzone

i am doing one application.In that i have to show the time for how much time user is in the application.For that,i calculated the difference between application opened time and current time for every one second and showing.But if i try to change the device time,that result also changing.But i want to show the exact result if user change the time also.So how to get the exact correct time based on that timezone.
You can set a default time zone to GMT for your application in initialize method.
#interface AppDelegate ()
#property (nonatomic, strong) NSDate startDate;
#end
#implementation AppDelegate
+ (void)initialize
{
[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
self.startDate = [NSDate date];
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"User has stayed for %4.2f seconds.", [[NSDate date] timeIntervalSinceDate:self.startDate]);
}
In addition to that, don't forget to set time zone for your NSDateFormatter instances when you convert a string representation of a date into actual NSDate instance.

NSDates and TimeIntervals

I'm struggling to understand how to use NSDates properly.
I have an event that instantiates a timingDate = [NSDate date];
I then later on what to record the time intervals betweeen user's touches.
So I want to find the interval between the timingDate and the user touch in milliseconds.
Then I want to reset the timingDate to be equal to the touchTime so that the next time the screen is touched I can find the differnce between the previous touch and the present touch. I hope that makes sense. But I am going around in circles because I don't understand how to use NSDates or NSIntervals. The properties interval touchTime and timingDate are all currently NSDate types - Is this right?
So I've tried a lot of different things like
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
touchTime = timingDate;
interval = [[NSDate date] timeIntervalSinceDate:timingDate]; // should be the time difference from when the timingDate was first set and when the user touched the screen.
touchTime = [[[NSDate date]timeIntervalSinceDate:timingDate]doubleValue];
timingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:touchTime];
NSLog(#"Time taken Later: %f", [[NSDate date]timeIntervalSinceDate:timingDate]);
}
Your code is a bit complex! You just need to calculate the difference between timingDate and the time that the touch occurred, and then set timingDate to the current time so that you can perform this calculation on every touch event.
To find the difference between timingDate and the first touch, you can use NSDate's timeIntervalSinceDate with the current time. This will return an NSTimeInterval value, which represents a time value in seconds with sub-millisecond precision. Here's an example:
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:timingDate];
NSLog(#"Time taken: %f seconds / %f milliseconds",timeInterval,timeInterval*1000);
Then, in order to set your timingDate to the current time, simply use timingDate = currentDate;. This will allow you to continuously measure the time difference between touches.
NSTimeInterval is a double which represents seconds.
NSDate is an object that holds the date/time.
Here is an example:
#property(nonatomic, strong) NSDate * lastTouchDate;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSTimeInterval secondsSinceLastTouch = 0;
if(self.lastTouchDate){
secondsSinceLastTouch = [[NSDate date] timeIntervalSinceDate:self.lastTouchDate];
NSLog(#"It's been %.1f seconds since the user touched the screen", secondsSinceLastTouch);
}else{
NSLog(#"This is the first time the user touched the screen");
}
self.lastTouchDate = [NSDate date];
}
If you don't want the interval between the last time you touched it, do not update the self.lastTouchDate after initialization and it will be seconds since the date was initialized.
So, the first thing that you need to understand is that -[NSDate timeIntervalSinceDate:] returns an NSTimeInterval, which is really just a double value.
In your example above, you haven't declared your variables with types, but if you look at the value your variable interval it should be a decimal value of seconds since the time represented by timingDate.
Assuming that timingDate is an NSDate object, and it is set before this code is run, this code should print the time (seconds) to the debug console.
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:timingDate];
NSLog(#"Time between touches %f", interval);
Here is the NSDate class documentation, in case you were having trouble finding it.
( https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/index.html#//apple_ref/doc/c_ref/NSDate )

Can I make a button do an NSDate comparison in iOS?

Is it possible to have an action from a button a) do an NSDate store when tapped, and then b) for that method to do a date comparison with an if statement?
So, for instance, if the stored NSDate was less than 12 hours ago, the user could not press the button again?
Haven't come across a tip on this from my research.
Sure. You can get current date by code
[NSDate date]
Then save him into NSUserDefaults
And check a current date with saved date on button press.
How
if ( [[NSDate date] timeIntervalSinceDate: savedDate] >= 12*60*60) // 12 hours
{
// do your steps
}

Resources