1

I am trying to store times without any date (and preferably no timezone) information associated with them. For example, an employee might have an availability of 9am-11pm, Mon-Fri. You wouldn't store this as every date representing ever (many) future Mon-Fri at those times, but just as arbitrary times that you would add to the dates of the current week.

Also I want to be able to store these times as properties of a Core Data Managed Object.

The only solution I've come up with is storing the times in the hour and minute components of NSDateComponent, but I'm not sure how that will work with Core Data.

jjatie
  • 5,152
  • 5
  • 34
  • 56
  • 1
    While not a duplicate, you may find this similar question useful: http://stackoverflow.com/questions/27631882/function-to-return-open-closed-or-closing-from-hours-of-day – Rob Napier Jan 30 '15 at 21:02
  • Would you need to use this information in an `NSPredicate`? If not, `NSDateComponents` will work fine as long as you make the attribute type `transformable`. If you do need to use the information in predicates, `transformable` is probably not a good idea. – Tom Harrington Jan 30 '15 at 21:18
  • I will be needing to use the info in an NSPredicate. – jjatie Jan 30 '15 at 21:35
  • I like both answers, but ultimately storing the time as Ints and converting it as a date only when necessary seems most efficient. – jjatie Jan 30 '15 at 21:41

3 Answers3

3

You could do something as simple as create an entity with 3 attributes:

  1. Day of week
  2. Hour of day
  3. Minute of hour

(Expanding to start and end hour and minute if required)

The alternative is to store the date components object as binary (transformable) but then you can't query it easily.

Wain
  • 118,658
  • 15
  • 128
  • 151
1

Date components are the most natural solution for the reasons you're obviously already aware of: what we're talking about is inherently partial components of a date. However, Core Data does not inherently support date components.

You could switch safely to NSDate with something like:

- (NSDate *)referenceDate {
    return [NSDate dateWithTimeIntervalSinceReferenceDate:0.0];
}

- (NSCalendar *)referenceCalendar {
    NSCalendar *calendar =  [[NSCalendar alloc] 
                              initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
    return calendar;
}

- (NSDate *)canonicalDateForComponents:(NSDateComponents *)components {
    NSCalendar *calendar = [[self referenceCalendar] 
               dateByAddingComponents:components toDate:[self referenceDate] options:0];
}

- (NSDateComponents *)dateComponents:(NSCalendarUnit)components 
                   fromCanonicalDate:(NSDate *)date {
    return [[self referenceCalendar] components:components 
                                   fromDate:[self referenceDate] toDate:date options:0];
}

You could then store something like NSDate *startTime, NSDate *endTime, NSDate *startDay and NSDate *endDay, storing and retrieving from each by converting as above. Or combine more components as appropriate.

Tommy
  • 99,986
  • 12
  • 185
  • 204
0

I had a similar situation in a Core Data driven app, and I found it most practical to simply store the number of minutes since midnight, so a maximum of 1440. (If you need seconds, multiply by 60, obviously, or use floats if you need fractions of seconds.)

My Time entity also had a weekday attribute (1-7).

It is a really simple and pragmatic solution, an absolute no-brainer, and you can convert to and from dates easily and reliably via integer division or with date components, chacun à son goût.

Mundi
  • 79,884
  • 17
  • 117
  • 140