Date difference between UIDatepicker and NSDate - objective-c

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
Edit
Plist file.
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']];
}

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.

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

Related

convert hard code nsstring to nsdate

say i have this nsstring * date = #"13th May-2015"
i want to convert it to something like this #"13/05/2015"
currently i am trying to do it with nsdateformatter:
NSString * dateStr = #"13th May-2015";
NSDateFormatter *dateFormatOriginal = [[NSDateFormatter alloc] init];
[dateFormatOriginal setDateFormat:#"dd MM-yyyy"];
NSDate *date = [dateFormatOriginal dateFromString:dateStr];
NSDateFormatter *dateFormatConverted = [[NSDateFormatter alloc] init];
[dateFormatConverted setDateFormat:#"dd/MM/yyyy"];
NSString * convertedDateString = [dateFormatConverted stringFromDate:date];
NSLog(#"this should be 13/05/2015, %#", convertedDateString);
so i expect the converted date string became to 13/05/2015.
but above code fail to do so....any help with code example would be helpful, thanks guys.
NSString * dateStr = #"13th May-2015";
NSArray *stringComponentArray = [dateStr componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSMutableArray *workingArray = [NSMutableArray arrayWithArray:stringComponentArray];
NSMutableString *dateString = [[NSMutableString alloc]initWithString:[workingArray firstObject]];
[dateString replaceOccurrencesOfString:#"st" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0,[dateString length])];
[dateString replaceOccurrencesOfString:#"nd" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0,[dateString length])];
[dateString replaceOccurrencesOfString:#"rd" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0,[dateString length])];
[dateString replaceOccurrencesOfString:#"th" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0,[dateString length])];
[workingArray replaceObjectAtIndex:0 withObject:dateString];
dateStr = [workingArray componentsJoinedByString:#" "];
NSDateFormatter *dateFormatOriginal = [[NSDateFormatter alloc] init];
[dateFormatOriginal setDateFormat:#"dd MM-yyyy"];
NSDate *date = [dateFormatOriginal dateFromString:dateStr];
NSDateFormatter *dateFormatConverted = [[NSDateFormatter alloc] init];
[dateFormatConverted setDateFormat:#"dd/MM/yyyy"];
NSString * convertedDateString = [dateFormatConverted stringFromDate:date];
NSLog(#"this should be 13/05/2015, %#", convertedDateString);
Since your date string doesn't match with any of the iOS Date formatter styles. Uou need to play with the strings.Please have a look into above solution.
13th May-2014 is not "dd MM-yyyy" format.
You have to make sure your input string matches the format string exactly.

Create ICS with objective C

I am writing an app for students at my university. At this point I want to export the lessons in the schedule as an ics-file. I have wrote something that works with csv-files, but now I want the same for ics.
The problem is that iCal at my Mac doesn't want the in-app-created ics-files from this code:
-(NSURL*)getFileUrl
{
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"Stundenplan-%#.ics", _MatrNr]];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSError *error = nil;
[[self getICSData] writeToURL:fileUrl atomically:YES];
if (error) {
NSLog(#"Error while writing to File: %#", [error localizedDescription]);
}
return fileUrl;
}
-(NSData*)getICSData
{
NSMutableString *erg = [[NSMutableString alloc] init];
NSDate *aktDatum = [NSDate date];
[erg appendString:[NSString stringWithFormat:#"BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//www.htw-dresden.de//iOS//DE\nMETHOD:PUBLISH\n"]];
for (Stunde *this in _daten) {
NSString *titel = [this.titel stringByReplacingOccurrencesOfString:#"," withString:#"\\, "];
NSString *dozent = [this.dozent stringByReplacingOccurrencesOfString:#"," withString:#"\\, "];
NSString *uuid = [[NSUUID UUID] UUIDString];
[erg appendString:[NSString stringWithFormat:#"BEGIN:VEVENT\nUID:%#\n", uuid]];
[erg appendString:[NSString stringWithFormat:#"DTSTART:%#T%#Z\n",[self nurTagFromDate:this.anfang], [self nurUhrzeigFromDate:this.anfang]]];
[erg appendString:[NSString stringWithFormat:#"DTEND:%#T%#Z\n",[self nurTagFromDate:this.ende], [self nurUhrzeigFromDate:this.ende]]];
[erg appendString:[NSString stringWithFormat:#"LAST-MODIFIED:%#T%#Z\nSEQUENCE:0\nSTATUS:CONFIRMED\n", [self nurTagFromDate:aktDatum], [self nurUhrzeigFromDate:aktDatum]]];
[erg appendString:[NSString stringWithFormat:#"SUMMARY:%#\nDESCRIPTION:%#\nLOCATION:%#\nEND:VEVENT\n", titel, dozent, this.raum]];
}
[erg appendString:#"END:VCALENDER"];
NSData *ret = [erg dataUsingEncoding:NSUTF8StringEncoding];
return ret;
}
In the getFileUrl I want to return a URL to the file created in there. This function calls the getICSData function that goes through my array (_daten) and creates for every Stunde object this ics-"code".
For help I have these NSDate formatting functions:
-(NSString*)nurTagFromDate:(NSDate*)date
{
NSDateFormatter *nurTag = [[NSDateFormatter alloc] init];
[nurTag setDateFormat:#"yyyyMMdd"];
return [nurTag stringFromDate:date];
}
-(NSString*)nurUhrzeigFromDate:(NSDate*)date
{
NSDateFormatter *nurTag = [[NSDateFormatter alloc] init];
[nurTag setDateFormat:#"HHmmss"];
return [nurTag stringFromDate:date];
}
As output I get something like this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//www.htw-dresden.de//iOS//DE
METHOD:PUBLISH
BEGIN:VEVENT
UID:CCCAC9B3-E056-47E3-A63B-F2FE2C3BA454
DTSTART:20140318T111000Z
DTEND:20140318T124000Z
LAST-MODIFIED:20140429T182723Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Internet-Technologien I
DESCRIPTION:Vogt\, J.
LOCATION:Z 254
END:VEVENT
.
.
.
END:VCALENDER
But the calendar app at my Mac don't want to open the file...
It would be great if some of you will have an Idea :)
Replace this line:
[erg appendString:#"END:VCALENDER"];
With this:
[erg appendString:#"END:VCALENDAR"];
Notice the typo in VCALENDAR.
You may find this iCal file validator useful.

Sort NSDictionaries in NSMutableArray by NSDate

I have a NSMutableArray with dictionaries, all of the dict's contain a NSDate is form of NSString with key 'Date'. I want to sort the NSDictionaries by the Dates. So for example i have the following state of the array:
Dict
Date
20.06.1996 23:30
Dict
Date
04.10.2011 19:00
Dict
Date
20.06.1956 23:39
And I want to sort it, so that it looks like this:
Dict
Date
20.06.1956 23:39
Dict
Date
20.06.1996 23:30
Dict
Date
04.10.2011 19:00
I have already experimented with NSSortDescriptor, but without success...
Update:
I have managed to sort the dates, but I came to this problem: In the dicts there is not only dates, also other objects, and what my code does is it only switches the date values between the dicts, instead of switching the complete dicts around. With this, the other values in the dicts get assigned a wrong date, which is very bad. Can anybody help me? Heres my code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"savedData.daf"];
NSMutableArray *d = [NSMutableArray arrayWithContentsOfFile:path];
for (int ii = 0; ii < [d count]; ii++) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
if (is24h) {
[dateFormatter setDateFormat:#"dd.MM.yyyy HH:mm"];
}
else {
[dateFormatter setDateFormat:#"dd.MM.yyyy hh:mm a"];
}
[dateFormatter setLocale:[NSLocale currentLocale]];
NSDate *dat = [dateFormatter dateFromString:[[d valueForKey:#"Date"] objectAtIndex:ii]];
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
NSDictionary *oldDict = (NSDictionary *)[d objectAtIndex:ii];
[newDict addEntriesFromDictionary:oldDict];
[newDict setObject:dat forKey:#"Date"];
[d replaceObjectAtIndex:ii withObject:newDict];
[newDict release];
}
NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:#"Date" ascending:YES];
NSArray *sorters = [[NSArray alloc] initWithObjects:sorter, nil];
[sorter release];
NSMutableArray *sorted = [NSMutableArray arrayWithArray:[d sortedArrayUsingDescriptors:sorters]];
[sorters release];
NSLog(#"%#",sorted);
for (int ii = 0; ii < [sorted count]; ii++) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
if (is24h) {
[dateFormatter setDateFormat:#"dd.MM.yyyy HH:mm"];
}
else {
[dateFormatter setDateFormat:#"dd.MM.yyyy hh:mm a"];
}
[dateFormatter setLocale:[NSLocale currentLocale]];
NSString *sr = [dateFormatter stringFromDate:[[sorted valueForKey:#"Date"] objectAtIndex:ii]];
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
NSDictionary *oldDict = (NSDictionary *)[d objectAtIndex:ii];
[newDict addEntriesFromDictionary:oldDict];
[newDict setObject:sr forKey:#"Date"];
[sorted replaceObjectAtIndex:ii withObject:newDict];
[newDict release];
}
NSLog(#"before: %#"
""
"after: %#",d,sorted);
[sorted writeToFile:path atomically:YES];
There are many ways to do this, one would be to use NSDate objects instead of NSStrings (or NSStrings formatted according to ISO 8601, so that the lexicographic sort would match the desired sorting). Then you could do:
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"Date"
ascending:YES];
[array sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];
Or, if you can't (or don't want to) change your data, you can always sort using a block:
[array sortUsingComparator:^(id dict1, id dict2) {
NSDate *date1 = // create NSDate from dict1's Date;
NSDate *date2 = // create NSDate from dict2's Date;
return [date1 compare:date2];
}];
Of course this would probably be slower than the first approach since you'll usually end up creating more than n NSDate objects.
There are a couple of options, one is to put NSDate objects in the dictionary.
One problem with comparing the strings is that you can 't just do a string compare because the year is not in the most significant potion of the string.
So, you will need to write a comparison method to use with:
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr
or perhaps:
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context
The comparator will need to handle the dd.mm.yyyy hh:mm string format.
Other options include adding another dictionary key with an NSDate representation and sorting on that.

Saving selected date and time into a plist

I would like to know how to save a selected date and time from a date picker into a plist.
NSMutableArray *userArray = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
NSMutableDictionary *dict = [userArray objectAtIndex:0];
NSDate *date = [NSDate date];
NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init];
[dateformatter setDateFormat:#"MM/dd/yyy hh:mm a"];
[dict setObject:[dateformatter stringFromDate:date] forKey:#"LastLocalDataUpdate"];
[userArray writeToFile:plistPath atomically:YES];
NSUserDefaults is good enough for what you're trying to do:
NSDate *theDate = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:theDate forKey:#"Date"];
NSUserDefaults will do it just nicely.

Cocoa/Obj-C - Dateformat change

I got an application wich read XML file and extract data of the nodes and put the data into textfields.
One of the node is <date>20110305162831</date>
In my textfield I got: 20110305162831
Whish is not very understandable for enduser...
How can i format it like:
2011/03/05 16:28:31
Is it possible?
Here is my AppControler.m code:
NSMutableArray* dates = [[NSMutableArray alloc] initWithCapacity:10];
NSXMLElement* root = [doc rootElement];
NSXMLElement* root = [doc rootElement];
NSArray* dateArray = [root nodesForXPath:#"//Report/ReportCreationDate" error:nil];
for(NSXMLElement* xmlElement in dateArray)
[dates addObject:[xmlElement stringValue]];
NSString * date = [dates objectAtIndex:0];
[dateTextField setStringValue:date];
[doc release];
[dates release];
If someone can help me, it would be great!
Thanks in advance
Miskia
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"yyyyMMddHHmmss"];
NSDate* date = [dateFormatter dateFromString: #"20110305163031"];
[dateFormatter setDateFormat: #"yyyy/MM/dd HH:mm:ss"];
NSString* date_str = [dateFormatter stringFromDate: date];