Get moon phase in Vala and PowerShell.

I’m working on a project in Vala that requires the moon phase. I’ve done this before in Python myself but wanted to look around for better. I found a nice Python script that just works so I decided to use it in Vala. Again, I’m learning PowerShell so why not convert to that as well? First the PowerShell since it’s pretty. The Python is not my original code, taken from a post in a learning site and I cannot find it again to give credit. I had to tweak the math a bit but other than that it’s similar to the original.

Function Get-MoonPhase {
    <#
    .SYNOPSIS
    Calculate approximate moon phase.
    .DESCRIPTION
    Moon phase code converted by Mohawke, 2019
    .PARAMETER Year
    Specifies the year.
    .PARAMETER Month
    Specifies the month.
    .PARAMETER Day
    Specifies the day.
    #>
    Param (
        [Parameter(Mandatory=$True)]
     [string]$Year,
        [Parameter(Mandatory=$True)]
     [string]$Month,
        [Parameter(Mandatory=$True)]
     [string]$Day
    )
    $lunar_cycle = 29.530588853
    $ref_date = get-date -Year 2000 -Month 1 -Day 6 # Jan. 6. 2000 [New Moon]
    $usr_date = get-date -Year $Year -Month $Month -Day $Day
    $phases = @("new",
                "waxing crescent",
                "first quarter",
                "waxing gibbous",
                "full",
                "waning gibbous",
                "last quarter",
                "waning crescent")
    $phase_length = $lunar_cycle / 8
    $days = ($usr_date - $ref_date).Days
    $mdays = ($days + $phase_length / 2) % $lunar_cycle
    $phase_index = [int]($mdays * (8 / $lunar_cycle)) - 1
    
    Write-Host "length $phase_length days $days mday $mdays index $phase_index" 
    return $phases[$phase_index]
}
$moonphase = Get-MoonPhase -Year 2019 -Month 8 -Day 31
Write-Host $moonphase

So what about Vala? I could not find a way to do direct date compares like Python diff = datetime_object.date() – datetime_object.date(); diff.days. Urg! Anyway, it seems right.

using GLib;
// compile: $ valac -X -lm moonphases.vala

private static string moon_phase(int year, int month, int day) {
    string[] phases = {"new","waxing cresent","first quarter",
                       "waxing gibbous","full","waning gibbous",
                       "last quarter","waning cresent"};

    double lunar_cycle = 29.530588853;
    DateTime ref_date = new DateTime.utc (2000, 1, 6, 0, 0, 0.0); // known new moon.
    DateTime now_utc = new DateTime.utc (year, month, day, 0, 0, 0.0);

    double phase_length = lunar_cycle / 8;
    TimeSpan diff = now_utc.difference (ref_date);
    int days = (int)(diff / (1000*60*60*24));
    int days_adj = days / 1000;
    print(days_adj.to_string() + " -> ");

    double offset = Math.fmod((days_adj + phase_length / 2),  lunar_cycle);
    int phase_index = (int)(offset * (8 / lunar_cycle));
    print (phase_index.to_string() + "  ");
    string phase = phases[phase_index];
    return phase;
}

public static int main (string[] args) {
    string x = moon_phase(2019,8,31);
    print(x+" ");
    return 0;
}

Hope it’s useful.