Converting JSON date(ticks) to NSDate - objective-c

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.

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 do I count time in iOS?

I don't want to set up a timer that "fires" (and does something) after a certain amount of time has passed.
Therefore, I'm not interested in the NSTimer class and its methods.
All I'm interested in is counting the time that passes by while, for example, some while-loop is executing. I could use NSDate as follows I guess :
NSDate currentDate = [[NSDate alloc] init];
while(someConditionIsTrue)
{
// executing..
}
timeElapsed = [self timeIntervalSinceDate:currentDate];
NSLog(#"time elapsed was: %i", timeElapsed);
However, if I understand correctly, timeIntervalSinceDate: can only count seconds.
Is there a way I can count the time that is passing by in milliseconds?
In other words, what is the smallest unit I can count passing time in and how ?
Look at CFAbsoluteTimeGetCurrent()
CFAbsoluteTime before = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime after = CFAbsoluteTimeGetCurrent();
Your second approach is correct. Save the current date in an NSDate object and use timeIntervalSinceDate: to get the passed time since then. The result will be of type NSTimeInterval which is a floating point number. It specifies time differences in seconds, but since it's a floating point number it can store fractions of a second as well.
NSTimeInterval is always specified in seconds; it yields
sub-millisecond precision over a range of 10,000 years.

Calculating time 90 minutes prior to due date/time in Objective C (iPhone app)

This is a completely noobish question, but I spent 2 hours yesterday trying to make it work, and I'm obviously missing something very basic.
What I need to do is take input from user of date/time and count back 90 minutes for an alert.
Could someone please post an example calculation, where you have a var that holds user input and a new var that receives the result of this computation? (all done in Objective C for use in an iPhone app) Thank you!
I suspect you could do something like:
NSDate *alertDate = [userDate dateByAddingTimeInterval:-5400.0];
I think this should work:
NSDate * alarmDate = [NSDate dateWithTimeInterval:5400 sinceDate:userDefinedDate];
NSDate * now = [NSDate date];
NSTimeInterval wait = [now timeIntervalSinceDate:alarmDate];
[self performSelector:#selector(callAlarm) withObject:nil afterDelay:fabs(wait)];
Although I do agree with Nick too, adding your work its much more productive..
Assuming you have a UIDatePicker, your target date will already be in an NSDate object. If it's coming from another source, you're probably ending up with it in an NSDate object, either from a string via an NSDateFormatter or by some other means.
From an NSDate object, you can get an NSTimeInterval relative to some absolute date. That's a C primitive type (it's a double in practice, but obviously don't code to depend on that) that you can do arithmetic directly on. So you can subtract 90 minutes directly from that. There are then various + dateWithTimeInterval... class methods on NSDate that will allow you to get a date from the result.

JSON date to NSDate and back

I have a JSON date, e.g: 1295804021525, which is the number of milliseconds from 1970.
I have written the following code to convert this number into an NSDate:
long long seconds = [[payload valueForKey:#"starttime"]longLongValue]/1000;
NSDate *somedate = [NSDate dateWithTimeIntervalSince1970:seconds];
Which does work and returns the correct date. First I'm wondering if this is the best way of doing the conversion.
Next I am wondering how to convert back to the milliseconds format and then put into the url to send back to the server.
I have:
long long date = [somedate timeIntervalSince1970] * 1000;
NSString *urlString = [NSString stringWithFormat:#"http://someurl?since=%qi",date];
Again this seems to work but I was wondering how I could get the same functionality using NSNumber.
With your original conversion, you're losing sub-second precision. You may want to do something like
CFTimeInterval seconds = [[payload valueForKey:#"starttime"] doubleValue] / 1000.0;
The second snippet should be fine.
I'm not sure why you think using NSNumber would help in any fashion. With the modification I mentioned, both these code snippets are straightforward and should work just fine.

NSString to NSDate with float values

I'm developing an OS X desktop application which will track time for a car racing event.
The difference between pilots can be very small, so the collected data for each lap has a floating point value for the seconds:
bestLap = #"00:01:39.5930000"
But I need to compare each pilot's time and sort it. I'm trying to convert it to a NSDate object, using NSDateFormatter and I couldn't manage to make it work
Is it possible to convert a string like that to a NSDate? If so, how can I compare and sort an array containing NSDates
Thanks
An NSDate is used to represent a date, not a time interval.
Also, if the purpose is just to sort them, there is no need to convert the string into an NSDate or NSTimeInterval since they are already lexicographically ordered if a time interval is shorter than the other in your format.
That means, calling -sortUsingSelector: is enough.
[theMutableArrayOfLaps sortUsingSelector:#selector(compare:)];
As KennyTM says, lexicographic sorting is enough if all you need is ordering. If you really want to get a numeric value for comparison & reporting purposes, you can break the string up into components and convert to a double something like this:
NSArray* parts = [bestLap componentsSeparatedByString:#":"];
double bestLapInSeconds = [[parts objectAtIndex:0] doubleValue] * 3600 // hours
+ [[parts objectAtIndex:1] doubleValue] * 60 // minutes
+ [[parts objectAtIndex:2] doubleValue]; // seconds
(Note that this just blithely assumes that the original string conforms to an "H:M:S" format without any error checking. You should not normally do this in real life!)