29

This is quite a simple concept, but as of yet I have been unable to find an elegant (and calendar locale independent) solution. I need to find the first day of the month for an arbitrary NSDate. For example, given an arbitrary NSDate (arbitraryDate) another NSDate object will be returned (let's call this firstDayOfMonthDate) which represents the first day of the month in arbitraryDate. The time component does not matter, as I just need the NSDate object for the first day of the month (although for neatness it would be useful if the time was just zeroed out).

Thanks in advance for any assistance.

Skoota
  • 5,280
  • 9
  • 52
  • 75
  • can u explain it with example – jmj Sep 16 '10 at 10:28
  • I would like to provide a function with an NSDate such as 16 September 2010. The function would then return another NSDate which is the first day of that month. Continuing the previous example, the NSDate that would be returned is 1 September 2010. I realise that there are various alternate ways to accomplish this end result (split the original date into components, then rebuild with the day component being 1) but I am thinking that there must be a more elegant solution. – Skoota Sep 16 '10 at 10:33

5 Answers5

72

A possible solution:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *arbitraryDate = [NSDate date];
NSDateComponents *comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:arbitraryDate];
[comp setDay:1];
NSDate *firstDayOfMonthDate = [gregorian dateFromComponents:comp];
unom
  • 11,438
  • 4
  • 34
  • 54
diciu
  • 29,133
  • 4
  • 51
  • 68
  • Thanks for your suggestion. However, this will only work with the Gregorian calendar. Is it possible to make it calendar locale/format independent, as I would like the app I am building to work across all calendar formats supported on the iPhone? – Skoota Sep 16 '10 at 10:35
  • 9
    you can use [NSCalendar currentCalendar] – diciu Sep 16 '10 at 12:30
  • Thanks mate. Working perfectly. – Skoota Sep 17 '10 at 07:49
  • 5
    @diciu +1 from me too ..it worked but may be beasue of timezome I get the wrong date.How I can set that. Passed date 2012-04-26 06:55:40 +0000 & I am getting 2012-03-31 18:30:00 +0000. – Ajay Sharma Apr 26 '12 at 06:58
8
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear 
                                                               fromDate:[NSDate date]];
components.day = 1;
NSDate *firstDayOfMonthDate = [[NSCalendar currentCalendar] dateFromComponents: components];
NSLog(@"First day of month: %@", [firstDayOfMonthDate descriptionWithLocale:[NSLocale currentLocale]]);
falsecrypt
  • 1,536
  • 14
  • 11
4

Swift 3

I've included getting the last day of the month in case it is useful to anyone.

extension Date {
    func lastDayOfMonth() -> Date {
        let calendar = Calendar.current
        let dayRange = calendar.range(of: .day, in: .month, for: self)
        let dayCount = dayRange!.count
        var comp = calendar.dateComponents([.year, .month, .day], from: self)

        comp.day = dayCount

        return calendar.date(from: comp)!
    }

    func firstDayOfMonth() -> Date {
        let calendar: Calendar = Calendar.current
        var components: DateComponents = calendar.dateComponents([.year, .month, .day], from: self)
        components.setValue(1, for: .day)
        return calendar.date(from: components)!
    }
}
Chris Byatt
  • 3,689
  • 3
  • 34
  • 61
1

Swift version

let arbitraryDate:NSDate = NSDate()
let calendar:NSCalendar = NSCalendar.currentCalendar()
let components:NSDateComponents = calendar.components([.Year, .Month, .Day], fromDate: arbitraryDate)
components.setValue(1, forComponent: .Day)
let firstDayOfMonthDate = calendar.dateFromComponents(components)
Digitech
  • 262
  • 2
  • 9
1

Swift 3:

let calendar = Calendar.current
var comps = calendar.dateComponents([.year, .month], from: date)
comps.setValue(1, for: .day)
let firstDayOfMonth = calendar.date(from: comps)!

// I tried this, but it doesn't work, why?
// let firstDayOfMonth = calendar.date(bySetting: .day, value: 1, of: date)!
Ferran Maylinch
  • 10,919
  • 16
  • 85
  • 100