2

I am trying to create a day/month UIPickerView, no year. The goal being to pick a day/month to list historic events that happened on that day/month.

[NSCalendar currentCalendar]maximumRangeOfUnit:NSCalendarUnitDay]

will obtain the maximum number of days in any month, i.e. 31 in the Gregorian calendar. What I really want is something along the lines of

[calendar maximumRangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarMonth unit:2]

which would return 29 for February in the Gregorian calendar.

From what I can see the only thing close has a forDate: which isn't helpful. A quick hack would be to use that for a date in a range of 8 years (to handle non leap year centuries), but that wouldn't work for other calendar types with varying leap year rules.

Any suggestions on how to achieve this?

David Knight
  • 763
  • 6
  • 12
  • Can you expand a little on what you're showing in the picker and how you use it? Does your picker display a year as well as a day and month? – Tom Harrington Jan 19 '17 at 19:35
  • As stated, day/month, no year displayed at all, if a year were included the problem wouldn't exist as the existing UIDatePicker could be used or the forDate: message would solve the problem. – David Knight Jan 19 '17 at 19:48
  • @DavidKnight - His issue, I believe, is that he wants 29 for February, regardless if he happens to do this on 1-Feb-2017 which only has 28 days (hence his comment about repeating this for 8 years, but worrying that this is might not be sufficient for non-Gregorian calendars). – Rob Jan 19 '17 at 19:54

1 Answers1

2

NSCalendar doesn't directly offer the feature you're asking for. Since you want to support other calendars, your best bet is indeed to loop over many era/year/month combinations, calling -[NSCalendar rangeOfUnit:inUnit:forDate:]. Eight years will not be enough, as (for example) the Hebrew calendar is on (I believe) a 19-year cycle.

Also note that other calendars (e.g. the Chinese calendar) have more than just the two eras (BCE/CE) of the Gregorian calendar, so you should vary the era as well as the year and month.

If this is expensive, you could write a command-line program that does it and emits source code for a table that you embed in your app. Then you can run the program as a pre-compilation build step.

If you have appropriate access to the database of historic events, another approach would be to find every date actually used in the database, and just make sure your ranges cover those dates.

Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848