SwissEphSharp 2.10.3.1

dotnet add package SwissEphSharp --version 2.10.3.1
                    
NuGet\Install-Package SwissEphSharp -Version 2.10.3.1
                    
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="SwissEphSharp" Version="2.10.3.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SwissEphSharp" Version="2.10.3.1" />
                    
Directory.Packages.props
<PackageReference Include="SwissEphSharp" />
                    
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 SwissEphSharp --version 2.10.3.1
                    
#r "nuget: SwissEphSharp, 2.10.3.1"
                    
#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 SwissEphSharp@2.10.3.1
                    
#: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=SwissEphSharp&version=2.10.3.1
                    
Install as a Cake Addin
#tool nuget:?package=SwissEphSharp&version=2.10.3.1
                    
Install as a Cake Tool

SwissEphSharp

A C# port of the Astrodienst Swiss Ephemeris, the astronomical library used to compute planetary positions, house cusps, eclipses and related quantities. It is a line-by-line translation of Astrodienst's C source rather than a reimplementation, so the function names, arguments and return values are the ones in Astrodienst's own programming documentation.

swe_version() reports 2.10.03. Targets netstandard2.0, net8.0 and net10.0. No dependencies.

Read the license first

Swiss Ephemeris, and therefore this library, is dual-licensed, and one of the two options has a condition that catches people out. You must choose one:

  • AGPL-3.0. Free, but with a network clause. If you run this library as part of a service that users reach over a network, a web app, an API, a SaaS product, the AGPL requires you to offer those users the complete corresponding source of your whole service, not just this library. Operating the service is the trigger; you do not have to distribute a binary to anyone. If that does not work for your project, AGPL is not your option.
  • Swiss Ephemeris Professional License. A commercial license bought from Astrodienst, without the source-disclosure obligation.

This is not a choice this package makes for you, and it follows Astrodienst's own relicensing of Swiss Ephemeris. LICENSE, agpl-3.0.txt and NOTICE ship at the root of this package.

Install

dotnet add package SwissEphSharp

The package ID is SwissEphSharp; the namespace and every type name stay SwissEphNet, so using SwissEphNet; is what you write. The SwissEphNet package ID on nuget.org belongs to the upstream project's own release, which is why this project cannot publish under it.

Your first calculation

This computes the Sun's position on 1 January 2020. It needs no data files: SEFLG_MOSEPH selects the built-in analytic ephemeris, which is computed rather than read from disk.

using System.Globalization;
using SwissEphNet;

using var swe = new SwissEph();

// Julian day for 2020-01-01 00:00 UT, Gregorian calendar.
double jd = swe.swe_julday(2020, 1, 1, 0.0, SwissEph.SE_GREG_CAL);

var xx = new double[6];
string serr = "";
int ret = swe.swe_calc_ut(jd, SwissEph.SE_SUN, SwissEph.SEFLG_MOSEPH, xx, ref serr);

if (ret < 0)
    Console.WriteLine($"error: {serr}");
else
    Console.WriteLine("Sun longitude: "
        + xx[0].ToString("F6", CultureInfo.InvariantCulture) + " degrees");

Output:

Sun longitude: 280.009518 degrees

xx comes back as longitude, latitude, distance, then the three matching speeds. swe_calc_ut takes Universal Time; swe_calc takes Ephemeris Time. A negative return means failure and serr says why. SwissEph is IDisposable, hence the using.

Which API to call: prefer the 2 variants

Several functions have a newer sibling with a 2 in the name, and for new code that is generally what you want.

For fixed stars this is Astrodienst's own published advice: "For new projects, we recommend using the new functions swe_fixstar2_ut() and swe_fixstar2(). Performance will be a lot better if a great number of fixed star calculations are done." The same goes for swe_fixstar2_mag over swe_fixstar_mag. If an existing project is slow on star lookups, replacing the old calls is the fix. All six are here, old and new.

For houses, swe_houses_ex2 and swe_houses_armc_ex2 are new in 2.10.03 and give you two things the older calls cannot: per-cusp and per-ascmc speeds, and an explicit serr out-parameter instead of a bare return code. Astrodienst does not publish a "prefer these" recommendation for them the way it does for fixed stars, so treat them as extra capability rather than a replacement: reach for them when you want speeds or a diagnostic message, and stay on swe_houses/ swe_houses_ex otherwise.

There is no 2 variant of swe_calc, which is why the example above uses swe_calc_ut.

Using real ephemeris files

For better accuracy, or for bodies the analytic ephemeris does not cover, point swe_set_ephe_path at a directory of Astrodienst's .se1 files and ask for SEFLG_SWIEPH:

using var swe = new SwissEph();
swe.swe_set_ephe_path("/path/to/ephe");

var xx = new double[6];
string serr = "";
int ret = swe.swe_calc_ut(jd, SwissEph.SE_SUN, SwissEph.SEFLG_SWIEPH, xx, ref serr);

Files are read straight from the filesystem. Astrodienst publishes them in the Swiss Ephemeris repository at aloistr/swisseph/ephe, mirrored at ephe.scryr.io/ephe. sepl_18.se1, semo_18.se1 and seas_18.se1 cover 1800 to 2399 and are enough for most work; each file holds six centuries starting at the century in its name.

Watch for the silent fallback. When a file is missing the library falls back to the analytic ephemeris, notes it in serr, and returns a number that looks perfectly reasonable. Compare ret against the flag you asked for: ask for SEFLG_SWIEPH and get SEFLG_MOSEPH back and your path is wrong. If you read serr instead, null-check it, because it comes back null from some successful calls and "" from others.

When your data is not a file on disk, an embedded resource being the usual case, implement SwissEph.IEphemerisFileProvider (one method, Stream Open(string path), returning null for "not found") and assign it to SwissEph.FileProvider.

Threads

Create one SwissEph instance per thread. A single instance is not safe to share across threads. Separate instances are independent and can run concurrently. There is no async API; the calls are synchronous, so wrap a long sweep in Task.Run to keep it off a UI thread.

Upgrading from SwissEphNet 2.8.0.2

Four things to check, in the order that matters:

  1. The license changed. 2.8.0.2 was GPL-2.0-or-later; this is AGPL-3.0 or the Professional License. See above. If you run it server-side and cannot publish your source, this is a licensing decision before it is a technical one.
  2. The package ID changed from SwissEphNet to SwissEphSharp, and the assembly is now SwissEphSharp.dll. Source that only calls the public API needs no change beyond the PackageReference. Anything that hardcodes the assembly name needs updating.
  3. Your numbers will change. Some of that is Astrodienst's own model changes between 2.08 and 2.10.03; some is port defects that are now fixed, including one that gave every SEFLG_SWIEPH position the wrong obliquity. Eclipse magnitude and obscuration are now fractions rather than percentages, so a value that read 100 reads 1.
  4. OnLoadFile is gone, replaced by SwissEph.FileProvider. If your handler just opened a real file by path, delete it: swe_set_ephe_path alone now reaches those files.

Target frameworks moved too. 2.8.0.2 shipped net40 and netstandard1.0; neither is supported here. .NET Framework 4.6.1 and later resolve netstandard2.0.

The full README documents every breaking change with the C source line each one corresponds to.

Credits

The original C-to-C# port is Yan Grenier's work (2014-2019). SwissEphSharp continues it, maintained since 2026 by Timothy van der Ham: modernised target frameworks, the 2.10.03 upgrade, and a number of bug fixes in the port. The Swiss Ephemeris itself is by Astrodienst. See NOTICE in this package for the full attribution.

This package is not published or endorsed by Yan Grenier or Astrodienst.

More

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net10.0

    • No dependencies.
  • 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
2.10.3.1 126 8/8/2026
2.10.3 151 8/3/2026

2.10.3.1:
- Full XML documentation (<summary>, <param>, <returns>) added for all 116
 public swe_* methods in SwissEphNet/SwissEph.swephexp.h.cs, plus the SEFLG_*/SE_*/SEMOD_*
 constants they reference. Purely additive: no signature or behavior changed, and
 SwissEphNet/CPort/ is untouched. IntelliSense now shows the same documentation a C caller
 gets from swephexp.h instead of nothing (CS1591 is suppressed repo-wide, so this gap was
 previously silent).
- Programs/SweTest: fixed insert_gap_string_for_tabs's LEN_SOUT bound. It now counts bytes the
 way the C's strlen does, using native single-byte semantics on Windows (the narrow-argv code
 page) and UTF-8 elsewhere, instead of counting UTF-16 characters. Accented -g gap values no
 longer stop tab substitution one byte early. This affects the SweTest program's console
 output, not the SwissEphSharp library API.
- swe_houses_ex2 now re-reads sid_data after its SE_SIDM_FAGAN_BRADLEY fallback, matching the
 C's pointer semantics (swehouse.c:221). No input reachable through the public API changes
 value from this today; it closes an audited fidelity gap rather than fixing an observed bug.
- Test coverage: BaselineMatrix now exercises 7 more of the library's 107 public entry points,
 all 100% EXACT on both TFMs. A new NutationTableFidelityTest value-diffs the nutation
 coefficient table against upstream source instead of only checking its length.
- CI gained macOS legs on the baseline and conformance gates (report-only).
- No breaking changes. See docs/known-issues.md and docs/compliance-2.10.03.md for the
 verification detail behind this release.

2.10.3 (the first release published to nuget.org, under the SwissEphSharp
package ID):
- LICENSE CHANGE, read this before upgrading. 2.8.0.2 was distributed under the GNU General
 Public License version 2 or later. This release is under the Swiss Ephemeris dual license:
 the GNU Affero General Public License, or a Swiss Ephemeris Professional License bought from
 Astrodienst. The practical difference is the AGPL's network clause. Under GPL-2.0 you could
 run this library inside a web service and owe nobody source, because nothing was distributed.
 Under the AGPL, operating the service is itself the trigger, and users who reach it over a
 network can require the complete corresponding source of your whole service, not just this
 library. If that does not work for your project, the Professional License is the other arm.
 This follows Astrodienst's own relicensing of Swiss Ephemeris and applies to the C library
 just as much as to this port. LICENSE, agpl-3.0.txt and NOTICE ship at the package root.
- SE_VERSION now reports "2.10.03", matching the C library this port tracks (upstream tag
 v2.10.3bfinal). Every stage of the 2.10.03 delta has landed: the header/constants stage,
 swephlib.c, the ayanamsha machinery, sweph.c, swecl.c, swehouse.c and swetest.c.
- swe_houses, swe_houses_ex, swe_houses_armc, swe_house_pos and swe_house_name each gained an
 int hsys overload alongside the existing char hsys overload, matching upstream swephexp.h.
- New API surface: swe_houses_ex2, swe_houses_armc_ex2, swe_calc_pctr, swe_get_current_file_data.
- swe_lun_occult_when_glob and swe_lun_occult_when_loc each gained an Int32 backward overload, so
 SE_ECL_ONE_TRY can be OR-ed into that bitfield the way swephexp.h declares. The existing bool
 overload is unchanged and still binds; it can only pass 0 or 1, so it can never request the
 flag. Reflection that resolves either method by name alone now throws AmbiguousMatchException.
- OnLoadFile is gone; ephemeris files are read from disk by default through the new
 SwissEph.FileProvider (IEphemerisFileProvider).
- The assembly is now named SwissEphSharp (was SwissEphNet), so this package can coexist in one
 dependency graph with the original SwissEphNet 2.8.0.2 instead of silently colliding with it at
 build time and crashing at runtime. The namespace stays SwissEphNet.
- 2.10.3 is the only release that ships netstandard2.0, not the last of several. 2.8.0.2 shipped
 net40 and netstandard1.0 and never carried netstandard2.0, and net8.0 or later will be required
 from the next release on, so the window in which this library is reachable from .NET Framework
 is this one version. Consumers on .NET Framework 4.6.1+ can take 2.10.3 and should pin to it
 deliberately rather than expect it to persist. netstandard2.0 is a compatibility target,
 not a correctness one: measured on .NET Framework 4.8 and 4.6.2 against .NET 10, the same
 asset's swe_calc differs on 29 of 102 calls (34 bodies x 3 epochs; worst case SE_ADMETOS
 latitude speed, 2.28e-3 relative -- an absolute divergence of 1.4e-08 deg/day against a base
 value of about -6.1e-06), while net8.0 and net10.0 agree on all 102. The cause is .NET
 Framework's less accurate Math.Sin/Math.Cos/Math.Tan near quarter-turn boundaries, not this
 port; see the "V:2.10.3" section of README.md for the full measurement.
- Numerous port bug fixes surfaced by the 2.10.03 work, several of them upstream C bugs Astrodienst
 fixed between 2.08 and 2.10.03 that this port now also carries: swe_nod_aps/swe_nod_aps_ut
 returning all-zero nodes and apsides, an obliquity read that affected every SEFLG_SWIEPH
 position, eclipse magnitude and obscuration off by a factor of 100, and the swe_house_pos buffer
 that was one element short for Gauquelin houses. See docs/compliance-2.10.03.md for the
 verification numbers behind this release and docs/known-issues.md and the "V:2.10.3" section
 of README.md for the full list.

- You are also inheriting everything in CHANGELOG.md's 2.8.1.0 entry, even though no such
 package was ever published. On nuget.org the step is 2.8.0.2 straight to this release, so
 those changes arrive with it: DIR_GLUE went from '\' to '/' on every platform, which changes
 the asteroid file names a file provider is asked for; DefaultEncoding became UTF-8 explicitly
 rather than falling back to it when Windows-1252 could not be resolved; and C.strcmp,
 strncmp, strstr and strchr became ordinal instead of culture-sensitive, which affects
 fixed-star name search and sort under a non-invariant culture.

Full history, back to the 2.08 upgrade: CHANGELOG.md at
https://github.com/Tim81/SwissEphNet/blob/main/CHANGELOG.md.