- +---------------------+--------+-----------+-----------------+
- | Date | Vis | Phase No. | Moon Phase Time |
- +---------------------+--------+-----------+-----------------+
- | 12/12/2008 00:26:44 | 95.14% | 14.048 | 14d 1h 9m |
- | 13/12/2008 00:26:44 | 98.08% | 15.048 | 15d 1h 9m |
- | 14/12/2008 00:26:44 | 91.31% | 16.048 | 16d 1h 9m |
- | 15/12/2008 00:26:44 | 84.54% | 17.048 | 17d 1h 9m |
- | 16/12/2008 00:26:44 | 77.77% | 18.048 | 18d 1h 9m |
- | 17/12/2008 00:26:44 | 70.99% | 19.048 | 19d 1h 9m |
- | 18/12/2008 00:26:44 | 64.22% | 20.048 | 20d 1h 9m |
- | 19/12/2008 00:26:44 | 57.45% | 21.048 | 21d 1h 9m |
- | 20/12/2008 00:26:44 | 50.68% | 22.048 | 22d 1h 9m |
- | 21/12/2008 00:26:44 | 43.9% | 23.048 | 23d 1h 9m |
- | 22/12/2008 00:26:44 | 37.13% | 24.048 | 24d 1h 9m |
- | 23/12/2008 00:26:44 | 30.36% | 25.048 | 25d 1h 9m |
- | 24/12/2008 00:26:44 | 23.59% | 26.048 | 26d 1h 9m |
- | 25/12/2008 00:26:44 | 16.81% | 27.048 | 27d 1h 9m |
- | 26/12/2008 00:26:44 | 10.04% | 28.048 | 28d 1h 9m |
- | 27/12/2008 00:26:44 | 3.27% | 29.048 | 29d 1h 9m |
- | 28/12/2008 00:26:44 | 3.51% | 0.518 | 0d 12h 25m |
- | 29/12/2008 00:26:44 | 10.28% | 1.518 | 1d 12h 25m |
- | 30/12/2008 00:26:44 | 17.05% | 2.518 | 2d 12h 25m |
- | 31/12/2008 00:26:44 | 23.82% | 3.518 | 3d 12h 25m |
- | 01/01/2009 00:26:44 | 30.6% | 4.518 | 4d 12h 25m |
- | 02/01/2009 00:26:44 | 37.37% | 5.518 | 5d 12h 25m |
- | 03/01/2009 00:26:44 | 44.14% | 6.518 | 6d 12h 25m |
- | 04/01/2009 00:26:44 | 50.91% | 7.518 | 7d 12h 25m |
- | 05/01/2009 00:26:44 | 57.69% | 8.518 | 8d 12h 25m |
- | 06/01/2009 00:26:44 | 64.46% | 9.518 | 9d 12h 25m |
- | 07/01/2009 00:26:44 | 71.23% | 10.518 | 10d 12h 25m |
- | 08/01/2009 00:26:44 | 78% | 11.518 | 11d 12h 25m |
- | 09/01/2009 00:26:44 | 84.78% | 12.518 | 12d 12h 25m |
- | 10/01/2009 00:26:44 | 91.55% | 13.518 | 13d 12h 25m |
- | 11/01/2009 00:26:44 | 98.32% | 14.518 | 14d 12h 25m |
- | 12/01/2009 00:26:44 | 94.91% | 15.518 | 15d 12h 25m |
- | 13/01/2009 00:26:44 | 88.13% | 16.518 | 16d 12h 25m |
- | 14/01/2009 00:26:44 | 81.36% | 17.518 | 17d 12h 25m |
- | 15/01/2009 00:26:44 | 74.59% | 18.518 | 18d 12h 25m |
- | 16/01/2009 00:26:44 | 67.81% | 19.518 | 19d 12h 25m |
- | 17/01/2009 00:26:44 | 61.04% | 20.518 | 20d 12h 25m |
- | 18/01/2009 00:26:44 | 54.27% | 21.518 | 21d 12h 25m |
- | 19/01/2009 00:26:44 | 47.5% | 22.518 | 22d 12h 25m |
- | 20/01/2009 00:26:44 | 40.72% | 23.518 | 23d 12h 25m |
- | 21/01/2009 00:26:44 | 33.95% | 24.518 | 24d 12h 25m |
- | 22/01/2009 00:26:44 | 27.18% | 25.518 | 25d 12h 25m |
- | 23/01/2009 00:26:44 | 20.41% | 26.518 | 26d 12h 25m |
- | 24/01/2009 00:26:44 | 13.63% | 27.518 | 27d 12h 25m |
- | 25/01/2009 00:26:44 | 6.86% | 28.518 | 28d 12h 25m |
- | 26/01/2009 00:26:44 | 0.09% | 29.518 | 29d 12h 25m |
- | 27/01/2009 00:26:44 | 6.68% | 0.987 | 0d 23h 41m |
- | 28/01/2009 00:26:44 | 13.46% | 1.987 | 1d 23h 41m |
- | 29/01/2009 00:26:44 | 20.23% | 2.987 | 2d 23h 41m |
- | 30/01/2009 00:26:44 | 27% | 3.987 | 3d 23h 41m |
- | 31/01/2009 00:26:44 | 33.78% | 4.987 | 4d 23h 41m |
- | 01/02/2009 00:26:44 | 40.55% | 5.987 | 5d 23h 41m |
- | 02/02/2009 00:26:44 | 47.32% | 6.987 | 6d 23h 41m |
- | 03/02/2009 00:26:44 | 54.09% | 7.987 | 7d 23h 41m |
- | 04/02/2009 00:26:44 | 60.87% | 8.987 | 8d 23h 41m |
- | 05/02/2009 00:26:44 | 67.64% | 9.987 | 9d 23h 41m |
- | 06/02/2009 00:26:44 | 74.41% | 10.987 | 10d 23h 41m |
- | 07/02/2009 00:26:44 | 81.18% | 11.987 | 11d 23h 41m |
- | 08/02/2009 00:26:44 | 87.96% | 12.987 | 12d 23h 41m |
- | 09/02/2009 00:26:44 | 94.73% | 13.987 | 13d 23h 41m |
- | 10/02/2009 00:26:44 | 98.5% | 14.987 | 14d 23h 41m |
- | 11/02/2009 00:26:44 | 91.73% | 15.987 | 15d 23h 41m |
- | 12/02/2009 00:26:44 | 84.95% | 16.987 | 16d 23h 41m |
- | 13/02/2009 00:26:44 | 78.18% | 17.987 | 17d 23h 41m |
- | 14/02/2009 00:26:44 | 71.41% | 18.987 | 18d 23h 41m |
- | 15/02/2009 00:26:44 | 64.64% | 19.987 | 19d 23h 41m |
- | 16/02/2009 00:26:44 | 57.86% | 20.987 | 20d 23h 41m |
- | 17/02/2009 00:26:44 | 51.09% | 21.987 | 21d 23h 41m |
- | 18/02/2009 00:26:44 | 44.32% | 22.987 | 22d 23h 41m |
- | 19/02/2009 00:26:44 | 37.54% | 23.987 | 23d 23h 41m |
- | 20/02/2009 00:26:44 | 30.77% | 24.987 | 24d 23h 41m |
- | 21/02/2009 00:26:44 | 24% | 25.987 | 25d 23h 41m |
- | 22/02/2009 00:26:44 | 17.23% | 26.987 | 26d 23h 41m |
- | 23/02/2009 00:26:44 | 10.45% | 27.987 | 27d 23h 41m |
- | 24/02/2009 00:26:44 | 3.68% | 28.987 | 28d 23h 41m |
- | 25/02/2009 00:26:44 | 3.09% | 0.456 | 0d 10h 57m |
- | 26/02/2009 00:26:44 | 9.86% | 1.456 | 1d 10h 57m |
- | 27/02/2009 00:26:44 | 16.64% | 2.456 | 2d 10h 57m |
- | 28/02/2009 00:26:44 | 23.41% | 3.456 | 3d 10h 57m |
- | 01/03/2009 00:26:44 | 30.18% | 4.456 | 4d 10h 57m |
- | 02/03/2009 00:26:44 | 36.95% | 5.456 | 5d 10h 57m |
- | 03/03/2009 00:26:44 | 43.73% | 6.456 | 6d 10h 57m |
- | 04/03/2009 00:26:44 | 50.5% | 7.456 | 7d 10h 57m |
- | 05/03/2009 00:26:44 | 57.27% | 8.456 | 8d 10h 57m |
- | 06/03/2009 00:26:44 | 64.04% | 9.456 | 9d 10h 57m |
- | 07/03/2009 00:26:44 | 70.82% | 10.456 | 10d 10h 57m |
- | 08/03/2009 00:26:44 | 77.59% | 11.456 | 11d 10h 57m |
- | 09/03/2009 00:26:44 | 84.36% | 12.456 | 12d 10h 57m |
- | 10/03/2009 00:26:44 | 91.14% | 13.456 | 13d 10h 57m |
- | 11/03/2009 00:26:44 | 97.91% | 14.456 | 14d 10h 57m |
- | 12/03/2009 00:26:44 | 95.32% | 15.456 | 15d 10h 57m |
- | 13/03/2009 00:26:44 | 88.55% | 16.456 | 16d 10h 57m |
- | 14/03/2009 00:26:44 | 81.77% | 17.456 | 17d 10h 57m |
- | 15/03/2009 00:26:44 | 75% | 18.456 | 18d 10h 57m |
- | 16/03/2009 00:26:44 | 68.23% | 19.456 | 19d 10h 57m |
- | 17/03/2009 00:26:44 | 61.46% | 20.456 | 20d 10h 57m |
- | 18/03/2009 00:26:44 | 54.68% | 21.456 | 21d 10h 57m |
- | 19/03/2009 00:26:44 | 47.91% | 22.456 | 22d 10h 57m |
- | 20/03/2009 00:26:44 | 41.14% | 23.456 | 23d 10h 57m |
- | 21/03/2009 00:26:44 | 34.37% | 24.456 | 24d 10h 57m |
- +---------------------+--------+-----------+-----------------+
Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.
Forum Search
Forum Statistics
UsersTotal Post History
- Posts:
- 78552
- Topics:
- 17957
7-Day Post History
- New Posts:
- 51
- New Topics:
- 30
- Active Topics:
- 31
Our newest member
Other
-
FAQ
All times are UTC [ DST ]
Google Ads
LTD Puzzle 13: Calculate the moon phase
Mind Boggling Puzzles, to keep that grey matter in shape...
Forum rules
Always post answers in a "Hidecode" tag, so that others have a chance to answer the question too.
Always post answers in a "Hidecode" tag, so that others have a chance to answer the question too.
Please wait...
LTD Puzzle 13: Calculate the moon phase
by chrissie1 on Fri Aug 29, 2008 12:42 pm
Calculate the phase of the moon as accurately as possible.
We all know that a moon month is not as long as a normal month. It is about 29.53 days long, but that is an average and not very accurate. SO you will have to find a better implementation than this one: http://www.voidware.com/moon_phase.htm
And for those having fun, once you have that, the calculation of Easter is easy.
This can take some research.
So you enter a date and get a % visibility, the calculation (the number that specifies the moon month / phase time corresponding to the "normal" time) and your calculation transformed to a time in days/hours and minutes.
Here is the test data and some results.
Dates are (dd/mm/yyyy)
We all know that a moon month is not as long as a normal month. It is about 29.53 days long, but that is an average and not very accurate. SO you will have to find a better implementation than this one: http://www.voidware.com/moon_phase.htm
And for those having fun, once you have that, the calculation of Easter is easy.

This can take some research.

So you enter a date and get a % visibility, the calculation (the number that specifies the moon month / phase time corresponding to the "normal" time) and your calculation transformed to a time in days/hours and minutes.
Here is the test data and some results.
Dates are (dd/mm/yyyy)
| Date | Visibility | Moon Phase Number | Moon Phase Time |
|---|---|---|---|
| 29/08/2008 13:56:00 | 9 % | 28.275 | 28d 6h 36m |
| 30/08/2008 13:56:00 | 2 % | 29.276 | 29d 6u 37m |
| 31/08/2008 13:56:00 | 5 % | 0.745 | 0d 17h 53m |
pink fuzzy slippers
-

chrissie1 - Senior Guru

-











- Posts: 9106
- Joined: Wed Oct 10, 2007 7:18 pm
- Location: Belgium
Unrated
Re: LTD Puzzle 13: Calculate the moon phase
by chrissie1 on Mon Sep 01, 2008 12:39 pm
So here is my implementation in VB.Net
Class: Moonday
Class Quarter
Class Quarters
Class Moonmonth
Main
You'll have to run it to see the result. But let's just say they are very close
Class: Moonday
- Namespace Moonphase
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- <CLSCompliant(True)> _
- Public Class MoonDay
- #Region " Private members "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Day As DateTime
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Visibility As Integer
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Age As String
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _MoonNumber As Double
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _SmallestQuarter As Quarter
- #End Region
- #Region " Constants "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Const _MoonConstant As Double = 29.53058868
- #End Region
- #Region " Constructors "
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="Day"></param>
- ''' <param name="SmallestQuarter"></param>
- ''' <remarks></remarks>
- Public Sub New(ByVal Day As DateTime, ByVal SmallestQuarter As Quarter)
- _SmallestQuarter = SmallestQuarter
- _Day = Day
- _MoonNumber = CalculateMonday()
- _Age = CalculateAge()
- _Visibility = CalculateVisibility()
- End Sub
- #End Region
- #Region " Public properties "
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property Day() As DateTime
- Get
- Return _Day
- End Get
- Set(ByVal Value As Date)
- _Day = Value
- _MoonNumber = CalculateMonday()
- _Age = CalculateAge()
- End Set
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property MoonNumber() As Double
- Get
- Return _MoonNumber
- End Get
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property Visibility() As Integer
- Get
- Return _Visibility
- End Get
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property Age() As String
- Get
- Return _Age
- End Get
- End Property
- #End Region
- #Region " Private methods "
- ''' <summary>
- '''
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function CalculateMonday() As Double
- Dim result As Double = 0
- If _SmallestQuarter.Name.ToLower = "new moon" Then
- result = DateDiff(DateInterval.Second, _SmallestQuarter.QuarterDate, _Day)
- result = result / 60 / 60 / 24
- If result < 0 Then
- result = GetSynodicPeriod(_Day) + result
- End If
- End If
- Return result
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="datum"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function GetSynodicPeriod(ByVal datum As Date) As Double
- Dim t As Double = (GetJuliandate(datum) - 2451545) / 36525
- Return _MoonConstant + (0.00000021621 * t) - 3.64 * (10 ^ -10 * t ^ 2)
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="dt"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function GetJuliandate(ByVal dt As DateTime) As Double
- Dim a As Double = Math.Floor(dt.Year / 100)
- Dim b As Double = Math.Floor(a / 4)
- Dim c As Double = 2 - a + b
- Dim d As Double = dt.Day
- Dim e As Double = Math.Floor(365.25 * (dt.Year + 4716))
- Dim f As Double = Math.Floor(30.6001 * (dt.Month + 1))
- Dim jd As Double = c + d + e + f - 1521.5
- Return jd
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function CalculateAge() As String
- Dim dagen As Double = 0
- Dim uren As Double = 0
- Dim minuten As Double = 0
- dagen = Fix(_MoonNumber)
- uren = (_MoonNumber - dagen) * 24
- minuten = (uren - Fix(uren)) * 60
- Return dagen & "d " & Fix(uren) & "u " & Fix(minuten) & "m"
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function CalculateVisibility() As Integer
- If _MoonNumber > (_MoonConstant / 2) Then
- Return Convert.ToInt32((_MoonConstant - _MoonNumber) / _MoonConstant * 100 * 2)
- Else
- Return Convert.ToInt32((_MoonNumber) / _MoonConstant * 100 * 2)
- End If
- End Function
- #End Region
- End Class
- End Namespace
Code is hidden, SHOW
Class Quarter
- Namespace Moonphase
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Public Class Quarter
- #Region " Private members "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _QuarterDate As Date
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Name As String
- #End Region
- #Region " Constructors "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Public Sub New(ByVal Name As String, ByVal QuarterDate As Date)
- _Name = Name
- _QuarterDate = QuarterDate
- End Sub
- #End Region
- #Region " Public properties "
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property QuarterDate() As Date
- Get
- Return _QuarterDate
- End Get
- Set(ByVal Value As Date)
- _QuarterDate = Value
- End Set
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property Name() As String
- Get
- Return _Name
- End Get
- Set(ByVal Value As String)
- _Name = Value
- End Set
- End Property
- #End Region
- End Class
- End Namespace
Code is hidden, SHOW
Class Quarters
- Namespace Moonphase
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Public Class Quarters
- #Region " Private members "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Quarters As New Collection
- #End Region
- #Region " Constructors "
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="Year"></param>
- ''' <param name="Month"></param>
- ''' <remarks></remarks>
- Public Sub New(ByVal Year As Integer, ByVal Month As Integer)
- Me.MakeYear(Year, Month)
- End Sub
- #End Region
- #Region " Public properties "
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property Quarters() As Collection
- Get
- Return _Quarters
- End Get
- End Property
- #End Region
- #Region " Private methods "
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="Julian"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function ToGregorian(ByVal Julian As Double) As DateTime
- Dim _Date(2) As Integer
- Dim _Time(2) As Integer
- Dim _JulianRounded As Double = 0
- Dim dbla, dblb, dblc, dbld, dble, dblf, dblalpha As Double
- Dim _MoonNumber As Double
- Dim _Seconds As Double
- Julian += 0.5
- _JulianRounded = Math.Floor(Julian)
- dblf = Julian - _JulianRounded
- If (_JulianRounded < 2299161.0) Then
- dbla = _JulianRounded
- Else
- dblalpha = Math.Floor((_JulianRounded - 1867216.25) / 36524.25)
- dbla = _JulianRounded + 1 + dblalpha - Math.Floor(dblalpha / 4)
- End If
- dblb = dbla + 1524
- dblc = Math.Floor((dblb - 122.1) / 365.25)
- dbld = Math.Floor(365.25 * dblc)
- dble = Math.Floor((dblb - dbld) / 30.6001)
- If dble < 14 Then
- _MoonNumber = Math.Floor(dble - 1)
- Else
- _MoonNumber = Math.Floor(dble - 13)
- End If
- If _MoonNumber > 2 Then
- _Date(0) = Convert.ToInt32(Format(Math.Floor(dblb - dbld - Math.Floor(30.6001 * dble) + dblf), "00"))
- _Date(1) = Convert.ToInt32(Format(_MoonNumber, "00"))
- _Date(2) = Convert.ToInt32(Format(Math.Floor(dblc - 4716), "00"))
- Else
- _Date(0) = Convert.ToInt32(Format(Math.Floor(dblb - dbld - Math.Floor(30.6001 * dble) + dblf), "00"))
- _Date(1) = Convert.ToInt32(Format(_MoonNumber, "00"))
- _Date(2) = Convert.ToInt32(Format(Math.Floor(dblc - 4715), "00"))
- End If
- _Seconds = (Julian - Math.Floor(Julian)) * 86400.0
- _Time(0) = Convert.ToInt32(Format(Math.Floor(_Seconds / 3600), "00"))
- _Time(1) = Convert.ToInt32(Format(Math.Floor((_Seconds / 60) Mod 60), "00"))
- _Time(2) = Convert.ToInt32(Format(Math.Floor(_Seconds Mod 60), "00"))
- Return CDate(_Date(0) & "/" & _Date(1) & "/" & _Date(2) & " " & _Time(0) & ":" & _Time(1) & ":" & _Time(2))
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="x"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function dsin(ByVal x As Double) As Double
- Return Math.Sin(dtr(x))
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="x"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function dcos(ByVal x As Double) As Double
- Return Math.Cos(dtr(x))
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="d"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function dtr(ByVal d As Double) As Double
- Return (d * Math.PI) / 180.0
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="k"></param>
- ''' <param name="phase"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Private Function truephase(ByVal k As Double, ByVal phase As Double) As Double
- Dim t, t2, t3, pt, m, mprime, f As Double
- Const SynMonth As Double = 29.53058868
- k += phase
- t = k / 1236.85
- t2 = t * t
- t3 = t2 * t
- pt = 2415020.75933 + SynMonth * k + 0.0001178 * t2 - 0.000000155 * t3 + 0.00033 * dsin(166.56 + 132.87 * t - 0.009173 * t2)
- m = 359.2242 + 29.10535608 * k - 0.0000333 * t2 - 0.00000347 * t3
- mprime = 306.0253 + 385.81691806 * k + 0.0107306 * t2 + 0.00001236 * t3
- f = 21.2964 + 390.67050646 * k - 0.0016528 * t2 - 0.00000239 * t3
- If ((phase < 0.01) Or (Math.Abs(phase - 0.5) < 0.01)) Then
- pt += (0.1734 - 0.000393 * t) * dsin(m) + 0.0021 * dsin(2 * m) - 0.4068 * dsin(mprime) + 0.0161 * dsin(2 * mprime) - 0.0004 * dsin(3 * mprime) + 0.0104 * dsin(2 * f) - 0.0051 * dsin(m + mprime) - 0.0074 * dsin(m - mprime) + 0.0004 * dsin(2 * f + m) - 0.0004 * dsin(2 * f - m) - 0.0006 * dsin(2 * f + mprime) + 0.001 * dsin(2 * f - mprime) + 0.0005 * dsin(m + 2 * mprime)
- ElseIf ((Math.Abs(phase - 0.25) < 0.01 Or (Math.Abs(phase - 0.75) < 0.01))) Then
- pt += (0.1721 - 0.0004 * t) * dsin(m) + 0.0021 * dsin(2 * m) - 0.628 * dsin(mprime) + 0.0089 * dsin(2 * mprime) - 0.0004 * dsin(3 * mprime) + 0.0079 * dsin(2 * f) - 0.0119 * dsin(m + mprime) - 0.0047 * dsin(m - mprime) + 0.0003 * dsin(2 * f + m) - 0.0004 * dsin(2 * f - m) - 0.0006 * dsin(2 * f + mprime) + 0.0021 * dsin(2 * f - mprime) + 0.0003 * dsin(m + 2 * mprime) + 0.0004 * dsin(m - 2 * mprime) - 0.0003 * dsin(2 * m + mprime)
- End If
- If (phase < 0.5) Then
- pt += 0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime)
- Else
- ' Last quarter correction */
- pt += -0.0028 + 0.0004 * dcos(m) - 0.0003 * dcos(mprime)
- End If
- Return pt
- End Function
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private Sub MakeYear(ByVal Year As Integer, ByVal Month As Integer)
- Dim _Exit As Boolean = False
- Dim _Quarter As Quarter = Nothing
- Dim _FirstYear As Double = 0
- Dim _Time As Double = 0
- Dim _Year As Double = 0
- Dim _DatTime As DateTime
- Dim _Phases As Integer = 0
- Dim _NumberOfFullMoons As Integer = 0
- _Quarters = New Collection
- For _Phases = 0 To 3
- _FirstYear = Math.Floor((Year - 1900) * 12.3685) - 4
- _Exit = False
- Do While _Exit = False
- _Time = truephase(_FirstYear, _Phases / 4)
- _Year = Me.ToGregorian(_Time).Year
- If _Year >= Year Then
- If _Time < 0 Then
- _DatTime = Me.ToGregorian(-_Time)
- Else
- _DatTime = Me.ToGregorian(_Time)
- End If
- If _DatTime.Year = Year And _DatTime.Month = Month Then
- Select Case _Phases
- Case Is = 0
- _Quarter = New Quarter("New moon", _DatTime)
- Case 1
- _Quarter = New Quarter("First quarter", _DatTime)
- Case 2
- _Quarter = New Quarter("Full moon", _DatTime)
- _NumberOfFullMoons += 1
- Case 3
- _Quarter = New Quarter("Last quarter", _DatTime)
- End Select
- _Quarters.Add(_Quarter)
- End If
- End If
- If (_Year > Year) Then
- _Exit = True
- Else
- _FirstYear += 1
- End If
- Loop
- Next
- SortCollection()
- End Sub
- #End Region
- #Region " Public methods "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Public Sub SortCollection()
- Dim a, b As Quarter
- Dim i, i2 As Integer
- Dim Max As Integer = Me._Quarters.Count
- For i = 2 To Max
- For i2 = 1 To _Quarters.Count - 1
- a = CType(_Quarters.Item(i2), Quarter)
- b = CType(_Quarters.Item(i2 + 1), Quarter)
- If a.QuarterDate > b.QuarterDate Then
- _Quarters.Remove(i2)
- _Quarters.Add(b, , i2)
- _Quarters.Remove(i2 + 1)
- _Quarters.Add(a, , i2 + 1)
- End If
- Next
- Next
- Max -= 1
- End Sub
- #End Region
- End Class
- End Namespace
Code is hidden, SHOW
Class Moonmonth
- Namespace Moonphase
- Public Class MoonMonth
- #Region " Private methods "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Month As DateTime
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Days As New Dictionary(Of Integer, MoonDay)
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private _Quarters As New Collection
- #End Region
- #Region " Constructors "
- ''' <summary>
- '''
- ''' </summary>
- ''' <param name="Month"></param>
- ''' <remarks></remarks>
- Public Sub New(ByVal Month As DateTime)
- _Month = Month
- FillQuarters()
- MakeCollection()
- End Sub
- #End Region
- #Region " Public properties "
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property Month() As DateTime
- Get
- Return _Month
- End Get
- Set(ByVal Value As Date)
- _Month = Value
- FillQuarters()
- MakeCollection()
- End Set
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property Days() As Dictionary(Of Integer, MoonDay)
- Get
- Return _Days
- End Get
- End Property
- ''' <summary>
- '''
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property Quarters() As Collection
- Get
- Return _Quarters
- End Get
- End Property
- #End Region
- #Region " Private methods "
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private Sub FillQuarters()
- _Quarters = New Quarters(_Month.Year, _Month.Month).Quarters
- End Sub
- ''' <summary>
- '''
- ''' </summary>
- ''' <remarks></remarks>
- Private Sub MakeCollection()
- 'Kijk waar de nieuwe maan zit
- Dim intnieuwemaan As Integer = 0
- For inttemp As Integer = 1 To _Quarters.Count
- If CType(_Quarters(inttemp), Quarter).Name.ToLower = "new moon" Then
- intnieuwemaan = inttemp
- End If
- Next
- 'Omdat er niet altijd een nieuwe maan is nemen we de niewe maan van de vorige maand
- If intnieuwemaan = 0 Then
- Dim _Quarters2 As New Collection
- _Quarters2 = New Quarters(_Month.Year, _Month.Month - 1).Quarters
- For inttemp As Integer = 1 To _Quarters2.Count
- If CType(_Quarters2(inttemp), Quarter).Name.ToLower = "new moon" Then
- intnieuwemaan = inttemp
- End If
- Next
- 'maak voor elke dag in deze maand een dag in de collectie
- For inttemp As Integer = 1 To DateTime.DaysInMonth(_Month.Year, _Month.Month)
- _Days.Add(inttemp, New MoonDay(Convert.ToDateTime(inttemp & "/" & _Month.Month & "/" & _Month.Year & " " & _Month.Hour & ":" & _Month.Minute & ":" & _Month.Second), CType(_Quarters2(intnieuwemaan), Quarter)))
- Next
- Else
- 'maak voor elke dag in deze maand een dag in de collectie
- For inttemp As Integer = 1 To DateTime.DaysInMonth(_Month.Year, _Month.Month)
- _Days.Add(inttemp, New MoonDay(Convert.ToDateTime(inttemp & "/" & _Month.Month & "/" & _Month.Year & " " & _Month.Hour & ":" & _Month.Minute & ":" & _Month.Second), CType(_Quarters(intnieuwemaan), Quarter)))
- Next
- End If
- End Sub
- #End Region
- End Class
- End Namespace
Code is hidden, SHOW
Main
- Module Module1
- Sub Main()
- Dim _MoonMonth As New Moonphase.MoonMonth(New Date(2008, 8, 28, 13, 56, 0))
- Dim _Moonday As Moonphase.MoonDay = _MoonMonth.Days(29)
- Console.WriteLine("Date: " & _Moonday.Day)
- Console.WriteLine("Moon Number: " & _Moonday.MoonNumber)
- Console.WriteLine("Moon Age: " & _Moonday.Age)
- Console.WriteLine("Moon Visibility: " & _Moonday.Visibility)
- _Moonday = _MoonMonth.Days(30)
- Console.WriteLine("Date: " & _Moonday.Day)
- Console.WriteLine("Moon Number: " & _Moonday.MoonNumber)
- Console.WriteLine("Moon Age: " & _Moonday.Age)
- Console.WriteLine("Moon Visibility: " & _Moonday.Visibility)
- _Moonday = _MoonMonth.Days(31)
- Console.WriteLine("Date: " & _Moonday.Day)
- Console.WriteLine("Moon Number: " & _Moonday.MoonNumber)
- Console.WriteLine("Moon Age: " & _Moonday.Age)
- Console.WriteLine("Moon Visibility: " & _Moonday.Visibility)
- Console.ReadLine()
- End Sub
- End Module
Code is hidden, SHOW
You'll have to run it to see the result. But let's just say they are very close

pink fuzzy slippers
-

chrissie1 - Senior Guru

-











- Posts: 9106
- Joined: Wed Oct 10, 2007 7:18 pm
- Location: Belgium
Unrated
Re: LTD Puzzle 13: Calculate the moon phase
by rizzo on Fri Jan 30, 2009 12:27 am
-takes a bow-
This should be accurate to within a second or so. (i hope
)
And the result...
This should be accurate to within a second or so. (i hope
)- Module MoonTimer
- Public Const TicksPerDay As Long = 864000000000
- Public Const LunarMonth As Long = 25514429760000 'Number of microseconds / ticks in a lunar month to the nearest millisecond.
- Public Const NewMoonMark As Long = 632409553800000000 'New moon on 10th of january 2005 @ 12:03:00.
- Sub Main()
- Dim dtMoonDates(99) As DateTime
- Dim i As Integer
- For i = 0 To 99
- dtMoonDates(i) = DateTime.Now.AddDays(-49 + i)
- Next
- Console.WriteLine("+---------------------+--------+-----------+-----------------+")
- Console.WriteLine("| Date | Vis | Phase No. | Moon Phase Time |")
- Console.WriteLine("+---------------------+--------+-----------+-----------------+")
- For Each d As DateTime In dtMoonDates
- Dim MoonStrings As String() = GetMoonByDateTime(d)
- Console.WriteLine("| " & d.ToString("dd/MM/yyyy HH:mm:ss") & _
- " | " & MoonStrings(0).PadRight(6) & _
- " | " & MoonStrings(1).PadRight(9) & _
- " | " & MoonStrings(2).PadRight(15) & _
- " |")
- Next
- Console.WriteLine("+---------------------+--------+-----------+-----------------+")
- End Sub
- Public Function GetMoonByDateTime(ByVal dtMoonDate As DateTime) As String()
- Dim TimeSince1st As Long = dtMoonDate.Ticks - NewMoonMark
- Dim TimeSinceLast As Long = TimeSince1st Mod LunarMonth
- Dim TimeToNext As Long = LunarMonth - TimeSinceLast
- Dim TimeToFull As Long = IIf(TimeToNext > TimeSinceLast, TimeToNext - (LunarMonth / 2), TimeSinceLast - (LunarMonth / 2))
- Dim tsLast As TimeSpan = TimeSpan.FromTicks(TimeSinceLast)
- Dim tsNext As TimeSpan = TimeSpan.FromTicks(TimeToNext)
- Dim VisPerc As Decimal = Nothing
- Dim o As String() = New String() { _
- Math.Round(100 - (100 / (LunarMonth / 2)) * TimeToFull, 2) & "%", _
- Math.Round(tsLast.TotalDays, 3), _
- tsLast.Days & "d " & tsLast.Hours & "h " & tsLast.Minutes & "m "}
- Return o
- End Function
- End Module
Code is hidden, SHOW
And the result...
Code is hidden, SHOW
-

rizzo - Apprentice

-

- Posts: 23
- Joined: Wed Jan 21, 2009 11:10 pm
- Location: Devon. UK
3 posts • Page 1 of 1


LTD Social Sitings
Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.