Reputation: 63
I have the following problem. I need to create an NSDate object from a specific time. The time is 6 pm for today in a given timezone (sometimes CST, EST etc). Not 6 pm for every day, but 6pm for today in that particular timezone.
I was thinking of using the NSCalendar object to create the specific date/time but the problem is that it needs a day, month and year. So how do I set these values when I don't have the correct date for it. Example :
Today is 28th January 2014, 11:09 in CST. Now if I need to create a NSCalendar object I would need the day, month and year. I cannot use the NSDate object's day, month and year calculations as it will lead to problems with edge cases.
Can anyone point me in the right direction?
Upvotes: 6
Views: 8794
Reputation: 789
Alternatively,
NSLocale *const here = [NSLocale currentLocale];
NSDate *const now = [[NSDate alloc] init];
NSCalendar *const calendar = [NSCalendar currentCalendar];
[calendar setLocale: here];
NSTimeZone *const timeZone = [NSTimeZone localTimeZone];
[calendar setTimeZone: timeZone];
NSDate *const midnight = [calendar startOfDayForDate: now];
NSDate *sixOClock = [[NSDate date] initWithTimeInterval: 60 * 60 * (12 + 6) sinceDate: midnight];
if ([now isGreaterThan: sixOClock]) {
sixOClock = [[NSDate date] initWithTimeInterval: 60 * 60 * (12 + 6) + (24 * 60 * 60) sinceDate: midnight];
}
Upvotes: 0
Reputation: 2177
Swift
let calendar = Calendar(identifier: .gregorian)
let units: Set<Calendar.Component> = [.year, .month, .day, .hour]
var components = calendar.dateComponents(units, from: Date())
components.hour = 18
let todayAt6PM = calendar.date(from: components)
Objective C
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSCalendarUnit calendarUnits = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour;
NSDateComponents *components = [calendar components:calendarUnits fromDate:[NSDate date]];
[components setHour:18];
NSDate *todayAt6PM = [calendar dateFromComponents:components];
Upvotes: 3
Reputation: 790
Try out NSDateComponents.
// Initialize date components with date values
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear:2014];
[dateComponents setMonth:1];
[dateComponents setDay:28];
[dateComponents setHour:11];
[dateComponents setMinute:9];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *configuredDate = [calendar dateFromComponents:dateComponents];
I'm not sure what the various NSCalendar identifier configuration options the initWithCalendarIndetifier will take, but if this answer is helpful maybe someone can add an edit with some additional info.
Upvotes: 10
Reputation: 53010
Your concern seems to be about edge cases, this suggests to me that rather than "6pm today" you are actually looking for the "next 6pm", i.e. if the time is past 6pm you want 6pm tomorrow?
Maybe the following will help, whether my guess is correct or not:
NSDate
NSCalendar
NSDateComponents
- only extracting the components for year, month, day, hour & time zone. You now have the current time components in the target time zone rounded down to the nearest hour.NSDate
from your extracted time components using your calendar. You now have your rounded down time as an NSDate
.NSTimeInterval
value, add that interval to your rounded down date. NSDate
will take care of the edge cases of advancing the date, changing the month, etc. as needed.HTH
Upvotes: 8
Reputation: 1708
You can create date from time like this:
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *weekdayComponents = [gregorian components:NSCalendarUnitDay fromDate:today];
[weekdayComponents setHour:[timeOfDay intValue]];
[weekdayComponents setMinute:00];
Initialize a NSDate object with a specific time
Upvotes: 2