You have most of the pieces here already.
UPDATED
The proper coordinates
In this problem, we want to get the positions of astronomical objects in terms of a Cartesian system that is geocentric and rotates with the Earth. In astronomy, the positions of objects are commonly given in terms of right ascension (RA) and declination (Dec), which are similar to longitude and latitude projected onto the sky, but do not rotate with the Earth. Because of this similarity RA and Dec are natural coordinates to start with: it is simple to take the RA and Dec and then boost them into a frame that rotates with the Earth. One can then make a simple transformation from spherical into Cartesian coordinates.
$$
(r, Dec, RA) \rightarrow (r, lat, long) \rightarrow (x, y, x)
$$
Aside:
Because the Earth's axis moves slowly with respect the distant stars (precession and nutation etc.), there is some ambiguity as to whether RA and Dec should move with the Earth or remain fixed. As detailed at length in this question, the various astronomical Data functions when applied to the Sun, the Moon, the planets, and the other planetary moons supply precessing (true geocentric) right ascension and declination. But, for stars besides the Sun, StarData provides a non-precessing (fixed) RA and Dec. All appear to be accurate up to about a degree or RA and less than a degree of Dec. I haven't checked yet what the other astronomical Data functions do, so I will restrict this answer to the Sun, the Moon, and planets. It should be sufficiently easy to generalize.
Conversion into Earth-rotating coordinates
To convert from geocentric, precessing RA into a coordinate in an Earth-rotating reference frame, we calculate the local hour angle as
$$
LHA(long,t) = LST(long,t) - RA(t)
$$
Here, $LST$ is the local sidereal time. Since we are interested in the position of the Sun or Moon with respect to Earth longitude and latitude, we pick our earth position to be $(lat, long) = (0, 0)$. Conveniently, the local sidereal time, on the prime meridian is Greenwich sidereal time (GST, closely related to GMT), so a "longitude-type" angle (only "longitude-type", because we don't need to require this angle to only run between -180 degrees and 180 degrees) for the moon or sun is given as
$$
LHA(0,t) = 360^\circ - \left( GST(t) - RA(t) \right)
$$
(the 360 degrees converts the angle from westward-directed to eastward-directed, so that we can get a right-handed coordinate system, with the x-axis sticking out from the equator-prime meridian point, the y-axis going off through the equator at 90 degrees, and the z-axis along up the axis of rotation)
Mathematica implementation
We can put this into Mathematica now fairly easily:
Sun position
SunPositionXYZ[date_] := With[
{date0 = TimeZoneConvert[date, 0], pos0 = GeoPosition[{0, 0}]},
Module[{pos, GST, r, lat, long},
pos = StarData["Sun",
{EntityProperty["Star", "RightAscension", {"Date" -> date0}],
EntityProperty["Star", "Declination", {"Date" -> date0}]}];
pos = UnitConvert[pos, "Degrees"];
GST = UnitConvert[SiderealTime[pos0, date0], "Degrees"];
r = PlanetData["Earth",
EntityProperty["Planet", "DistanceFromSun", {"Date" -> date0}]];
long = Quantity[360, "Degrees"] - (GST - pos[[1]]);
lat = pos[[2]];
<|
x -> r Cos[lat] Cos[long],
y -> r Cos[lat] Sin[long],
z -> r Sin[lat]
|>
]
]
Moon position
MoonPositionXYZ[date_] := With[
{date0 = TimeZoneConvert[date, 0], pos0 = GeoPosition[{0, 0}]},
Module[{pos, GST, r, lat, long},
pos = PlanetaryMoonData["Moon",
{EntityProperty["PlanetaryMoon", "RightAscension", {"Date" -> date0}],
EntityProperty["PlanetaryMoon", "Declination", {"Date" -> date0}]}];
pos = UnitConvert[pos, "Degrees"];
GST = UnitConvert[SiderealTime[pos0, date0], "Degrees"];
r = PlanetaryMoonData["Moon",
EntityProperty["PlanetaryMoon", "DistanceFromSun", {"Date" -> date0}]];
long = Quantity[360, "Degrees"] - (GST - pos[[1]]);
lat = pos[[2]];
<|
x -> r Cos[lat] Cos[long],
y -> r Cos[lat] Sin[long],
z -> r Sin[lat]
|>
]
]
Planet positions
PlanetPositionXYZ[planet_, date_] := With[
{date0 = TimeZoneConvert[date, 0], pos0 = GeoPosition[{0, 0}]},
Module[{pos, GST, r, lat, long},
pos = PlanetData[planet,
{EntityProperty["Planet", "RightAscension", {"Date" -> date0}],
EntityProperty["Planet", "Declination", {"Date" -> date0}]}];
pos = UnitConvert[pos, "Degrees"];
GST = UnitConvert[SiderealTime[pos0, date0], "Degrees"];
r = PlanetData[planet,
EntityProperty["Planet", "DistanceFromEarth", {"Date" -> date0}]];
long = Quantity[360, "Degrees"] - (GST - pos[[1]]);
lat = pos[[2]];
<|
x -> r Cos[lat] Cos[long],
y -> r Cos[lat] Sin[long],
z -> r Sin[lat]
|>
]
]
For moons, just make the substitution PlanetData -> PlanetaryMoonData and "Planet" -> "PlanetaryMoon".
Date and Time
Run these using DateObject to specify the time and date:
MoonPositionXYZ[DateObject[{2015, 4, 17, 10, 0, 0}, TimeZone -> -3]]
SunPositionXYZ[DateObject[{2015, 4, 17, 10, 0, 0}, TimeZone -> 10]]
PlanetPositionXYZ["Venus",
DateObject[{2015, 4, 17, 10, 0, 0}, TimeZone -> 5]]
(* -> <|x -> 0.857983 au, y -> -0.512016 au, z -> 0.0685721 au|>
<|x -> -0.9875 au, y -> -0.00628945 au, z -> 0.179209 au|>
<|x -> -0.824832 au, y -> 0.583867 au, z -> 0.431657 au|> *)
Mathematica should convert all of the DateObjects into some kind of universal date (probably Julian date) internally when they are passed to the various astronomical position functions, so as long as the date and time are uniquely specified, it shouldn't matter what timezone is used (note that Mathematica may use your timezone as default). That said, it is probably safest to specify the time and date fully (as above), rather than just using DateObject[TimeZone -> x], as this seems to give an unexpected date sometimes (see this question).
Other objects
For objects such as stars for which Mathematica gives non-precessing RA and Dec, we must first convert it to a precessing RA. Mathematica already does this, but the functionality is buried in the innards of the astronomical Data functions. I have not yet come up with a good way of doing the conversion.
SunPosition,MoonPositionandSiderealTime. By some experiment I think we need to pass aDateObjectwith an explicitTimeZone->0option. For some reason aDateObjectwithout the option or with a differentTimeZoneapparently is not handled properly, at least for the Moon. Can you confirm this? – unlikely Apr 17 '15 at 09:00SunPosition,MoonPosition, andSiderealTime. That is fixed now. The date should be insensitive to timezone (because we have specified all of the positions and Mathematica probably needs to convert it all into Julian date anyway when extracting position info), but it is safer to explicitly useTimeZone -> 0. For some reason, today, on 17 April, when I runDateObject[TimeZone -> #] & /@ {0, 3, 11, -23}, the first two results are for 17 April, the second for 19 April, and the last for 15 April...although all should be for 17. – Virgil Apr 17 '15 at 13:15TimeZoneworks (it runs from +12 to -12), on 17 April, runningDateObject[TimeZone -> -23]will give a date 24 hours earlier inTimeZone -> 1. – Virgil Apr 17 '15 at 13:44MoonPosition[DateObject[{2015, 03, 20, 9, 32, 09}, TimeZone -> 0], CelestialSystem -> "Equatorial"]and compare withMoonPosition[ DateObject[{2015, 03, 20, 10, 32, 09}, TimeZone -> 1], CelestialSystem -> "Equatorial"]? The results shouldn't be equal? – unlikely Apr 17 '15 at 14:26PlanetaryMoonData["Moon", EntityProperty["PlanetaryMoon", "RightAscension", {"Date" -> DateObject[{2015, 03, 20, 9, 32, 09}, TimeZone -> 0]}]]andPlanetaryMoonData["Moon", EntityProperty["PlanetaryMoon", "RightAscension", {"Date" -> DateObject[{2015, 03, 20, 10, 32, 09}, TimeZone -> 1]}]]do coincide, so it seems to be something inMoonPositionitself or it its interaction withDateObject. – Virgil Apr 17 '15 at 14:36TimeZonesother than 0, and I think that is becauseMoonPositionandSunPositionboth assume that you are usingGMTif you specifyCelestialSystem -> "Equatorial", and just completely ignore whateverTimeZoneyou put in yourDateObject(can you confirm this?). This is a little frustrating. However, it can be fixed withTimeZoneConvert– Virgil Apr 17 '15 at 14:56SunPositionapparently handle correctlyTimeZone, so I'm inclined to call this a bug if nobody is contrary. Maybe it's better to add aTimeZoneConvert[...,0]insideMoonPositionin our code to make the code more bug-proof :) – unlikely Apr 17 '15 at 15:03SunPosition. So it does seem that onlyMoonPositionis responding oddly. It is probably supposed to act like the others. – Virgil Apr 17 '15 at 15:06MoonPositionandPlanetaryMoonDatato compute the corrections $\delta$ to apply from Celestial to Geocentric coordinates, insteadSunPositionandStarData? UsingSunPositionI get different corrections! – unlikely Apr 20 '15 at 10:31MoonPositionandPlanetaryMoonDatabecause they were the first pair I thought of. I checked the separation betweenSunPositionandStarData, and found that it is very small (effectively zero) , so it seems thatCelestialSystem -> "Equatorial"means two different things forSunPositionand forMoonPosition. For the first, it seems to coincide the celestial coordinates and for the latter with something else (probably geocentric coordinates). This is worth investigating. – Virgil Apr 20 '15 at 19:42