PrayerTimePlus 0.3.0

dotnet add package PrayerTimePlus --version 0.3.0
                    
NuGet\Install-Package PrayerTimePlus -Version 0.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PrayerTimePlus" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PrayerTimePlus" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="PrayerTimePlus" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PrayerTimePlus --version 0.3.0
                    
#r "nuget: PrayerTimePlus, 0.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PrayerTimePlus@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PrayerTimePlus&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=PrayerTimePlus&version=0.3.0
                    
Install as a Cake Tool

PrayerTimePlus for .NET

A dependency-free C# library for Islamic prayer times and Sunnah night portions. The net8.0 library uses immutable inputs, nullable DateTimeOffset results and the caller's UTC offset. It implements the supported prayer-time calculations of the Dart, Swift and Kotlin 0.3.0 siblings. The initial C# package is 0.3.0, aligned with that family version; helper and city-context differences are described below.

Also available for Dart / Flutter, Swift, and Kotlin / JVM. All four are faithful ports of the same solar engine and match supported prayer-time calculations to the minute for identical inputs. See Other platforms.

Install

Version 0.3.0 is prepared for NuGet distribution. To install the locally built package into a consumer project:

dotnet add package PrayerTimePlus --version 0.3.0 --source /absolute/path/to/artifacts/packages

Public feed publication is a separate release action. The library requires .NET 8 or later and has no third-party runtime dependencies.

Calculate a day

using PrayerTimePlus;

var times = new PrayerTimes(
    coordinates: new Coordinates(24.3486, 56.6953, altitude: 5.0),
    dateComponents: new DateComponents(2026, 6, 28),
    calculationParameters: CalculationMethod.Oman.GetParameters(),
    utcOffset: TimeSpan.FromHours(4),
    countryCode: "OM",
    cityName: "sohar");

Console.WriteLine(times.Fajr?.ToString("HH:mm"));    // 03:59
Console.WriteLine(times.Maghrib?.ToString("HH:mm")); // 19:10
Console.WriteLine(times.Isha?.ToString("HH:mm"));    // 20:35

The seven properties are Fajr, Sunrise, Dhuhr, Asr, Sunset, Maghrib and Isha. Each defined result carries the supplied offset; .UtcDateTime gives its absolute UTC instant. Undefined solar events return null.

The date is a Gregorian civil date. A DateOnly can be adapted with DateComponents.From(date). UTC offsets must contain whole minutes and fall within ±14 hours; include the DST adjustment for the requested date yourself. Offsets such as TimeSpan.FromMinutes(345) (+05:45) are supported. The library does not discover time zones or locations.

Ordinary prayer times round to a minute and wrap to the requested civil date, even if an intermediate hour crosses midnight. Gregorian dates use years 1–9999. An invalid date, default DateComponents, invalid enum or invalid offset throws an argument exception. At the date-range endpoints, a UTC instant outside years 1–9999 also throws ArgumentOutOfRangeException.

Coordinates accepts arbitrary doubles. Choose Coordinates.Validated(latitude, longitude, altitude) to require finite latitude in [-90, 90], longitude in [-180, 180] and non-negative altitude in metres. East longitude is positive. Elevation affects only the methods and countries listed in METHODS.md. cityName is a caller label and does not affect the calculation.

Presets, Auto and adjustments

METHODS.md lists every supported stable key, angle, interval and minute offset. CalculationMethods.FromKey("oman") resolves exact keys; unknown, null, case-altered or whitespace-padded keys return null. Custom and the None placeholder use the shared MWL defaults. The Dubai label uses MWL numeric fallback values.

var method = AutoMethod.ForCountry("OM");
var parameters = method.GetParameters() with
{
    Madhab = Madhab.Hanafi,
    HighLatitudeRule = HighLatitudeRule.SeventhOfTheNight,
    Adjustments = new PrayerAdjustments { Fajr = 2 }
};

Auto uses the compiled country map, matches invariant case without trimming, and falls back to Muslim World League for unknown, empty or null country codes. Pass the country code to PrayerTimes too, for country-dependent elevation and Ramadan behavior. Presets return fresh immutable records. Customize them with with; MethodAdjustments and caller Adjustments are combined once. Their signed integer values are minutes. Sunset has no adjustment slot.

Shafi is the default Asr school and uses shadow factor 1. Hanafi uses factor 2. The default high-latitude rule is Automatic: calculate with None, then retry once using the literal night fraction 0.14286 if rounded Fajr is null or midnight, or Isha is null or in hour 0 or 12. Explicit rules are:

  • None: preserve unavailable twilight as null.
  • MiddleOfTheNight: half the sunset-to-sunrise night.
  • SeventhOfTheNight: the literal fraction 0.14286 of the night.
  • TwilightAngle: the prayer's depression angle divided by 60 of the night; interval Isha uses 18 degrees for this rule.

Night corrections limit twilight only when the natural result is undefined or farther from its anchor than the permitted fraction. An unavailable Sunrise or Sunset can still leave twilight null under any rule.

Custom Maghrib and Isha

var custom = CalculationMethod.Custom.GetParameters() with
{
    HighLatitudeRule = HighLatitudeRule.None,
    MaghribIsInterval = false,
    MaghribValue = 4.0,
    IshaIsInterval = true,
    IshaValue = 90.0
};

Fajr always uses a depression angle in degrees. In angle mode, positive Maghrib values use a finite evening angle later than Sunset and earlier than angle-based Isha. A non-positive, unavailable or non-chronological angle falls back to Sunset plus Maghrib adjustments. In interval mode, Maghrib is Sunset plus MaghribValue minutes and its adjustments. Interval Isha starts at the final Maghrib, then adds IshaValue minutes and its own adjustments.

Bare new CalculationParameters() defaults MaghribIsInterval to false: an omitted flag makes a positive MaghribValue an angle in degrees. In contrast, the Custom preset explicitly uses interval=true with a zero-minute value.

The caller sets IsRamadan. With method key makkah and country SA (case-insensitive), it adds 30 minutes to Isha before high-latitude correction. The library performs no Hijri calendar conversion.

Current, next and Sunnah times

var current = times.CurrentPrayer(times.Dhuhr!.Value);
var next = times.NextPrayer(times.Dhuhr.Value); // Asr
var fajr = times.TimeForPrayer(Prayer.Fajr);
var sunnah = new SunnahTimes(times);
Console.WriteLine(sunnah.LastThirdOfTheNight);

Current/next compare absolute instants, skip undefined values and include Sunrise. Current is the latest boundary at or before the supplied instant; next is the earliest strictly after it. Current returns None before the day's first defined boundary, and next returns None after the last. None has no time. Omitting the instant reads the current UTC clock.

Helpers use actual timestamp order when midnight wrapping or adjustments make the prayer names unordered. Equal timestamps select the later prayer name for current and the earlier name for next, in Fajr → Sunrise → Dhuhr → Asr → Maghrib → Isha order. Kotlin and Dart 0.3.0 helpers scan that fixed name order instead, so helper answers can differ for reordered schedules even when all seven calculated prayer minutes match. For Oslo on 2026-06-21, +02:00, MWL/Shafi and TwilightAngle, Isha is 00:12 on the requested date: C# selects Isha as next at 00:00, and Sunrise as current at 10:00. The sibling helpers select Fajr and Isha respectively. NextPrayer only examines this constructed day; consumers must calculate tomorrow with its correct DST offset after the day's last event.

Minute-level compatibility covers the supported solar calculations. C# and Kotlin treat cityName as a label, while Dart applies city-specific tweaks for some presets. Those application adjustments are outside the C# engine. C# preserves country/city context when recomputing tomorrow for Sunnah, matching Kotlin; Dart 0.3.0 omits that context and can produce different night portions.

PrayerTimes.Today(coordinates, parameters, offset) chooses today's date at the supplied offset. Calculation for an explicit date never reads the clock.

Sunnah times run from today's final Maghrib to tomorrow's recomputed Fajr, using the same inputs and offset. They can fall on the following date and round to a minute after integer-second night division. Either missing boundary makes both values null. Tomorrow beyond year 9999 throws an argument exception. If DST changes overnight, calculate the required days and boundaries in your application using their respective offsets.

Build, example and verification

Install the stable .NET SDK pinned in global.json. The library targets net8.0; the example, tests and generator target net10.0. From the repository root:

dotnet restore PrayerTimePlus.slnx
dotnet build PrayerTimePlus.slnx -c Release --no-restore
dotnet format PrayerTimePlus.slnx --verify-no-changes --no-restore
dotnet test tests/PrayerTimePlus.Tests/PrayerTimePlus.Tests.csproj -c Release --no-build --no-restore
dotnet run --project examples/PrayerTimePlus.Example -c Release --no-build
dotnet run --project tools/PrayerTimePlus.DataGenerator -c Release --no-build -- --check
dotnet pack src/PrayerTimePlus/PrayerTimePlus.csproj -c Release --no-build --no-restore -o artifacts/packages

The console example defaults to Sohar on 2026-06-28. For another date and location, provide yyyy-MM-dd latitude longitude utc-offset-minutes country:

dotnet run --project examples/PrayerTimePlus.Example -c Release --no-build -- 2026-06-28 24.3486 56.6953 240 OM

The example also compiles and demonstrates customization and helper APIs. tools/Verify-Package.ps1 checks package contents and runs a fresh consumer for each of .NET 8 and .NET 10, with isolated caches and package references using only the local feed. Install both runtimes and their reference packs; the SDKs include them. Each consumer asserts the actual runtime major version:

pwsh -File tools/Verify-Package.ps1

Tests contain exact Sohar/Mecca goldens, custom-angle conformance and captured fixed-input Dart sibling vectors across presets, both Asr schools, all high-latitude choices, fractional offsets, leap dates and hemispheres. Fixtures and generator inputs are committed; builds require no sibling repositories. Focused custom/Sunnah cases include source revisions and normalized instants; the optional capture recipe records the selected helper policy and the known Dart context exceptions. Generated code remains subject to analyzers and formatting. Regenerate tables and method documentation with:

dotnet run --project tools/PrayerTimePlus.DataGenerator -c Release

CI runs the checks on Windows, Linux and macOS. Runtime scope covers the calculation library; Qibla, Shia presets, static city tables, seasonal changes, application city tweaks, geolocation, scheduling and native UI are outside it.

Other platforms

The same solar engine, ported idiomatically to four ecosystems, with matching supported prayer-time calculations to the minute:

Platform Package Repository
C# / .NET — you are here PrayerTimePlus (0.3.0 prepared, unpublished) prayer-time-plus-csharp
Dart / Flutter prayer_time_plus prayer_time_plus
Swift · iOS, macOS, watchOS, tvOS, Linux Swift Package Index prayer-time-plus-swift
Kotlin / JVM io.github.abdulwahed-s:prayer-time-plus prayer-time-plus-kotlin

See Current, next and Sunnah times for helper ordering and city-context compatibility details.

License

Licensed under MIT.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 123 9/30/2026