B4A Library Astro library

The library provides the times of Sunrise, Sunset, Moon rise and Moon set, according to place and date.
It also provides the phase of the moon (equivalent to the day of the moon month).
The Sunrise and Sunset times vary according to the value of Zenith angle.
The following conventions are in use:
Official – 90.8333 (90° 50’)
Civil - 96°
Nautical - 102°
Astronomical - 108°
The values can be used by their names.
The library use the Official value as default, and it can be changed using the method Zenith.

No demo program as it is very simple to use.
Please report problems.

Edit: Version 1.1 corrected the following as per alfcen comments:
- no_rise or no_set time are returned as "--:--"
- sun rise and set times are within the 24 hours.

Edit: the files are updated to ver. 1.2 with additional methods which provide data about the sun and the moon, all by our astronomy expert alfcen:sign0188:
Edit: Ver 1.21 correction of rounding problem.
Edit: Ver 1.22 bug correction in sun + format change.
Edit: ver 1.23 bug correction in moon phase.
Edit: ver 1.4 added a method to calculate sun's position (azimuth and elevation).
 

Attachments

Last edited:
Hi, derez! it's very usefull library!
I have seen in you post a fragment of code for calculating SunPosition. And Celectial coordinates was used inside him.
How i Can get celestial coordinates ( right ascension And declination ) for Sun and for Moon?
I have created the library in 2012 based on algorithms that I have found googling. I didn't do much with it since then...
The expert that helped me after first publishing is alfcen (see post #3) and since Astronomy is his hobby, he may help you much better then me.
 
Thank you, derez! For the first attemption, i will try to rewrite untAstro code from my Delphi project...
 
Hi, derez! For now untAstro-code is working in Android! untAstro can calculate Rise and Set times without limitations for 65deg Latitude (it's very important for me). Can i take one or two procedures from Your library (Astrolib) and insert them into my library? (Some procedures from You code are more compact then my... ) :)
 
Great library derez! Integrated the lib into my new project and I am really satisfied with the accuracy of the data. Only trouble is the "circumpolar" mode of the sun during summertime in the far north or south of the globe (and this happens already in the north of sweden and norway here in europe). So if the sun is not sinking below the horizon, this should be visible somehow. A "--:--" is not enough (when travelling virtually). So this is also valid for the times of dusk and dawn. Is there a way to indicate that somehow? Maybe the elevation value of sun could be used if the library can calculate it. So then you could replace the "--:--" from the sample simply with an "UP" or "PD" for polar day and a "DOWN" or "PN" for polar night. Same for the south pole, think it's the same there 6 months later.
A little bit more tricky, when it comes to dusk & dawn. So, in St. Peterburg in Russia you have "white nights", where sun is down but it is not dark. Is that dusk or already dawn? Probably not a big change in code, just a nice finetuning.
What if the Moon simply had no rise, like today here in Berlin? Also a "--:--" for the Moon's rise. When there is no rise-time, is the Moon visible? In this case it was easy to answer because Moon had a set-time, so Moon must be visible (it was not, it was cloudy). Just an idea... Maybe you can change that somehow? Would be perfect then.
 
I have not done any work with eclipse and writing libraries in java and I don't have intention to restart it all over.
I attach the java code that was used, feel free to modify to your likes.
Sorry !
 

Attachments

I see, what a pity. That's a perfect match then, because I have no knowledge about java. So I have to work around with the data I have or calculate what I am missing within B4A. Thanks for the response, derez.
 
I can translate the code for sun but I don't know how to solve the problem of "no result = --:--"
The case is when there is no solution because cosh > 1 :
[CODE lang="java" title="part of sun"]...
double sinDec = 0.39782 * Math.sin(DtoR*L); //' this is in radians
double cosDec = Math.cos(Math.asin(sinDec)) ;
double cosH = (Math.cos(DtoR*zenith) - (sinDec * Math.sin(DtoR*latit))) / (cosDec * Math.cos(DtoR*latit));
if (cosH > 1)
{ RiseSet[order]= "--:--" ;}
else
...[/CODE]

In b4x code this code is:
B4X:
...
dim sinDec as double  = 0.39782 *sinD(L)
dim cosDec as double = cos(asin(sinDec))  
dim cosH as double = (cosD(zenith) - (sinDec * sinD(latit))) / (cosDec * cosD(latit))
    if  cosH >  1 then
        RiseSet(order)= "--:--"
    else
        ...
 
Last edited:
Here is the code translation for sun and tsun:
[CODE lang="b4x" title="sun & tsun"]' /**
' * Returns the Sunrise And Sunset times in an Array of two strings.
' * At Latitudes greater Then 65 Or smaller Then -65 there are cases that
' * there Is no sunrise And sunset. The result in this Case Is "--:--"
' */
Public Sub Sun( day As Int, month As Int , year As Int, latitude As Double , longitude As Double, deltahour As Double) As String()
Dim RiseSet(2) As String

' test the input
If ((day < 1 ) Or ( day > 31) Or (month<1) Or (month>12) Or(year <100)) Then
RiseSet(0) = "Date error"
RiseSet(1) = "Date error"
else if ((year = 1582) And (month = 10) And ( day > 4) And (day < 15)) Then
RiseSet(0) = "Date error"
RiseSet(1) = "Date error"
Else
Dim N1 As Int = 275 * month / 9
Dim N2 As Int = Floor((month + 9) / 12)
Dim N3 As Int = (1 + Floor((year - 4 *Floor(year / 4) + 2) / 3))
Dim N As Int = N1 - N2 * N3 + day - 30

RiseSet(0) = tsun( 0, N, latitude, longitude, deltahour) ' rise time
RiseSet(1) = tsun( 1, N, latitude, longitude, deltahour) ' set time
End If
Return RiseSet
End Sub

' use the library to get the value of zenith
Private Sub tsun(order As Int, N As Int, latit As Double, longit As Double, deltahour As Double) As String
Dim RiseSet(2) As String
Dim RtoD As Double= 180/cPI
' double DtoR = Math.PI/180 ;
Dim lngHour As Double = longit / 15
Dim H , TT , UT, localT , ht , mint As Double

Dim st1,st2 As String
Dim t As Double = N + (6 + 12 * order - lngHour) / 24
Dim M As Double= (0.9856 * t) - 3.289
Dim L As Double = M + (1.916 * SinD(M)) + (0.020 * SinD( 2 * M)) + 282.634
L = (L + 720 ) Mod 360
Dim RA As Double = RtoD * ATan(0.91764 * TanD(L))
RA = (RA + 720 ) Mod 360
Dim Lquadrant As Double = Floor( L/90) * 90
Dim RAquadrant As Double = Floor(RA/90) * 90
RA = RA + Lquadrant - RAquadrant
RA = (RA + 720 ) Mod 360
RA = RA / 15
Dim sinDec As Double = 0.39782 *SinD(L)
Dim cosDec As Double = Cos(ASin(sinDec))
Dim cosH As Double = (CosD(zenith) - (sinDec * SinD(latit))) / (cosDec * CosD(latit))
If Abs(cosH) > 1 Then
RiseSet(order)= "--:--"
Else

If order = 0 Then
H = 360 - RtoD * ACos(cosH)
Else
H = RtoD * ACos(cosH)
End If
H = H / 15
TT = H + RA - 0.06571 * t - 6.622
UT = TT - lngHour
localT = (UT + deltahour + 48) Mod 24
ht = Floor (localT)

mint = Floor((localT - Floor (localT)) *60 + 0.5 )
If (mint = 60) Then
ht = ht + 1
mint = 0
End If
If (ht < 10) Then
st1 = "0" & ht
Else
st1 = ht
End If
If (mint < 10.0 ) Then
st2 = "0" & Floor(mint)
Else
st2 = Floor(mint)
End If
RiseSet(order) = st1 & ":" & st2
If (st2.length = 1) Then RiseSet(order) = "--:--" ' Case that mint Is Null

End If
Return RiseSet(order)
End Sub

[/CODE]

I compared the results to the library and the results are the same.
 
Last edited:
Well Derez, I am close to solve my "Moon"-problem within my current app-development. Spent hours with reading books about spherical trigonometrics. It's a mess. Forget one transition from rad to deg and you are lost. Currently I am working on a huge Excel-sheet putting all the formulas together to bring it into a "system". This is better done with Excel then with B4A. If that works, I will do the transition to B4A for my app.

To solve the problem with the "--:--" I have an idea in mind. It's so far only a workaround outside the library. It's an addition of B4A-code to your AstroLib-example. Don't know if I can realize it, but it looks promising. So stay tuned, this will take a while. As said above, calculating with spherical trigonometrics is not easy, I forget most of it since study-times. It's mostly a long chain of additions of sin, cos, tan and their opposites. Often you calculate with the same value, but you have to convert to deg or rad, for making the formula's work.
Calculations for the Moon in opposite to Sun are very complicated. NASA is doing that very exactly with uncounted variables with their highend-computers. It is good enough for us to calculate position and other things with the formulas developod by Jean Meeus (a belgian mathematic-astronomic genius). The result of these simplified calculations are up to 0.5 to 1 degree close to the real value. So gravitational influences from other objects in space for instance are playing no role.

Short: If that works as expected, somebody with excellent knowledge of Java could eventually enhance the library itself later, adding some new functions if there is public interest to it. We will see...
 
Hi,

Thank you for this nice library ?

I have tried it and got a "shift" of one hour for the sun position.

I mean that to get the correct values I must call the method with "1" hour delay. And I am currently at Universal Time +2 here in France.

I have tried also the sub provided here : https://www.b4x.com/android/forum/threads/astro-library.15975/post-481866
And this sub gives perfect results
B4X:
    AzimuthAstro = SunPosition(43.5156,1.4996,DateTime.Now)
        Log("Sun Azimuth: " & AzimuthAstro(0) & " Sun Elevation : " & AzimuthAstro(1) & " " & DateTime.GetHour(DateTime.Now)& ":" & DateTime.GetMinute(DateTime.Now))

result is consistant : Sun Azimuth: 237.16063521081998 Sun Elevation : 54.57340827034812 16:4
Which is the right value for 16:04 local time
 
This could be tricky...
A year ago I had also problems while using the lib. But...

In my understanding, you should try to fix all your calculations based on UTC in general. Given this, France is more or less located on the Greenwich meridian from astronomical point of view. But France is using Middle European Time politically, so this is already one hour difference to Greenwich. On top comes during summertime one hour for DST. So this gives you a two hours offset compared to the "real astronomical time". All you have to do is to calculate this "real astronomical time", based on your offset to Greenwich Mean Time or Universal Time.
Try to use your own "timezone" definition, depending on astronomical point of view. So based on Greenwich meridian, you have to add every 15 degrees to the east 1 hour, subtracting it to the west for getting a correct result, after determining your GPS-Position. If you are using the "time-zone-declaration" of your mobile provider, it may fail, because it is astronomically wrong for France, even more when DST is in effect because it is already included in your local time.

As far as I remember there is something about that written within the explanation of the astro-library.

Honestly I fixed it somehow within my COMPASS-APP, but have no idea what I did exactly in the past. Within this app I am calculating the actual position of the sun and (MUCH MUCH MORE COMPLICATED) the actual position and phase of the moon for plotting two symbols on the compass rose. And the moon gave me real headache for some weeks, finally I made it... But then never released the app nor the code, it was more or less a project "for fun". I don't like the playstore, because of it's "useful" developer-regulations, renewed every day. I am not willing to follow all this developer-regulations and to fill out every day a formular for "better security". This is driving me nuts.
 
Last edited:
Thank you fo this clear explaination.

I do use UTC for all my computations, and especially for my solar tracker

I expected the lib to do all the tricky stuff and to be consistant with the sub
The sub gives good results without any correction.
I can see that the code takes into account the timezone
B4X:
' Calculate time of the day in UT decimal hours
            Dim offsetTicks As Long = DateTime.TimeZoneOffset * DateTime.TicksPerHour
            Dim UTCTimenow As Long = Timenow - offsetTicks
            dDecimalHours = DateTime.GetHour(UTCTimenow ) + DateTime.GetMinute(UTCTimenow )/60 + DateTime.GetSecond(UTCTimenow )/3600.0

But the lib doesn't...

Well I will use the sub ?
 
Hello, is it possible to calculate the moon phase when I have a date and time?
 
Well, yes and no, depending on needed accuracy. For a given date and time you can calculate the moon phase based on a known date of new moon or full moon. The cycle is about 29,53059 days (synodic period). This is a "rounded" value. The true cycle varies above and below that value, because of gravitation effects of other objects in space (constellation of other planets and moons).
Try the ASTROLIB DEMO for better understanding. It calculates the moon phase exactly enough for your personal needs. Use the value "moon age" to determine the moon phase.
 
Back
Top