As Sjoerd shows, AstronomicalData[]
can be used to determine the altitude of the sun. However, if you do not need too much accuracy, such as in this application, you can use a low-accuracy method for computing the altitude. Most of the formulae I will be using are from (of course) Jean Meeus's Astronomical Algorithms.
Some auxiliary routines will be needed. First, one for computing the Julian Day number:
Options[jd] = {"Calendar" -> "Gregorian"};
jd[{yr_Integer, mo_Integer, da_?NumericQ, rest___}, opts : OptionsPattern[]] :=
Module[{y = yr, m = mo, h}, If[m < 3, y--; m += 12];
h = Switch[OptionValue["Calendar"],
"Gregorian", (Quotient[#, 4] - # + 2) &[Quotient[y, 100]],
"Julian", 0,
_, Return[$Failed]];
Floor[365.25 y] + Floor[30.6001 (m + 1)] + da +
FromDMS[PadRight[{rest}, 3]]/24 + 1720994.5 + h]
jd[opts : OptionsPattern[]] := jd[DateList[], opts]
Here's a method for computing the Greenwich Mean Sidereal Time:
GMST[{yr_Integer, mo_Integer, da_?NumericQ, rest___}, opts : OptionsPattern[]] :=
Mod[6.697374558 + 0.06570982441908 (jd[{yr, mo, da}, opts] - 2.451545*^6) +
1.00273790935 FromDMS[PadRight[{rest}, 3]] + 0.000026 ((jd[{yr, mo, da, rest}, opts] -
2.451545*^6)/36525)^2, 24]
GMST[opts : OptionsPattern[]] := GMST[DateList[], opts]
Finally, here's the low-accuracy method for computing the solar altitude:
solarAltitude[date_List, {ϕ_, λ_}] :=
Module[{t, ℳ☉, ℯ, s, ℰ, v, Ω, ℒ0, Λ, ε, α, δ, ℋ},
t = (jd[date] - 2451545)/36525;
(* ℳ☉ - mean solar anomaly *)
ℳ☉ = Mod[(1.28710479305*^6 + t (1.295965810481*^8 + t (-0.5532 + t (1.36*^-4 -
1.149*^-5 t))))/3600, 360] °;
(* ℯ - eccentricity of Earth's orbit *)
ℯ = 0.0167086342 + t (-0.004203654 + t (-0.00126734 +
t (1.444*^-4 + t (-2.*^-6 + 3.*^-5 t))));
(* ℰ - eccentric anomaly; approximate solution of Kepler's equation *)
s = Sin[ℳ☉]; ℰ = ℳ☉ + ℯ s/(s - Sin[ℳ☉ + ℯ] + 1);
(* v - true anomaly *)
v = 2 ArcTan[Sqrt[(1 + ℯ)/(1 - ℯ)] Tan[ℰ/2]]/°;
(* ℒ0 - geometric mean longitude *)
ℒ0 = (280.46645 + t (36000.76983 + 3.032*^-4 t));
(* Ω - Meeus's correction for apparent angles *)
Ω = (125.04 - 1934.136 t) °;
(* Λ - solar longitude, plus correction for apparent position *)
Λ = Mod[v + ℒ0 - ℳ☉/°, 360] ° - (0.00569 + 0.00478 Sin[Ω]) °;
(* ε - mean obliquity of the ecliptic, plus correction for apparent position *)
ε = (84381.406 + t (-46.836769 + t (-1.831*^-4 + t (0.0020034 +
t (-5.76*^-7 - 4.34*^-8 t))))) °/3600 + 0.00256 Cos[Ω] °;
(* α - right ascension, δ - declination *)
{α, δ} = {ArcTan[Cos[Λ], Sin[Λ] Cos[ε]]/(15 °), ArcSin[Sin[ε] Sin[Λ]]};
(* ℋ - hour angle *)
ℋ = 15 ° Mod[FromDMS[GMST[date]] + λ/15 - α, 24];
ArcSin[Sin[δ] Sin[ϕ °] + Cos[δ] Cos[ϕ °] Cos[ℋ]]/°]
A few nice maps:
earthDay = Import["https://i.sstatic.net/KLrc8.jpg"];
earthNight = Import["https://i.sstatic.net/mCJik.jpg"];
Finally, the routine for making a day/night map:
Options[DayAndNightMap] = {Sphere -> False, TimeZone :> $TimeZone};
DayAndNightMap[date_List, opts : OptionsPattern[]] :=
Module[{h = OptionValue[TimeZone], terminator, dayAndNight},
terminator = Binarize[
RegionPlot[Positive[solarAltitude[DatePlus[date, {-h, "Hour"}], {ϕ, λ}]],
{λ, -180, 180}, {ϕ, -90, 90}, AspectRatio -> Automatic,
BoundaryStyle -> None, Frame -> False, ImagePadding -> None,
ImageSize -> {2048, 1024}, PlotPoints -> 45,
PlotRangePadding -> None, PlotStyle -> Black]];
dayAndNight = RemoveAlphaChannel[ImageCompose[earthDay,
SetAlphaChannel[earthNight, terminator]]];
If[TrueQ[OptionValue[Sphere]],
ParametricPlot3D[{Cos[λ] Sin[ϕ], Sin[λ] Sin[ϕ], Cos[ϕ]},
{λ, -π, π}, {ϕ, 0, π}, Axes -> None, Boxed -> False,
Lighting -> "Neutral", Mesh -> None, PlotPoints -> 55,
PlotStyle -> Texture[dayAndNight], RotationAction -> "Clip",
TextureCoordinateFunction -> ({#4, 1 - #5} &)],
dayAndNight]]
DayAndNightMap[opts : OptionsPattern[]] := DayAndNightMap[DateList[], opts]
I guess an example is in order at this point:
DayAndNightMap[{2013, 5, 21, 15, 30, 0}, TimeZone -> 0]
For the kids who prefer actual globes:
DayAndNightMap[{2013, 5, 21, 15, 30, 0}, Sphere -> True, TimeZone -> 0]