0

I have a datepicker and I save the value to .plist file with key UserDate in string format.

The value returns from datepicker is in 2013-02-13 11:17:34 +0000 format.

In order to save it into to .plist file I need to convert datepicker to string 2013-02-14T19:17:34Z

In other View, I want to retrieve back the UserDate from plist and compare with the user current date. I want days and hours different.

I convert and pass 2012-02-12 19:17:34 +0800 as destinationDate to compare with [NSDate new]. I managed to calculate the difference between two date. But the result is not correct.

How to get the correct difference result for two dates between iPhone's date and Datepicker's date? Do I need to use a specific timezone?

Extra info: I live in GMT+8. I set the simulator datepicker to Feb 13 2012, yet the result still say the countdown has 18hours and 4 minutes.

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

enter image description here

Edit

Plist file.

enter image description here

save method

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']];
}
Community
  • 1
  • 1
neotorama
  • 138
  • 2
  • 15
  • 1
    You can save an `NSDate` directly into a plist, it will be automatically converted to an ISO 8601 string format. On reading the plist the `NSData` will be converted back to an `NSDate`. – zaph Feb 12 '12 at 14:47
  • 1
    You should show us more of your code; ideally an entire sequence of statements that reproduces the problem, not just a small portion of it, and especially the code you're using to 1) convert an NSDate into a string and save it to the plist 2) retrieve the date from the plist and make it into a date. – yuji Feb 12 '12 at 14:50
  • 1
    top comment is right..but incomplete..:P .. you can save array,dictionary,data,string,integers etc in a plist file directly.. just make an array with an NSDate object and make a plist of it...then later get the plist..get the array..and you will get the appropriate date at its objectAtIndex :0 ..then compare.. – Shubhank Feb 12 '12 at 14:52

2 Answers2

0

Remember to create the NSDate and then output it with a valid timezone and calendar!

Check a similar question I answered in another post: UIDatePicker return wrong NSDate

Community
  • 1
  • 1
Carlos Morales
  • 5,676
  • 4
  • 34
  • 42
0

NSDate keeps time in GMT. If you have time zones you will have to specify them.

The question is not clear so this is not a complete answer but should provide some help with NSDate in a plist.

Here is an example of creating, writing and reading a plist with a 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"];

There is no need to convert the NSDate to a string and no need to use NSPropertyListSerialization.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • I have edited the question. What I need is the correct result calculation between my datepicker and iphone date. Today is 13 Feb 2012, I set the simulator datepicker to Feb 13 2012, yet the result still say the countdown has 18hours and 4 minutes. sorry for confusion. – neotorama Feb 12 '12 at 17:15