Unix timestamp is not getting converted correctly to NSDate - objective-c

I have parsed an api which returns a unixtimestamp for last updated value. I am trying to convert it into NSDate. The code is below
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[[[feedCount objectAtIndex:i] objectForKey:#"firstitemmsec"] intValue]];
NSLog(#"%#", date);
When I NSLog the date, I am getting date like this:
2038-01-19 03:14:07 +0000
The above date is obviously wrong
What is the mistake in the above code?
EDIT: my unixtimestamp is
"firstitemmsec":"1264396813500"
This value is obviously bigger for int. So how best can I handle this situation

Unix timestamps are in seconds, the value you have looks like a number of milliseconds since 1st January 1970. If you divide by 1000, you get 1264396813, which according to this converter is:
Mon, 25 Jan 2010 05:20:13 GMT

Check the value of [[[feedCount objectAtIndex:i] objectForKey:#"firstitemmsec"] intValue]--odds seem good that it's not a valid UNIX timestamp (okay, it is since any int value is on iOS, but obviously it's not the right value.)

I think there's another to do. Erase the "500" at the end of your number wich is an error code from the server and you have a right unix time ;)
There was probably an error or a bug on your server... ???

Related

Formatting NSDate

I am having some trouble comparing NSDate as they have a different format.
From one side I have a NSDate who looks like this:
2013-12-05T10:12:00.120Z
And from the other side I have another NSDate that looks this way:
2013-12-01 10:1200 +00000
My question is, how could I make the first NSDate look like the 2nd one?
And more important, what does 120Z mean? I guess it's the timezone, but I am not really sure of it.
By the way, is it there any way to can format the NSDate's and updating the time respecting the timezone hour difference?
Thanks a lot!
EDITED:
To get the 1st NSDate I do the following (I need to get the last opened date of a file):
MDItemRef item = MDItemCreate(NULL, (__bridge CFStringRef)filePath);
NSDate *date = (NSDate*)CFBridgingRelease(MDItemCopyAttribute(item,
kMDItemLastUsedDate));
And to get the 2nd NSDate I do the following:
NSDate* threeDaysAgo = [NSDate dateWithTimeIntervalSinceNow:-259200];
Convert both the dateStrings to NSDate and then you can easily compare the dateObjects.
For converting string to date thing you need :
NSDateFormatter
For comparing two dates :
resultant = [dateOne compare:dateTwo]
resultant can be NSOrderedAscending or NSOrderedSame or NSOrderedDescending.
You have a misunderstanding of what an NSDate is. It is not "in a format" at all, but is actually a wrapper around a a double which is the number of seconds since Jan 1st 1970 12:00am UTC. You can compare your two dates directly to see which one is the earlier. However, if you are trying to compare for equality, it's more tricky. If you want to see if they are within one minute of each other, you can do something like
[date1 timeIntervalSinceDate: date2] < 60.0;

How To Get Time Since Like 1972 in Objective-C

I know in python that you can get the time in milliseconds since 1972 or some time around there. I wanted to know if there was a similar feature in Objective-C or if I need to make something to calculate it.
Well, there's [[NSDate date] timeIntervalSince1970], which give the time (in seconds) since midnight on January 1, 1970.
[NSDate date] returns the current time; you can get the seconds-since-epoch relative to any time that you have an NSDate object for.
From the sound of it, you don’t care about the particular start date, just an elapsed-time number you can get milliseconds from. CFAbsoluteTimeGetCurrent() will give you a double-precision value for the current system time.
If it doesn't have to be Objective-C:
long timeSinceEpoch = time(NULL);

CalEvent with IsAllDay=TRUE gets me in trouble with timezone

I have a TimeZone problem with allday events in CalCalendar:
- (BOOL)setDayType:(NSString *)type
forDay:(NSDate *)date;
{
NSError *err = nil;
CalEvent *e = [CalEvent event];
[e setTitle:type];
[e setIsAllDay:YES];
[e setStartDate:date];
[e setEndDate:[date dateByAddingTimeInterval:1]];
[e setCalendar:[self calendar]];
if ( ![[CalCalendarStore defaultCalendarStore] saveEvent:e span:CalSpanThisEvent error:&err] )
{
...
Let's say I set the date at January 2nd, 2012, with a time of 00:00:00. I am at GMT+2, so timezone +0200. My date object reports 1-1-2012, 22:00:00, at GMT, as per this NSLog output:
"Set daytype ptd on 2012-01-01 22:00:00 +0000"
and also generates the allday even on January 1st!!
How can I make sure that I set the allday event in the correct day, for all timezones? I could easily add three hours but that will not work worldwide!
As long as date is on the correct day in the current time zone, you can use it as-in.
The "problem" that you see is caused because if you print the stored date via NSLog (or in the debugger) it will always show you GMT time because NSDate has no knowledge of which timezone that you are in.
However, since date is a specific point in time, when you format it for the user (using a date formatter), it will show the correct date and time, no matter what the time zone is, as long as it stays consistent.
The only situation where you will need to worry about adding/subtracting time like you mention is if you need a point in time which is the same date across multiple time zone's.
EDIT:
So it looks like iCal uses GMT time to store everything, so you need to create your date in the GMT timezone. If you need help with this, post your code where you create your NSDate and I'll be happy to point you in the right direction.

nil result from NSDateFormatter with 0's in format string

I'm getting a date from a webservice back in the form MM00yyyy -- it is just the two-digit month, followed by two 0's, and then the four-digit year. When I do this:
NSString *expDate = #"12001975";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM00yyyy"];
NSDate postDate = [dateFormat dateFromString:expDate];
[dateFormat dateFromString] returns nil for some reason. I have also tried MMddyyyy, and MM'0''0'yyyy, with no success either way. I am converting a similar date, except the 0's are actually the day with no problem using the same method.
To get this working, I would just use the following pattern MMHHyyyy. Since you need only the date and not neccessarily the hour, the HH will use the 00 to set the time as zeroth hour and hence you will get the date that you are looking for. Again this is just a hack and a workaround only to solve your current problem.
Have a look at the Date Formatting Guide from Apple. The section "Use Format Strings to Specify Custom Formats" lists all the different standards the are supported by various iOS versions for specifying a format string. I would say that "00" is not allowed, so that is the reason why "MM00yyyy" is failing. Similarly, "MMddyyyy" is also failing because no day can be "00".
I don't know if you can have more luck with UNIX functions, as the Apple doc suggests:
For date and times in a fixed, unlocalized format, that are always guaranteed to use the same calendar, it may sometimes be easier and more efficient to use the standard C library functions strptime_l and strftime_l.
Be aware that the C library also has the idea of a current locale. To guarantee a fixed date format, you should pass NULL as the loc parameter of these routines. This causes them to use the POSIX locale (also known as the C locale), which is equivalent to Cocoa's en_US_POSIX locale, as illustrated in this example.
struct tm sometime;
const char *formatString = "%Y-%m-%d %H:%M:%S %z";
(void) strptime_l("2005-07-01 12:00:00 -0700", formatString, &sometime, NULL);
NSLog(#"NSDate is %#", [NSDate dateWithTimeIntervalSince1970: mktime(&sometime)]);
// Output: NSDate is 2005-07-01 12:00:00 -0700
Getting the format strings right seems much more like art than science. I suggest you make a new string without the 00 in it and then have your DateFromatter process that with "MMyyyy".
While this might not be the "correct" way to do it, it should solve your problem pretty quickly.
The zeros are unsupported symbols. Apple supports the following characters for date formatting: http://unicode.org/reports/tr35/tr35-10.html#Date_Format_Patterns See the day section.

Converting JSON date(ticks) to NSDate

Does anyone know how to convert a JSON date(ticks) to an NSDate in Objective-C? Can someone post some code?
I'm guessing here but your JSON value is the number of milliseconds since 1970, right? You can use NSDate's dateWithTimeIntervalSince1970: method to return an NSDate object with the correct time. Just make sure to convert the JSON milliseconds number to seconds before passing it to NSDate-- Cocoa uses NSTimeInterval in most places, which represents an interval in seconds.
It goes roughly like this:
// Input string is something like: "/Date(1292851800000+0100)/" where
// 1292851800000 is milliseconds since 1970 and +0100 is the timezone
NSString *inputString = [item objectForKey:#"DateTimeSession"];
// This will tell number of seconds to add according to your default timezone
// Note: if you don't care about timezone changes, just delete/comment it out
NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
// A range of NSMakeRange(6, 10) will generate "1292851800" from "/Date(1292851800000+0100)/"
// as in example above. We crop additional three zeros, because "dateWithTimeIntervalSince1970:"
// wants seconds, not milliseconds; since 1 second is equal to 1000 milliseconds, this will work.
// Note: if you don't care about timezone changes, just chop out "dateByAddingTimeInterval:offset" part
NSDate *date = [[NSDate dateWithTimeIntervalSince1970:
[[inputString substringWithRange:NSMakeRange(6, 10)] intValue]]
dateByAddingTimeInterval:offset];
(from https://gist.github.com/726910)
You'd have to detect the client's locale in order to be able to do that, and unless your client knows how to do that, there's probably not much point.
NSDate's descriptionWithLocale: would be the way you format it for another locale. And timeIntervalSince1970 will go back to the (seconds) since 1970, which you could multiply by 1000 to get ms to return to the client. It's all in the NSDate documentation.
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
According to this page: http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx ticks begin on Jan 1, 0001 so dateWithTimeIntervalSince1970: is not automatically setup to work with ticks. You can still use this method but should adjust for the difference.