2009-09-24 39 views

Trả lời

5

Nếu bạn chỉ sử dụng Lịch Gregorian, bạn có thể tính toán thủ công.

http://en.wikipedia.org/wiki/Leap_year#Algorithm

if year modulo 400 is 0 then leap 
else if year modulo 100 is 0 then no_leap 
else if year modulo 4 is 0 then leap 
else no_leap 
+2

Tính số ngày trong năm là đủ đơn giản, nhưng nói chung tôi khuyên bạn nên sử dụng thư viện ngày/giờ sẵn có. Thực hiện các phép tính ngày/giờ theo cách thủ công sẽ luôn quay trở lại và cắn bạn bằng cách nào đó ... – Krumelur

+0

Tôi thực sự khuyên bạn nên chống lại điều này. Thời gian là siêu phức tạp. Nếu bạn cần công cụ của bạn để làm việc trong các ngôn ngữ khác mà có thể không sử dụng lịch Gregorian hoặc cần phải làm việc trong quá khứ xa xôi (một lần nữa không Gregorian) điều này sẽ không hoạt động. NSCalendar thật tuyệt vời để giải quyết những thứ này. –

5

Cuối cùng tôi đã đưa ra một giải pháp mà làm việc. Những gì tôi làm đầu tiên tính toán số tháng trong năm và sau đó cho mỗi tháng tính toán số ngày cho tháng đó.

Mã này trông như thế này:

NSUInteger days = 0; 
NSCalendar *calendar = [NSCalendar currentCalendar]; 
NSDate *today = [NSDate date]; 
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:today]; 
NSUInteger months = [calendar rangeOfUnit:NSMonthCalendarUnit 
            inUnit:NSYearCalendarUnit 
            forDate:today].length; 
for (int i = 1; i <= months; i++) { 
    components.month = i; 
    NSDate *month = [calendar dateFromComponents:components]; 
    days += [calendar rangeOfUnit:NSDayCalendarUnit 
          inUnit:NSMonthCalendarUnit 
          forDate:month].length; 
} 

return days; 

Nó không phải là gọn gàng như tôi đã có hy vọng nhưng nó sẽ làm việc cho bất kỳ lịch như bình thường Gregorian một hoặc một islamic.

1

Sử dụng NSCalendarNSDateComponent lớp học, như thế này:

long GetDaysInYear(int year) { 
    NSDateComponents* c = [[NSDateComponents alloc] init]; 
    c.year = year; 
    NSCalendar* cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSDate* startDate = [cal dateFromComponents:c]; 
    c.year += 1; 
    NSDate* endDate = [cal dateFromComponents:c]; 
    return [cal components:NSDayCalendarUnit fromDate:startDate toDate:endDate options:0].day; 
} 
0

Một ví dụ:

func daysInYear(year: Int) -> Int { 
    var calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar) 
    var b = NSDate.dateWithNaturalLanguageString("01.01.\(year)", locale: NSLocale.currentLocale()) as! NSDate 
    var e = NSDate.dateWithNaturalLanguageString("12.31.\(year)", locale: NSLocale.currentLocale()) as! NSDate 

    return calendar!.components(NSCalendarUnit.CalendarUnitDay, fromDate: b, toDate: e, options: nil).day + 1 
} 

Nhưng ngày mặc định trở lại 355 và 354 này gây ra (có thể) đếm rằng bắt đầu từ con số không:)

+0

Đó là một ít kể từ khi bạn bắt đầu từ ngày đầu tiên. Nếu bạn làm từ 12/31 đến 12/31, đó là một năm đầy đủ :) –

+0

Tôi nghĩ năm bắt đầu từ 01.01.2015 00:00:00 (000) và kết thúc đến 31.12.2015 23:59:59 (99) :)) – iTux

8

Đây là tiện ích mở rộng NSCalendar siêu chính xác trong Swift 2:

extension NSCalendar { 
    func daysInYear(date: NSDate = NSDate()) -> Int? { 
     let year = components([NSCalendarUnit.Year], fromDate: date).year 
     return daysInYear(year) 
    } 

    func daysInYear(year: Int) -> Int? { 
     guard let begin = lastDayOfYear(year - 1), end = lastDayOfYear(year) else { return nil } 
     return components([NSCalendarUnit.Day], fromDate: begin, toDate: end, options: []).day 
    } 

    func lastDayOfYear(year: Int) -> NSDate? { 
     let components = NSDateComponents() 
     components.year = year 
     guard let years = dateFromComponents(components) else { return nil } 

     components.month = rangeOfUnit(NSCalendarUnit.Month, inUnit: NSCalendarUnit.Year, forDate: years).length 
     guard let months = dateFromComponents(components) else { return nil } 

     components.day = rangeOfUnit(NSCalendarUnit.Day, inUnit: NSCalendarUnit.Month, forDate: months).length 

     return dateFromComponents(components) 
    } 
} 

Bạn có thể sử dụng nó như thế này:

let calendar = NSCalendar.currentCalendar() // I'm using the Gregorian calendar 
calendar.daysInYear()  // 365 (since it's currently 2015) 
calendar.daysInYear(2016) // 366 (leap year!) 

Đây là siêu linh hoạt vì chúng ta không thừa nhận bất cứ điều gì về độ dài của lịch:

let hebrew = NSCalendar(calendarIdentifier: NSCalendarIdentifierHebrew) 
hebrew?.daysInYear(-7) // 354 
hebrew?.daysInYear(-100) // 384 

Thưởng thức.

+0

Một cách tiếp cận khác là lấy các tháng trong năm nhất định và sau đó liệt kê mỗi tháng và cộng lại các ngày. Tôi không chắc cái nào chính xác hơn hoặc hiệu quả hơn. Tôi cho rằng cách tiếp cận hiện tại của tôi là hiệu quả nhất. Không có ý tưởng nếu nó chính xác hơn để làm điều đó theo cách khác mặc dù. Thời gian là khó. –

Các vấn đề liên quan