Objective-C Library for Sunrise and Sunset? - iphone

Is there an Objective-C (or C) library (that is compatible with core location) that can tell me the time of sunrise and sunset for any given calendar day?

EDSunriseSet is an open source and free Objective-C wrapper for the C languages routines created by Paul Schlyter.
Calculation is done entirely by the C-code routines. EDSunrisetSet bridges those calculations to common Cocoa classes (NSDate, NSTimeZone, ...)

I've actually ported the KosherJava Library and plan to make it available soon on GitHub!
Edit:
KosherCocoa is now live on GitHub! If you don't need the hebrew calendar related code, you can delete the "calendar" file. The class files are separated nicely into folders based on the kinds of calculations that they do.
Edit: KosherCocoa us due to be replaced with a modern and more complete update as soon as I can. The above link now points at a legacy repo.

I have used a library called SUNWAIT. Very simple, effective - easy to use!

Try this: https://github.com/mourner/suncalc/
Very clear and easy to implement, although it writen by javascript but it is easy to convert it to
objective-C
It also support for calculate sun, moon position and coordinate.

After not finding a simple Swift alternative, I created Solar: a Swift built micro-library for Sunrise / Sunset.

Just a note.. if you use the Berkley one... well it doesn't work (in Australia as least).
It does include the Paul Schlyter C code though, which is great.
If you want it to work anywhere, best to just calc the dates in UTC.
In SunriseAndSunset.m, replace the code from
double rise;
double set;
as follows:
sun_rise_set(theYear, theMonth, theDay, lon, lat, &rise, &set);
int hours = HOURS(rise);
int mins = MINUTES(rise);
int sethrs = HOURS(set);
int setmins = MINUTES(set);
NSTimeInterval riseOffset = ((hours * 60) + mins) * 60;
NSTimeInterval setOffset = ((sethrs * 60) + setmins) * 60;
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSString *dateStr = [NSString stringWithFormat:#"%i-%02d-%02dT00:00:00+0000", theYear, theMonth, theDay];
NSDate *utcMidnight = [formatter dateFromString:dateStr];
NSDate *utcSunrise = [utcMidnight dateByAddingTimeInterval:riseOffset];
NSDate *utcSunset = [utcMidnight dateByAddingTimeInterval:setOffset];
[formatter release];
[gregorian release];
return [NSDictionary dictionaryWithObjectsAndKeys:utcSunrise, #"sunrise", utcSunset, #"sunset", nil];

try this one: https://github.com/berkley/ObjectiveCUtil

Related

Nslog timestamp

I want to nslog the device motion timestamp property .
The device motion is in the class CMMotionManager.devicemotion.timestamp
Any ideas.
Here the solution I put in place because the date is according to Apple documentation :
The time stamp is the amount of time in seconds since the phone booted.
I first save the originDate at the first mesure (if my NSDate is nil).
[self.motionManager startGyroUpdatesToQueue:self.queue withHandler:^(CMGyroData *gyroData, NSError *error) {
if (self.originDate == nil) {
self.originDate = [NSDate dateWithTimeIntervalSinceNow:-gyroData.timestamp];
}
}];
Then I can display when I want the real date like this :
[NSDate dateWithTimeInterval:mygyroData.timestamp sinceDate:self.originDate]
Don't forget to reset the originDate to nil if you need to restart some mesure.
Edit: Please see Nicolas Lauquin's answer. Per the comments, the following solution is not correct but is retained here for history (and because I can't delete it since it is currently marked accepted).
The timestamp property is an NSTimeInterval, so you should be able to do:
NSLog(#"Motion at time: %#",
[NSDate dateWithTimeIntervalSinceReferenceDate:devicemotion.timestamp]);
NSTimeInterval is just a typedef'd double type, so you could use %f instead of %# and log it directly.
Also, the docs don't indicate whether this timestamp is set against Apple's reference date or the standard *nix date, so you may need to use [NSDate dateWithTimeIntervalSince1970:] if the aforementioned method returns dates far in the future.
As #davidbitton has suggested the CMDeviceMotion's timestamp is relative to the last device boot, the correct NSDate could be derived by
NSDate *startupTime = [NSDate dateWithTimeIntervalSinceNow:
-1 * [[NSProcessInfo processInfo] systemUptime]];
NSDate *deviceMotionDate = [NSDate dateWithTimeInterval:devicemotion.timestamp
sinceDate:startupTime];
This should yield a roughly accurate NSDate object, assuming #davidbitton is correct. (reference: NSProcessInfo -systemUptime)
However, given how complicated this is, I would now suggest for simplicity that, given the nature of the timestamp property, that you log it in a format string as something like
"... event logged at %0.2f seconds since startup...", devicemotion.timestamp

how to store time in NSDate without date?

I have a timer in my app. When I click on exit buton then timer gets stop and stores value into the string in format of 01:15:55 . I have an array to store this string object.
What I want is , now I want to display these values by comparing to each other. So I think first I have to convert the string into the NSDate but I am having only time format and do not want to store date.
How can I accomplish this task ? any suggestion ?
EDITED : code
NSInteger secondsSinceStart = (NSInteger)[[NSDate date] timeIntervalSinceDate:sDate]; // sDate = when app get started
myAppDelegate.seconds = secondsSinceStart % 60;
myAppDelegate.minutes = (secondsSinceStart / 60) % 60;
myAppDelegate.hours = secondsSinceStart / (60 * 60);
NSString *result = nil;
if (myAppDelegate.hours > 0)
{
result = [NSString stringWithFormat:#"%02d:%02d:%02d", myAppDelegate.hours, myAppDelegate.minutes, myAppDelegate.seconds];
}
else
{
result = [NSString stringWithFormat:#"%02d:%02d", myAppDelegate.minutes, myAppDelegate.seconds];
}
NSString *tempDateString = [NSString stringWithFormat:#"%d:%d:%d",[myAppDelegate hours],[myAppDelegate minutes],[mogsApp seconds]];
Now I want to convert tempDateString into the NSDate so I can compare with similar objects. Is it possible ?
Thanks...
Sounds like an NSTimeInterval might be more appropriate. This is just a floating-point value indicating a number of seconds (including fractional seconds). You can manually format a value like this into whatever string format you want with some simple division and remainder math. (NSDate will give you time intervals since a reference date or other dates if you want to use those to get the values.) You can store NSTimeIntervals as strings if necessary.
NSDateComponents is always a good choice when storing only parts of a date/time (or a timespan).
It also gives you easy access to time management methods via NSCalendar. Then (unlike using NSTimeInterval), you don't have to set up any of the math yourself, and it will all automagically localize.

finding NSDate's in an NSArray that have a time of day after a given time (e.g. 8pm)?

Is there a quick way in Objective-C of identifying NSDate's in an NSArray that have a time of day after a given time (e.g. 8pm)?
I can't quite see anyway other than manually walking through each NSDate in the array and then using NSDateComponents to break out the hour/minute/second...Not even sure if there is a simple way to get the time from an NSDate in a fashion that represents a fraction of 24hours, as this might help a little. (e.g. 6pm would be 18/24 = 0.75 in this case)
There is no need to break in NSDateComponents.
NSTimeInterval interval = [date1 timeIntervalSinceDate:date2];
if (interval > 0) {
// date2 is earlier
} else {
// date1 is earlier
}
Now you can represent your target time(8 P.M., for example) with date2 and compare all dates of array with that.
Haven't tried this myself, but I guess
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate
is what you're looking for.

"Streaming" data: Keep parser open or continually create a new one?

I wanted to know what is more efficient for what I am doing:
I'm bringing in (very small - 4kb or less each) .xml files which contain GPS coordinates of a vehicle. I am then parsing them (very light parsing involved) and sending them back to the delegate.
Currently, I am using a a timer which every 1 second calls the following:
-(void)refreshGPSData:(NSTimer *)theTimer{
GPSParser *parser = [[GPSParser alloc] initWithName:#"route"];
[parser parseRssFeed:#"http://thefeed.com/feed.xml" withDelegate:self];
[parser release];
}
My question is, would it be more efficient to do this in a different way that isn't continuously alloc and initing the parser? Should I alloc+init only one parser and then call "parseRssFeed" every 1 second. Or should i not use a timer, but instead call "parseRssFeed" every time the parser finishes and returns data to the delegate? What is best programming practice?
Please let me know if i have provided enough information.
Thank you!
This depends how often you want to use the parser. If you only parse data once a minute there is no need to store a parser in an object.
If you parse the data 10 times a second you have to allocate once and store the parser.
As the other poster (who deleted his answer because this is not a .net question) suggested I made a little performance test to show that an alloc is a really slow operation.
for (NSTimeInterval i = 0; i < 1000; i++) {
self.label1.text = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSinceNow:i]];
}
vs
for (NSTimeInterval i = 0; i < 1000; i++) {
NSDateFormatter *localDateFormatter = [[NSDateFormatter alloc] init];
self.label2.text = [localDateFormatter stringFromDate:[NSDate dateWithTimeIntervalSinceNow:i]];
[localDateFormatter release];
}
gave a result of 0.0017 seconds for the first version, and 0.28 seconds for the second version. You'll get the idea. Yes, NSDateFormatter might be one of the more complex examples of an object.
If you want to use an object like a parser or a dateformatter often I would store it somewhere.

Best way to store a 'time' value

My class needs two properties: startTime and endTime. What is the best class to use? I know there is NSDate, but I only need to store a specific time (something in between 00:00-23:59), I don't need a date. What is the most elegant solution here?
NSTimeInterval is probably good enough for this.
It stores a time value in seconds as a double.
Eg. 5 mins = 300.0
I believe the most elegant solution, and what you want, is NSTimeInterval, that is the primitive type that NSDate is built on top.
NSTimeInterval is a typedef for double, and is a measurement of time in seconds. This primitive time type do not have any concept of a reference date. What NSDate do is to add this concept of reference date and anchor the 0.0 time at 1 January 2001 GMT. There is nothing that stops you from inventing your own reference date or anchor, like for example "midnight of whatever day there is".
What you can do is to add two properties of the NSTimeInterval either as startTime and endTime and let them both use midnight as the reference. Or you could skip endTime and go for a startTime and duration combo.
There's NSDateComponents, which "can also be used to specify a duration of time, for example, 5 hours and 16 minutes."
The NSDate class is similar to the DateTime class in C#: both hold a date and time, but they can be independent of each other. In Cocoa, you would compare two NSDate classes:
//Create NSDate objects in the time format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSString *startTimeString = #"00:00:00"; //0 seconds
NSString *endTimeString = #"00:00:52"; //52 seconds
NSDate *startTime = [dateFormatter dateFromString:startTimeString];
NSDate *endTime = [dateFormatter dateFromString:endTimeString];
//Compare the time
BOOL date1before2 = [startTime compare:endTime] == NSOrderedAscending;