BlaBla BlaBla - 11 days ago 6
iOS Question

iOS - Moon Calculation for Moonrise and Moonset

I'm trying to translate a library written in Javascript in order to implement it in Objective C for my iOS application.

The link to the JavaScript library : https://github.com/mourner/suncalc

I got different values for Moonrise and Moonset.

The Javascript library returns :

moonrise = Mon Nov 28 2016 06:43:49 GMT+0100 (CET)
moonset = Mon Nov 28 2016 17:10:33 GMT+0100 (CET)


My Objective C implementation returns :

moonrise : 2016-11-28 02:00:00 +0000
moonset : 2016-11-28 01:00:00 +0000


I'm facing an issue with this functions :

// date/time constants and conversions

var dayMs = 1000 * 60 * 60 * 24,
J1970 = 2440588,
J2000 = 2451545;

function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }

function toDays(date) { return toJulian(date) - J2000; }

function hoursLater(date, h) {
return new Date(date.valueOf() + h * dayMs / 24);
}


My Objective C implementation :

// date/time constants and conversions

#define dayMS 1000 * 60 * 60 * 24
#define J1970 2440588
#define J2000 2451545

-(double)toJulian:(NSDate *) date
{
return ([date timeIntervalSince1970] * 1000) / dayMS - 0.5 + J1970;
}

-(double)toDays:(NSDate *) date
{
double tj = [self toJulian:date];

return tj - J2000;
}

-(NSDate *)hoursLater:(NSDate *) date :(int) h
{
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate * newDate = [calendar dateByAddingUnit:NSCalendarUnitHour value:h toDate:date options:0];

return newDate;
}


I can't see any mistakes, but my values are false.

Test Example :

Javascript Test

var date = new Date();
var d = toDays(date);
console.log("d = " + d);


d = 6175.947204432916

Objective C Test

NSDate *today = [NSDate date];
double d = [self toDays:today];
NSLog(@"d = %f", d);


d = 127900386826537.265625

If you find something, please let me know.

Answer

The issue is on the #define definition.

#define dayMS 1000 * 60 * 60 * 24
#define J1970 2440588
#define J2000 2451545

-(double)toJulian:(NSDate *) date
{
    return ([date timeIntervalSince1970] * 1000) / dayMS - 0.5 + J1970;
}

This is translated with:

-(double)toJulian:(NSDate *) date
{
    return ([date timeIntervalSince1970] * 1000) / 1000 * 60 * 60 * 24 - 0.5 + 2440588;
}

It simply replace exactly the values. But ([date timeIntervalSince1970] * 1000) / 1000 * 60 * 60 * 24 is different of ([date timeIntervalSince1970] * 1000) / (1000 * 60 * 60 * 24).

A quick solution:

return ([date timeIntervalSince1970] * 1000) / (dayMS) - 0.5 + J1970;`

Or you can put the parenthesis in the #define:

#define dayMS (1000 * 60 * 60 * 24)

Another solution (I don't really like #define) and you don't need the parenthesis anymore:

const double dayMS = 1000 * 60 * 60 * 24;