NSDate on iOS Issues - ios

I absolutely hate NSDate. Just when I think I have my head wrapped around it, DST either starts or ends, and wrecks everything I am working on.
I am parsing an XML file which in the pubDate has:
Fri, 1 Aug 2014 20:15:00 -0500
The event occurs at 8:15 PM in the Central time zone. This would normally be -0600, but due to taking place during DST, it becomes -0500.
Anyways, since this is just a string of text in the XML, I use NSDateFormatter to format it to an NSDate, and then store it as a property of a class I created:
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *dateofarticle = [dateFormatter stringFromDate:articleDate];
NSDate *date = [dateFormatter dateFromString:dateofarticle];
I have this date appear in the detailTextLabel of a TableView cell, and it shows perfectly as 8:15 PM using:
NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init];
[formatter3 setTimeStyle:NSDateFormatterShortStyle];
[formatter3 setDateStyle:NSDateFormatterShortStyle];
NSString *detailstext = [formatter3 stringFromDate:entry.articleDate];
cell.detailLabel.text = [NSString stringWithFormat:#"%# - Tap for more details.", detailstext];
So far, all is well. I have the time of 8:15 PM from the XML, and it shows 8:15 PM in the TableView. It is when setting a reminder that things get screwy.
I make the property self.theDate in my reminder class equal the same articleDate I have saved from the first part of all this, and then run this code:
NSDate *newDate = [self.thedate dateByAddingTimeInterval:-60*15];
NSDateFormatter *formatter3 = [[NSDateFormatter alloc] init];
[formatter3 setTimeStyle:NSDateFormatterShortStyle];
[formatter3 setDateStyle:NSDateFormatterShortStyle];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.timeZone = nil;
notification.fireDate = newDate;
From all this, I would expect it to fire at 8:00 PM on August 1st, but when I schedule notification and then change the time on my phone to this date, it fires one hour too late, at 9:00 PM.
Any thoughts?

Related

How to subtract time from NSDate with the help of NSDateFormatter?

I'm working on an application in which user set a time to do a task and before 10 or 15 minutes application triggers an alarm. Just like a reminder app you can say.
After searching a lot on stackOverFlow and other different links my problem still exists. Here is what I'm doing:
-(void)timeWasSelected:(NSDate *)selectedTime element:(id)element {
if((UITextField *)element == self.timeForTask){
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
self.textField.text = [dateFormatter stringFromDate:selectedTime];
[defaults setObject:self.textField.text forKey:#"taskTime"];
myTime = [selectedTime dateByAddingTimeInterval:-600];
NSLog(#"New Time %#",myTime);
}
After doing this the NSLog part gives this output: New Time 2015-04-27 06:14:14 +0000
The problem is that I've selected time 11:22AM and it is storing 06:14 and I've only deducted 10min from the selected time.
Try this you will get output:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSDate* selectedTime = [dateFormatter dateFromString:#"11:22 AM"];
NSDate* myTime = [selectedTime dateByAddingTimeInterval:-60*10];//10 minute deduction
NSString* updateTime = [dateFormatter stringFromDate:myTime];
NSLog(#"New Time %#",updateTime);
Output :
New Time 11:12 AM
Here you are subtracting 10 Minutes from selected time. if you want 15 Minutes then replace with 10 digits.
Hope this help you.
Try this, may help you,
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
NSLog(#"1New Time %#",[dateFormatter stringFromDate:selectedTime]);
self.textField.text = [dateFormatter stringFromDate:selectedTime];
[defaults setObject:self.textField.text forKey:#"taskTime"];
NSTimeZone *destinationTimeZone = [NSTimeZone systemTimeZone];
[dateFormatter setTimeZone:destinationTimeZone];
NSDate *myTime = [selectedTime dateByAddingTimeInterval:-600];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setTimeZone:destinationTimeZone];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd hh:mm:ss ZZ"];
NSLog(#"2New Time %#",[dateFormatter1 stringFromDate:myTime]);
Enjoy Coding !!
// gives new date object with time 15 minutes earlier
NSDate *newDate = [oldDate dateByAddingTimeInterval:-60*15];
NSString* NewTime = [dateFormatter stringFromDate:newDate];
NSLog(#"New Time %#",newDate);
This code will exactly get you 15 minutes earlier time

iOS: What should I use EST or EDT and why?

I asked a question not too long ago about timezone and I was using EST. Users suggested me to use EDT. I want to know why I should use one or the other because they both print the same time for me. Here is the code to better illustrate what I mean.
NSDate *today = [NSDate date];
NSDateFormatter *edtDf = [[NSDateFormatter alloc] init];
[edtDf setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EDT"]];
[edtDf setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *stringDate = [edtDf stringFromDate:today];
NSLog(#"The EDT is %#", stringDate);
NSDate *today1 = [NSDate date];
NSDateFormatter *estDf = [[NSDateFormatter alloc] init];
[estDf setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EST"]];
[estDf setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *stringDate1 = [estDf stringFromDate:today1];
NSLog(#"The EST is %#", stringDate1);
They may print different things depending on the time of year (since time of year determines whether Daylight Saving Time is active).
Don't use EST or EDT. Use US/Eastern or America/New_York:
NSTimeZone *tz = [NSTimeZone timeZoneWithName:#"US/Eastern"];
// or
NSTimeZone *tz = [NSTimeZone timeZoneWithName:#"America/New_York"];
These time zones adjust for Daylight Saving Time at the correct times of the year.

Creating absolute time from NSDate

It looks easy, but I couldn't figure out a proper way to do this. I need to create an NSString from a NSDate which represents the same time on every device, independently from the iPhone's time zone settings.
Suppose userA is in London, where the actual time is 14:00, userB is in New York where is 9:00 and userC is in Hong Kong, where the actual time is 21:00.
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yy HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:now];
Actually with this code I'm getting these results (when I log the dateString):
userA: 08/12/14 14:00:00
userB: 08/12/14 09:00:00
userC: 08/12/14 21:00:00
But I need to create dates like this
userA: 08/12/14 14:00:00
userB: 08/12/14 14:00:00
userC: 08/12/14 14:00:00
My goal is to create a "system/absolute time" which is the same inside the app and doesn't matter the original time zone of the user's device. The end result must look like this MM/dd/yy HH:mm:s.
Is it possible to get the NSDate *now = [[NSDate alloc] init]; from a pre-defined timezone? For example it could always use the actual time of the GMT-00 timezone.
I've tried to do it with this code, but when I run the code, the console writes out the wrong date (based on the device time zone setting) again, so I don't have a better idea. I would appreciate any ideas.
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"Europe/London"];
[dateFormatter setDateFormat:#"MM/dd/yy HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:now];
NSLog(#"the date is %#,", dateString);
The below code should work. What ever the timezone you are in it will always display the time in UTC.
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[[NSTimeZone alloc] initWithName:#"UTC"]];
[dateFormatter setDateFormat:#"MM/dd/yy HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:now];
NSLog(#"%#",dateString);
Between the following two threads, I think you'll find everything you need (and thensome). The first is an extensive example of a problem similar to yours (just remember to look at the code in the answers and not the question), while the second has all the time zone abbreviations that you'll ever need. Gotta love the helpful people on The Stack.
The links again, just in case
objective-c: Conversion between TimeZones
GMT timezone conversion in objective c
NSDate *localDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = #"MM/dd/yy";
NSString *dateString = [dateFormatter stringFromDate: localDate];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc]init];
timeFormatter.dateFormat = #"HH:mm:ss";
NSString *dateString = [timeFormatter stringFromDate: localDate];

Iphone date format

I was trying to format a time from GMT+7 to GMT+3:
I am building an app with a world clock in specific country (the user will be at the GMT+7and I want to represent the GMT+3 time )
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale];
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:118800];
NSLocale *USLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setLocale:USLocale];
NSLog(#"Date for locale %#: %#",
[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:date]);
I looked deep into NSDate class reference but I didn't understand how to make it.
Please if someone can help me I will be grateful.
There is 2 important parameters that works separately: Time and Time Zone.
e.g: Vietnam uses GMT+7
If I know that the time in Vietnam is 9:00 AM, then GMT time is 2:00 AM.
When you get the Date from your device you are getting Time and Time Zone: YYYY-MM-DD HH:MM:SS ±HHMM. Where ±HHMM is a time zone offset in hours and minutes from GMT.
Usually you are only using time. However with NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"GMT"] you can tell the NSDateFormatter that you want the GMT time related to your local Time Zone. So, with:
NSDateFormatter *dt = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"GMT"];
[dt setTimeZone:timeZone];
You can get the GMT date of your local time zone date.
So, If you have GMT+7: 9:00 AM and you want to print out GMT+3: 5:00 AM, you have 3 possibilities:
NSDate *localDate = [NSDate date];
OPTION 1
Add a time interval of -4 hours:
NSTimeInterval secondsInFourHours = -4 * 60 * 60;
NSDate *dateThreeHoursAhead = [localDate dateByAddingTimeInterval:secondsInFourHours];
NSDateFormatter *dt = [[NSDateFormatter alloc] init];
[dt setDateFormat:#"h:mm a"];
NSLog(#"GMT+7(-4) = %#", [dt stringFromDate:dateThreeHoursAhead]);
This is the easiest way to do it. If you are always at GMT+7 and you need GMT+3, this is a time interval of -4 hours.
OPTION 2
Set the time to GMT time zone and then add a +3hours time interval. The easiest way to do it is to add the 3 hours first and then move the time to GMT:
NSTimeInterval secondsInThreeHours = 3 * 60 * 60;
NSDate *dateThreeHoursAhead = [localDate dateByAddingTimeInterval:secondsInThreeHours];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"GMT"];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:#"h:mm a"];
NSString *date = [dateFormatter stringFromDate:dateThreeHoursAhead];
NSLog(#"GMT+3 = %#", date);
OPTION 3
This is the better option. GMT+3 is EAT (East Africa Time) you can set your time zone to EAT with: [NSTimeZone timeZoneWithName:#"EAT"]
NSDateFormatter *dt = [[NSDateFormatter alloc] init];
[dt setDateFormat:#"h:mm a"];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"EAT"];
[dt setTimeZone:timeZone];
NSLog(#"EAT = %#", [dt stringFromDate:localDate]);
Option 3 is always retrieving GMT+3
An example code here.

how to use nsdateformatter to Venezuela

I'm trying to schedule a date on the calendar, which has a start time and an end time, everything works fine if the time zone is in the U.S., and the date the change does not help and I need it to Venezuela what should I do as I place generica, to serve me anywhere no matter the time zone?
here I leave the code as data and bring me as I make the date format.
comes the date in the following format: 12/10/2012 05:00 pm
EKEvent* event = [EKEvent eventWithEventStore:eventStore];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateFormat:#"dd/MM/yyyy hh:mm:ss a"];
horafin = [dateFormatter dateFromString:inicio];
horafin = [horafin dateByAddingTimeInterval:3600];
horainicio = [dateFormatter dateFromString:inicio];
[dateFormatter release];
NSString *ti=[[NSString alloc]initWithString:title];
NSLog(#"");
event.title =#"juego";
event.startDate = horainicio;
event.endDate = horafin;
event.URL = [NSURL URLWithString:#"http://pagina.com"];
event.notes = ti;
event.allDay = NO;
vc.event = event;
vc.editViewDelegate = self;
[self presentViewController:vc animated:YES completion:nil];
The event calendar call me correctly only fails when you change the time zone, as I did not take the date correctly I can do?
I use following code to get desired timezone-converted datetime:
- (NSString *) getUTCDate : (NSString *) inputDate
{
NSDateFormatter *utcDateFormatter = [[NSDateFormatter alloc] init];
[utcDateFormatter setDateFormat:#"dd-MMM-yyyy HH:mm:ss Z"];
[utcDateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
// [utcDateFormatter setTimeZone :[NSTimeZone timeZoneForSecondsFromGMT: 0]];
// utc format
NSDate *dateInUTC = [utcDateFormatter dateFromString: inputDate];
return dateInUTC;
}
where dateInUTC is the date in GMT timezone.
You need to replace your own timezone in call [NSTimeZone timeZoneWithName:#"UTC"] and it should work.
Simply change one line of code in your code...
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
This will set time format in universal which doesnot change with region or day light saving time.

Resources