views:

43

answers:

1

I'm trying to code part of a program that allows users to set up one or more alarms that will remind them to launch the application and do something at certain times of day.

I basically understand that I need to use local notifications, but I'm having a hard time coming up with the best way to represent a time of day in my application settings in the proper manner.

For example, I tried this sort of thing to represent 8:00 AM

[NSDate dateWithTimeIntervalSince1970:(8 * 60 * 60)]

But the problem is that this means 8 AM GMT and not in the local timezone, so when I pass this to NSDateFormatter I end up with 3:00AM for example in my time zone.

Basically I know I need to do something with NSCalendar, NSDate, and NSTimeInterval, and perhaps NSDateComponents but I can't seem to come up with the simplest approach to this that will allow me to calculate scheduling NSDates for iOS local notifications.

So I guess what this boils down to is, how do I represent 8:00 AM for example in the system timezone in such a way that NSDateFormatter will correctly format it as a local time?

Seems like I should be able to figure this out but maybe it's just too late in the evening....

+2  A: 

For example, I tried this sort of thing to represent 8:00 AM

[NSDate dateWithTimeIntervalSince1970:(8 * 60 * 60)]

But the problem is that this means 8 AM GMT and not in the local timezone…

No, the problem is that that means 8 AM GMT on January 1st, 1970.

An NSDate object is not expressed in any calendar or time zone. An NSDate object is a moment in history, nothing more. You need a calendar object to convert it to or from a calendar representation (e.g., year, month, day-of-month, hour, minute, second), or a date formatter to convert it to or from a string representation (e.g., “2010-10-15T22:29:27-0700”).

If you want to compute the NSDate for 8 AM today, create an NSCalendar object and ask it when that is. Use components:fromDate: to turn right now ([NSDate date]) into date components, then overwrite the hour, minute, and second and convert back.

A UIDatePicker (such as you probably should present to the user to enable them to choose the date and time of their alarm) will give you an NSDate; there is no need to perform any sort of conversion or manipulation on it. The most you might need to do is subtract some time if the user chose to have you ring the alarm that much time ahead of the actual event.

So I guess what this boils down to is, how do I represent 8:00 AM for example in the system timezone in such a way that NSDateFormatter will correctly format it as a local time?

An NSDateFormatter takes an NSDate, and, as I said, NSDates aren't in a time zone. As you saw, your date formatter will use the user's time zone by default (although this isn't explicitly stated in the documentation). For the date formatter to use something else, you would have to have told it to do so.

Peter Hosey
Ok, so what I'm getting from this is that I shouldn't try to abuse NSDate to represent time of day, but instead just store NSUIntegers for hour and minute, or perhaps just store minutes or seconds since midnight, then just use that to calculate a date when notifications are scheduled. Then I just don't use NSDateFormatter to present the alarm time in the UI because it's not the appropriate thing to use for that.
Nimrod
Nimrod: Use NSDateComponents for hour and minute, or store seconds since midnight (as an NSTimeInterval, which has no fixed reference point—reference point + interval = date). You can use NSDateFormatter to present a specific fire date (“Next alarm: 2010-10-17T08:00”), but yes, for the hour and minute alone, you should use something else.
Peter Hosey