NSDateFormatter ISO8601 NSString do NSdate conversion - nsdate

i have a problem to convert string date (maybe ISO 8601) to NSDate..
NSString *testDate = #"2016-01-27T18:28:53.344+01:00";
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.sssZZZZZ"];
NSLog(#"_date_: %#",[formatter dateFromString:testDate]);
NSLog(#"_now_date: %#",[formatter stringFromDate:[NSDate date]]);
NSLog return:
_date_:(null)
_now_date: 2016-02-03T22:36:46.046+01:00
What is the right time format ? if log current date the format maybe appear correct but i can't get NSDate from string

You have fractional second in your date string. Fractional seconds are designated capital S. Try this:
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"]
Note that the NSDate you get back is 2016-01-27 17:28:53.344 +0000. This is due to NSDate always represent time in UTC. 17:38 UTC is the same moment in time as 18:38 +01:00.

Related

What format is a Date in CoreData - Date or String?

I have a routine that compares when a record was last updated on a website with the same record saved in CoreData on an iPad. Here, obsLastUpdated is a field in CoreData set as type Date.
Reading the data from CoreData into an NSDate:
NSDate *iPadDate = [[self.recordDetails objectAtIndex:0] obsLastUpdated]; //gets the date from CoreData
I get this warning:
Incompatible pointer types initializing 'NSDate *' with an expression
of type 'NSString *'
It is just a warning however and everything still works. If I try and compare this NSDate iPadDate with another NSDate there are no errors and everything works. But I would like to get to the bottom of the warning.
If I read from CoreData as a string and convert to an NSDate I can't seem to get the formatting correct and the app crashes. I have tried:
NSString *iPadDateStr = [[self.recordDetails objectAtIndex:0] obsLastUpdated];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *iPadDate = [dateFormat dateFromString: iPadDateStr];
I realise that CoreData does not store the date as an NSDate but how exactly is it stored and how do I get around the warning?
CoreData Entity:
UPDATE:
The error was in the class where obsLastUpdated was declared as an NSString. Changed to NSDate and all is well.
Simply define it as NSDate, not NSString:
MyEntity *entity = [self.recordDetails first];
NSDate *iPadDate = entity.obsLastUpdated;

Questions about categories

I want to do is produce a simple NSDate date in addition to would like
to add methods to add and subtract.
Date * myDate = [NSDate date]; // today
NSLog ("10 days after:%#", [myDate addToDays: 10]);
================= category ==================
#implementation NSDate (AddDate)
- (NSDate *)addToDays:addToDays{
NSDate *returnDate = [***HowGetmyDate*** dateByAddingTimeInterval:60*60*24*addToDays];
return returnDate;
}
how get (myDate)?
The base date need not necessarily today.
Just use self to get your date object.
Category is the extension of the original class, you can operate/implement it as the original one.
#implementation NSDate (AddDate)
- (NSDate *)addToDays:addToDays{
NSDate *returnDate = [self dateByAddingTimeInterval:60*60*24*addToDays];
return returnDate;
}

CoreData predicate by date

I have a coreData model already setup and data added to it. I want to search for all items from the last 30 days, and then add together a total number of units.
Here's what I got :-
- (void) calculateThirtyDayValues {
NSDate *endDate = [NSDate date];
NSTimeInterval timeSinceRefDate = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval lastThirtyDays = timeSinceRefDate- 2592000;
NSDate *startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:lastThirtyDays];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"(date >= %#) AND (date <= %#)", startDate, endDate];
}
Basically I have create an NSDate object set todays date, and then created another NSDate object set to 30 days before today. Then trying to predicate all objects from the start date until the present date.
I am getting results returned, but they don't seem to be really matching up with what the totals should be for the past 30 days. It appears to just be returning everything!
Any ideas?
Your predicate seems to be OK, but your date code is incorrect, for a couple of reasons.
[NSDate date] returns the current date, with sub-millisecond precision. So if you create the predicate at 4:15:37 PM local time, this predicate would not find any objects with a date of 5:37:42 PM local time. If you want down-to-the-second precision like that, then you're probably OK. But if you want granularity to a different calendar unit (such as by day), then you need to do more work.
Not every day has 86,400 seconds in it. Thus your attempt to subtract (30*86400) is subtly wrong. You should be letting the calendar object do the math for you:
NSDate *endDate = ...;
NSDateComponents *diff = [[NSDateComponents alloc] init];
[diff setDay:-30];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *startDate = [calendar dateByAddingComponents:diff toDate:endDate options:0];

Converting NSString date with 1 time zone to an NSDate object with another time zone

Hey everyone,
I need to convert the following format into a new format using NSDateFormatter. I am quite seasoned with this but for some reason I can't remember the correct formatting information for this foramt:
'Fri, 25 Mar 2011 10:16:00 -0700'.
I tried using this format:'aaa, dd bbb YYYY HH:MM:SS ZHHMM' but it doesn't work, gives me a date way in the past.
I also need to convert it into the Eastern Time Zone when creating a new date. It says '+0000' but what is that normalized to?
Any help appreciated,
Thanks,
~Arash
Typically when you're getting date strings like that, you know what locale they're coming from, and you would take an NSDateFormatter, set its locale using setLocale:, set its date and time formatting using setDateStyle: and setTimeStyle: and then use dateFromString:. If you can't do that because you don't know the locale, then you can use the UNIX functions:
struct tm sometime;
const char *formatString = "%a, %d %b %Y %T %z";
strptime_l("Fri, 25 Mar 2011 10:16:00 -0700", formatString, &sometime, NULL);
NSDate *newDate = [NSDate dateWithTimeIntervalSince1970: mktime(&sometime)];
Next, you want to "convert" newDate to Eastern Time. I say "convert" because NSDates don't contain any information about timezones—they're just represented as a number of seconds since January 1, 2001—so the idea of conversion makes no sense. When you print out an NSDate you get it in UTC (+0000), but an NSDate is no more associated with that timezone than with any other.
What you want to do instead is to create a dateFormatter with the right timezone and use it to output the date:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_UK"]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EST"]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLog(#"%#",[dateFormatter stringFromDate:newDate]);
// Outputs 25 Mar 2011 13:16

Get Date Parts from a NSDate value

I'm using a UIDatePicker and I'm having problems with converting this data to a System.DateTime value in MonoTouch. There are problems with conversions from NSDate to DateTime, which I've mostly solved, but now I see that if you choose a date that is NOT in the same Daylight Savings Time period then you are an hour off. For example, if I pick a date in January 2010 I'll have an offset issue.
What I'd like to do is when a user selects a date/time from the UIDatePicker is to get the Year, Month, Day, Hour, and Minute values of the NSDate and just create a New System.DateTime with those values and I'll always be assured to get a date value exactly as the user see's it in the UIDatePicker.
How can I break down a NSDate value into the various date parts?
Thank you.
An easy way to get rid of the daylight saving time problems is to set the time zone to GMT. Then the UIDatePicker will ignore daylight saving time:
_datePicker.TimeZone = NSTimeZone.FromAbbreviation("GMT");
Implicit conversion of NSDate to and from DateTime is quite good in Monotouch, but you must be aware that NSDate is always an UTC time and DateTime is default set to DateTimeKind.Unspecified (when read from database) or DateTimeKind.Locale (when set with DateTime.Today).
The best way to convert without complicated time-zone computations is to force the right DateTimeKind:
// Set date to the date picker (_date is a DateTime with time part 0:00:00):
_datePicker.Date = DateTime.SpecifyKind(_date, DateTimeKind.Utc);
// Get the date from the date picker:
_date = DateTime.SpecifyKind(_datePicker.Date, DateTimeKind.Unspecified);
This is easier and more reliable than getting the individual Day, Month and Year values.
It appears this can be done using an instance of NSDateComponents. The following has been copied from Date Components and Calendar Units:
To decompose a date into constituent
components, you use the NSCalendar
method components:fromDate:. In
addition to the date itself, you need
to specify the components to be
returned in the NSDateComponents
object. For this, the method takes a
bit mask composed of Calendar Units
constants. There is no need to specify
any more components than those in
which you are interested. Listing 3
shows how to calculate today’s day and
weekday.
Listing 3 Getting a date’s components
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];
NSInteger weekday = [weekdayComponents weekday];
public static DateTime NSDateToDateTime(MonoTouch.Foundation.NSDate date)
{
return (new DateTime(2001,1,1,0,0,0)).AddSeconds(date.SecondsSinceReferenceDate);
}
public static MonoTouch.Foundation.NSDate DateTimeToNSDate(DateTime date)
{
return MonoTouch.Foundation.NSDate.FromTimeIntervalSinceReferenceDate((date-(new DateTime(2001,1,1,0,0,0))).TotalSeconds);
}
Ok by using the above code you can turn the NSDate into a DateTime an do as you normally do on .Net World :) then with > DateTimeToNSDate you can revert it to a NSDate
hope this helps
Alex

Resources