Chapter 12 Challenge Solution

[code]@autoreleasepool {

    //
    NSDateComponents *components = [[NSDateComponents alloc] init];
    
    [components setYear:1993];
    [components setMonth:7];
    [components setDay:2];
    [components setHour:13];
    [components setMinute:10];
    [components setSecond:0];
    
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *dateOfBirth = [calendar dateFromComponents:components];
    
    //
    NSDateComponents *nowdays = [[NSDateComponents alloc] init];
    
    [nowdays setYear:2012];
    [nowdays setMonth:11];
    [nowdays setDay:9];
    [nowdays setHour:5];
    [nowdays setMinute:27];
    [nowdays setSecond:0];
    
    NSCalendar *nowdaysCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *nowdaysDate = [nowdaysCalendar dateFromComponents:nowdays];
    
    //
    double seconds = [nowdaysDate timeIntervalSinceDate:dateOfBirth];
    
    NSLog(@"\nMy age is %.2f.", (((seconds/60)/60)/24)/360); // I want to know my age in years.
    
}[/code]

[Moderator Edit] Added Code tags

I wrote the code a bit differently…

[code]NSDate *now = [NSDate date];

    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setYear: 1991];
    [comps setMonth:1];
    [comps setDay:15];
    [comps setHour:20];
    [comps setMinute:1];
    [comps setSecond:15];
    
    NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *dateOfBirth = [g dateFromComponents:comps];
    
    double secs = [now timeIntervalSinceDate: dateOfBirth];
    NSLog(@"I have been alive for %f seconds", secs);
    
    double age = (secs / (60 * 60 * 24 * 365));
    NSLog(@" I am %f years old", age);[/code]

Resulting in:

2012-11-13 14:58:55.431 TimeAfterTime[42253:303] I have been alive for 688849060.428998 seconds
2012-11-13 14:58:55.432 TimeAfterTime[42253:303] I am 21.843260 years old

What am I doing wrong and why???
//
// main.m
// TimeAfterTime
//
// Created by Sumner Magruder on 12/9/13.
// Copyright © 2013 Sumner Magruder. All rights reserved.
//

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    NSDate *now = [NSDate date];
    NSLog(@"The new date lives at %@", now);
    double seconds = [now timeIntervalSince1970];
    NSLog(@"It has been %f seconds since the start of 1970.", seconds);
    
    NSDate *later = [now dateByAddingTimeInterval:100000];
    NSLog(@"In 100,000 seconds it will be %@", later);
    
    NSDateComponents *comp = [[NSDateComponents alloc] init];
    [comp setYear:1993];
    [comp setMonth:9];
    [comp setDay:24];
    [comp setHour:5];
    [comp setMinute:15];
    [comp setSecond:0];
    
    NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *dateOfBirth = [g dateFromComponents:comp];
    
    
    double d = [now timeIntervalSinceDate:dateOfBirth];
    NSLog(@"I've been organic since %@", d);
}
return 0;

}

You should post your code between the code tags, like this:

void FooBar ()
{
   ...
}

And, more importantly, describe what you think the problem is.

Incidentally, the error is in the last NSLog statement.

First of all, I would like to thank everyone in the forum for their enormous help. I am having a lotta of fun reading the book because of you. The forum is a natural extension of my reading and I check every single post on each chapter that I finish.

I was trying for a solution that returned the years, months and minutes since I was born. The first one I came up with used simple arithmetic to calculate that using the % operator.

[code] NSDateComponents *birth = [[NSDateComponents alloc] init];
[birth setYear:1975];
[birth setMonth:12];
[birth setDay:31];
[birth setHour:11];
[birth setMinute:0];
[birth setSecond:0];

    NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSDate *dateOfBirth = [g dateFromComponents:birth];
    
    NSDate *now = [NSDate date];
    
    double secondsSinceBirth = [now timeIntervalSinceDate:dateOfBirth];
    
    NSLog(@"It has been %f seconds since my birth", secondsSinceBirth);
    
    int yearsAlive = (int) secondsSinceBirth / 31536000;
    
    double remainder = (int) secondsSinceBirth % 31536000;
    
    int monthsAlive = (int) remainder / 2592000;
    
    int daysAlive = (int) remainder % 2592000 / 86400;
    
    int hoursAlive = (int) remainder % 2592000 % 86400 / 3600;
    
    int minutesAlive = (int) remainder % 259200 % 86400 % 3600 / 60;
    
    NSLog(@"I am %d years, %d months, %d days, %d hours, %d minutes old", yearsAlive, monthsAlive, daysAlive, hoursAlive, minutesAlive);
    
}
return 0;

}
[/code]

It logs:

2013-12-13 19:31:48.042 Challenge 5.1[60424:303] It has been 1197703908.042589 seconds since my birth
2013-12-13 19:31:48.043 Challenge 5.1[60424:303] I am 37 years, 11 months, 27 days, 7 hours, 31 minutes old
Program ended with exit code: 0

I don’t really know why the need for (int) before each division, but (after a few experiments) it only worked that way. I know that it has something to do with the fact that is a integer division with a double variable. But other than that I am at a loss. Could someone explain why?

My second solution made use of the array data structure and a loop to convert seconds into years, months, hours and minutes.

[code] NSDateComponents *birth = [[NSDateComponents alloc] init];
[birth setYear:1975];
[birth setMonth:12];
[birth setDay:31];
[birth setHour:11];
[birth setMinute:0];
[birth setSecond:0];

    NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSDate *dateOfBirth = [g dateFromComponents:birth];
    
    NSDate *now = [NSDate date];
    
    double secondsSinceBirth = [now timeIntervalSinceDate:dateOfBirth];
    
    NSLog(@"It has been %f seconds since my birth", secondsSinceBirth);
    
    int quotientValues [] = {31536000, 2592000, 86400, 3600, 60};
    
    int results [5];
    
    for (int i = 0; i < 5; i ++) {
        
        results [i] = (int) secondsSinceBirth/ quotientValues [i];
        
        secondsSinceBirth = (int) secondsSinceBirth % quotientValues [i];
    }
    
    NSLog(@"%d years, %d months, %d days, %d hours, %d minutes old", results [0], results [1], results [2], results [3], results [4]);
    
}
return 0;[/code]

Is it possible to log the array results without having to call each member (“results [0], results [1], …, etc”)?

Thank you.

(int) expression

means convert the value of expression to integer value.

double pi = 3.145;

(int)pi;  // convert to int (3).

(int)2.7  // convert to int (2)

[quote]Is it possible to log the array results without having to call each member (“results [0], results [1], …, etc”)?
[/quote]
No. You have to iterate through the primitive arrays manually.

[quote=“magds16”]What am I doing wrong and why???
NSLog(@“I’ve been organic since %@”, d);
}[/quote]

variable d is a double, yet you don’t not set the type in the NSLog, you will need %f

I was pulling my hair out…the console kept saying i was 931 years old… Turns out i had setYear to 1084…my bad