Разлика в датата между UIDatepicker и NSDate

Имам инструмент за избор на дата и записвам стойността в .plist файл с ключ UserDate във формат на низ.

Стойността, върната от инструмента за избор на дата, е във формат 2013-02-13 11:17:34 +0000.

За да го запазя в .plist файл, трябва да конвертирам datepicker в низ 2013-02-14T19:17:34Z

В друг изглед искам да извлека обратно UserDate от plist и да сравня с текущата дата на потребителя. Искам дни и часове различни.

Преобразувам и предавам 2012-02-12 19:17:34 +0800 като destinationDate за сравнение с [NSDate new]. Успях да изчисля разликата между две дати. Но резултатът не е правилен.

Как да получа правилния резултат за разликата за две дати между датата на iPhone и датата на Datepicker? Трябва ли да използвам определена часова зона?

Допълнителна информация: Живея в GMT+8. Зададох инструмента за избор на дата на симулатора на 13 февруари 2012 г., но резултатът все още казва, че обратното броене има 18 часа и 4 минути.

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
int units = NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate:destinationDate options:0];
[datelabel setText:[NSString stringWithFormat:@"%d%c %d%c %d%c %d%c %d%c", [components month], 'm', [components day], 
                    'd', [components hour], 'h', [components minute], 'm', [components second], 's']];

NSLog

въведете описание на изображението тук

Редактиране

Plist файл.

въведете описание на изображението тук

метод за запазване

NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Data.plist"];

// set the variables to the values in the text fields
self.userTitle = myTitle.text;
self.userMessage = myMessage.text;  

NSLog(@"METHOD SAVE");

NSLog(@"Datepicker value =  %@", myDate.date );

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSString *mdate = [dateFormatter stringFromDate:myDate.date];
//  [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];

NSLog(@"Converted from date picker, save into plist =  %@", mdate );

self.saveDate = mdate;
//self.userDate = myDate.date;

// create dictionary with values in UITextFields
NSDictionary *plistDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: userTitle, userMessage, saveDate, nil] forKeys:[NSArray arrayWithObjects: @"Title", @"Message", @"UserDate", nil]]; NSString *error = nil;
// create NSData from dictionary
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];

// check is plistData exists
if(plistData)
{
    // write plistData to our Data.plist file
    [plistData writeToFile:plistPath atomically:YES];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Your settings have been saved." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok",nil];
    [alert show];
}
else
{
    NSLog(@"Error in saveData: %@", error);
    //[error release];
}

viewWillAppear

- (void)viewWillAppear:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES];

[super viewWillAppear:animated];

// Data.plist code
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"Data.plist"];

// check to see if Data.plist exists in documents
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
    // if not in documents, get property list from main bundle
    plistPath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
}

// read property list into memory as an NSData object
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
NSString *errorDesc = nil;
NSPropertyListFormat format;
// convert static property liost into dictionary object
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
if (!temp)
{
    NSLog(@"Error reading plist: %@, format: %d", errorDesc, format);
}

NSLog(@"Plist Title: %@", [temp objectForKey:@"Title"]);
NSLog(@"Plist Message: %@", [temp objectForKey:@"Message"]);
NSLog(@"Plist date: %@", [temp objectForKey:@"UserDate"]);

userTitle.text = [NSString localizedStringWithFormat:@"%@", [temp objectForKey:@"Title"]];
userMessage.text = [NSString localizedStringWithFormat:@"%@", [temp objectForKey:@"Message"]];

//http://stackoverflow.com/questions/1070354/how-do-i-get-the-current-date-in-cocoa

NSDate* now = [[NSDate alloc] initWithTimeIntervalSinceNow:3600];
userCoundown.text = [NSString stringWithFormat:@"%@",now];  

NSString *uDate = [[NSString alloc] init];
uDate = [temp objectForKey:@"UserDate"];
NSLog(@"Plist date in string - %@", uDate);

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate *ddate = [dateFormatter dateFromString:uDate];
[dateFormatter setDateFormat:@"yyyy-MM-dd H:mm:ss Z"];

NSLog(@"Format date from Plist -  %@", [dateFormatter stringFromDate:ddate]);

//NSLog(@"GMT format from Plist - %@", timeStamp);

//http://www.epochconverter.com/#
destinationDate = ddate;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabel) userInfo:nil repeats:YES];
}

updatelabel

-(void)updateLabel {

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
int units = NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate:destinationDate options:0];
[datelabel setText:[NSString stringWithFormat:@"%d%c %d%c %d%c %d%c %d%c", [components month], 'm', [components day], 
                    'd', [components hour], 'h', [components minute], 'm', [components second], 's']];
}

person neotorama    schedule 12.02.2012    source източник
comment
Можете да запишете NSDate директно в plist, той ще бъде автоматично преобразуван във формат на низ ISO 8601. При четене на plist NSData ще се преобразува обратно в NSDate.   -  person zaph    schedule 12.02.2012
comment
Трябва да ни покажете повече от вашия код; в идеалния случай цяла последователност от изрази, които възпроизвеждат проблема, а не само малка част от него, и особено кода, който използвате, за да 1) конвертирате NSDate в низ и да го запишете в plist 2) извлечете датата от plist и го превърнете в среща.   -  person yuji    schedule 12.02.2012
comment
горният коментар е прав..но непълен..:P .. можете да запишете масив, речник, данни, низ, цели числа и т.н. директно в plist файл.. просто направете масив с NSDate обект и направете plist от него.. .след това по-късно вземете plist..вземете масива..и ще получите подходящата дата в неговия objectAtIndex :0 ..след това сравнете..   -  person Shubhank    schedule 12.02.2012
comment
съжалявам Добавих кода. Благодаря   -  person neotorama    schedule 12.02.2012


Отговори (2)


NSDate пази времето в GMT. Ако имате часови зони, ще трябва да ги посочите.

Въпросът не е ясен, така че това не е пълен отговор, но трябва да предостави известна помощ с NSDate в plist.

Ето пример за създаване, писане и четене на plist с NSDate:

NSDictionary *plistDict = [NSDictionary dictionaryWithObjectsAndKeys:
                           userTitle,   @"Title",
                           userMessage, @"Message",
                           saveDate,    @"UserDate",
                           nil];

[plistDict writeToFile:filePath atomically:YES];

NSDictionary *plistDictRead = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSDate *dateRead = [plistDictRead objectForKey:@"UserDate"];

Няма нужда да конвертирате NSDate в низ и няма нужда да използвате NSPropertyListSerialization.

person zaph    schedule 12.02.2012
comment
Редактирах въпроса. Това, от което се нуждая, е правилното изчисление на резултата между моя инструмент за избор на дата и датата на iphone. Днес е 13 февруари 2012 г., зададох инструмента за избор на дата на симулатора на 13 февруари 2012 г., но резултатът все още казва, че обратното броене има 18 часа и 4 минути. съжалявам за объркването. - person neotorama; 12.02.2012

Не забравяйте да създадете NSDate и след това да го изведете с валидна часова зона и календар!

Вижте подобен въпрос, на който отговорих в друга публикация: UIDatePicker връща грешен NSDate

person Carlos Morales    schedule 09.08.2012