2009-11-19 8 views
0

C'est probablement une question stupide mais je n'arrive pas à trouver une réponse.NSDate - Change Time Component

J'utilise un sélecteur de date pour permettre à un utilisateur d'entrer une date et il règle également l'heure à l'heure actuelle (I init le sélecteur avec [date NSDate]).

Existe-t-il un moyen de modifier la composante temporelle de la date? Je calcule plus tard des intervalles de temps qui renvoient des secondes et je reçois un comportement étrange à cause du temps.

Ce code montre l'entrée de date:

@implementation AddEventViewController 
@synthesize backgroundColor, nameField, dateField, datePicker, eventName, eventDate; 

-(void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    self.view.backgroundColor = self.backgroundColor; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; 


    CGSize size = self.view.bounds.size; 
    CGRect frame = CGRectMake(0, size.height - 216, 320, 216); 
    datePicker = [[UIDatePicker alloc] initWithFrame: frame]; 
    datePicker.datePickerMode = UIDatePickerModeDate; 
    datePicker.hidden = YES; 
    datePicker.date = [NSDate date]; 
    [datePicker addTarget:self 
        action:@selector(changeDateInLabel:) 
     forControlEvents:UIControlEventValueChanged]; 

    [self.view addSubview: datePicker]; 
} 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
} 

-(IBAction)doneButton 
{ 
    if ((nameField.text != nil)) 
    { 
     self.eventName = nameField.text; 
     self.eventDate = datePicker.date; 
     [[NSNotificationCenter defaultCenter]postNotificationName:@"EventAddDone" object:nil]; 
    } 
    else 
    { 
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Enter Event Name" message:nil delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil]; 
     [alertView show]; 
     [alertView release]; 
    } 
} 

-(IBAction)cancelButton 
{ 
    [[NSNotificationCenter defaultCenter]postNotificationName:@"EventAddCancel" object:nil]; 

} 
- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    [textField resignFirstResponder]; 
    return YES; 
} 

- (void)changeDateInLabel:(id)sender 
{ 
    dateField.text = [dateFormatter stringFromDate:[datePicker date]]; 
} 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
{ 
    if(textField == dateField) 
    { 
     dateField.placeholder = @" "; 
     dateField.text = [dateFormatter stringFromDate:[datePicker date]]; 
     datePicker.hidden = NO; 
     [nameField resignFirstResponder]; 
     return NO; 
    } 
    return YES; 
} 

- (void)dealloc 
{ 
    self.backgroundColor = nil; 
    self.nameField = nil; 
    self.dateField = nil; 
    self.datePicker = nil; 
    self.eventName = nil; 
    self.eventDate = nil; 
    [dateFormatter release]; 
    [super dealloc]; 
} 
@end 

Mon utilisation de la date d'enregistrement est similaire à ce qui suit:

NSTimeInterval age = [enteredDate timeIntervalSinceNow]; 
//do some math on the age variable to get number of days since the event occurred. 
+0

Vous devriez changer cela à NSInteger au lieu de changer à NSTimeInterval. J'ai typo. – jtbandes

+0

Merci, j'ai vu ça après avoir répondu ci-dessous. – Eric

Répondre

3

Deux options:

Option 1:

int fromDate = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit 
                 inUnit:NSEraCalendarUnit 
                 forDate:enteredDate]; 
int toDate = [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit 
                 inUnit:NSEraCalendarUnit 
                forDate:[NSDate date]]; 
int days = toDate - fromDate; 

option 2:

NSDate *dateA, *dateB; 
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit 
           startDate:&dateA 
           interval:NULL 
            forDate:enteredDate]; 

[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit 
           startDate:&dateB 
           interval:NULL 
            forDate:[NSDate date]]; 
//From here, apply the above method using components:fromDate:toDate: 
//with dateA and dateB, which are set to the beginning of the days on 
//which they lie. 
+0

J'ai utilisé l'option 2 et cela a fonctionné parfaitement.Merci! – Eric

+0

Une chose pour vous assurer que vous testez est si les deux dates se trouvent sur les côtés opposés de l'une ou l'autre savi daylight ngs limite temporelle, renvoie-t-il toujours la même valeur. J'ai dû faire face à ce problème à plusieurs reprises. –

2
NSInteger days = [[[NSCalendar currentCalendar] components:NSDayCalendarUnit 
                fromDate:enteredDate 
                toDate:[NSDate date] 
                options:0] day]; 
+0

Très bien, merci. J'ai dû changer NSInterval à NSTimeInterval mais cela a fonctionné après cela. – Eric

+0

Oups, désolé, je voulais dire NSInteger. NSDateComponents (qui est ce qui est créé en utilisant 'components: fromDate: toDate: options:' stocke des composants en tant que NSIntegers – jtbandes

+0

En fait, mon code semble beaucoup mieux, mais j'ai toujours un problème, voici une entrée qui explique ce que je veux dire: à partir de 2009-11-19 21:06:40 -0500 à 2009-11-18 21:14:56 -0500 est 0 jours Je voudrais que cela ignore le temps et considère qu'un jour à part. ? – Eric