Zmanim API Ported to Cocoa / Objective-C

Moshe Berman completed the 2.0 release of his port of the KosherJava Zmanim API from Java to a Cocoa API using Objective-C. You can see the work in the KosherCocoa project page. The original work on the port dates back to Moshe’s iPhone Ultimate Omer 2 (iTunes link) app. In that app, he ported the minimum amount of code needed to calculate sunset in order to roll the day of the Omer after sunset. With Moshe’s latest check-in at github, he provided a port of a good portion of the API sticking to the basic design of the KosherJava API. The complexZmanimCalendar still remains to be ported, but the majority of zmanim in common use are in the ported ZmanimCalendar. Moshe’s blog post Introducing KosherCocoa 2.0 has additional details. Additional developer notes can be seen in the KosherCocoa wiki page. This port will be a boon to iOS developers who now have a simple way to include zmanim in their iPhone and iPad apps.
Here is some sample code that outputs zmanim to the console.

Zmanim.m

#import <Foundation/Foundation.h>
#import "ZmanimCalendar.h"

int main (int argc, const char * argv[]){

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    //  Set up the location
    NSString *locationName = @"Lakewood, NJ";
    double latitude = 40.096; //Lakewood, NJ
    double longitude = -74.222; //Lakewood, NJ
    NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:-18000];

    //  Initialize the Zmanim Calendar
    GeoLocation *geoLocation = [[GeoLocation alloc] initWithName:locationName andLatitude:latitude andLongitude:longitude andTimeZone:timeZone];
    ZmanimCalendar *zmanimCalendar = [[ZmanimCalendar alloc] initWithLocation:geoLocation];

    //  Create a Formatter for the date information
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setTimeZone:timeZone];
    [formatter setDateStyle:NSDateFormatterNoStyle];
    [formatter setTimeStyle:NSDateFormatterMediumStyle];

    NSDate *sunrise = [zmanimCalendar sunrise];
    NSDate *sofZmanShmaMGA = [zmanimCalendar sofZmanShmaMogenAvraham];
    NSDate *sofZmanShmaGRA = [zmanimCalendar sofZmanShmaGra];
    NSDate *sunset = [zmanimCalendar sunset];

    NSLog(@"Today's Zmanim for %@",  [geoLocation locationName]);
    NSLog(@"Sunrise: %@",  [formatter stringFromDate:sunrise]);
    NSLog(@"Sof Zman Shema MGA: %@",  [formatter stringFromDate:sofZmanShmaMGA]);
    NSLog(@"Sof Zman Shema GRA: %@",  [formatter stringFromDate:sofZmanShmaGRA]);
    NSLog(@"Sunset: %@",  [formatter stringFromDate:sunset]);

    [pool drain];
    return 0;
}

This would output (on February 8th):

Today's Zmanim for Lakewood, NJ
Sunrise: 6:58:43 AM
Sof Zman Shema MGA: 8:59:04 AM
Sof Zman Shema GRA: 9:35:04 AM
Sunset: 5:24:09 PM

KosherJava Zmanim API Released Under the LGPL License

LGPL 2.1Until this point the KosherJava Zmanim API has been released under the GPL V2.0 open source license. This had the effect of forcing any application written using the library to release it’s source code under the same license. Being that the Zmanim API is a library, the LGPL is a more appropriate license. The LGPL allows developers to use the KosherJava Zmanim API, yet keep their application code closed source. Only changes to the API itself (such as ports to different languages) would have to be released as open source. I had in the past on request released the source under the LGPL (the Zmanim API .NET port has already been released under the LGPL with my permission), and with the recent 3/27/2011 SVN checkin I formally changed the Java Zmanim API license to the LGPL 2.1 (not the newer LGPL 3.0). The next 1.3.0 release will be the first formal release under the LGPL. In one case the change to the license required permission from developer who wrote code used by the the Zmanim API, and this was done.

Calculating Erev Pesach Zmanim

MatzosThe Zmanim API did not have dedicated zmanim to claculate the Erev Pesach zmanim of sof zman achilas chametz (the latest time one can eat chametz), and sof zman biur chametz (the latest time to burn chametz) till the April 14 check in to the KosherJava Zmanim Project GitHub repository. The latest time for eating chametz is at the end of the 4th hour of the day. This corresponds to sof zman tfila. The API has about 12 of those, so that does not require any special programming, but to help developers who are unaware of how they work I created 3 wrapper getSofZmanAchilasChametz methods (getSofZmanAchilasChametzGRA(), getSofZmanAchilasChametzMGA72Minutes() and getSofZmanAchilasChametzMGA16Point1Degrees()) calling the 3 most commonly used getSofZmanTfila methods (getSofZmanTfilaGRA(), getSofZmanTfilaMGA72Minutes() and getSofZmanTfilaMGA16Point1Degrees()). For example here is the exact code used in getSofZmanAchilasChametzGRA()

public Date getSofZmanAchilasChametzGRA() {
	return getSofZmanTfilaGRA();
}

The API itself is very flexible, and as long as you know the calculation of the zman, you can easily calculate it. For example, to calculate sof zman biur chametz according to the GR"A, the time would be 5 shaos zmaniyos after sunrise. Using the Zmanim API this would be coded as:

Date SofZmanBiurChametzGra = getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 5);

The exact code used in the API is:

public Date getSofZmanBiurChametzGRA() {
	return getTimeOffset(getSeaLevelSunrise(), getShaahZmanisGra() * 5);
}

Developers who want to use the current API to generate these zmanim can use the following sample as a guide.

String locationName = "Lakewood, NJ";
double latitude = 40.09596; //Lakewood, NJ
double longitude = -74.22213; //Lakewood, NJ
double elevation = 0; //optional elevation
TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
ComplexZmanimCalendar czc = new ComplexZmanimCalendar(location);
czc.getCalendar().set(Calendar.YEAR, 2011);
czc.getCalendar().set(Calendar.MONTH, Calendar.APRIL);
czc.getCalendar().set(Calendar.DAY_OF_MONTH, 18);
Date graAchilas = czc.getSofZmanTfilaGRA();
Date graBiur = czc.getTimeOffset(czc.getSeaLevelSunrise(), czc.getShaahZmanisGra() * 5);
Date mga72Achilas = czc.getSofZmanTfilaMGA72Minutes();
Date mga72Biur = czc.getTimeOffset(czc.getAlos72(), czc.getShaahZmanisMGA() * 5);
Date mga16Achilas = czc.getSofZmanTfilaMGA16Point1Degrees();
Date mga16Biur = czc.getTimeOffset(czc.getAlos16Point1Degrees(), czc.getShaahZmanis16Point1Degrees() * 5);
System.out.println("Erev Pesach Zmanim for " + locationName);
System.out.println("Sof Zman Achilas Chametz GRA: " + graAchilas);
System.out.println("Sof Zman Biur Chametz GRA: : " + graBiur);
System.out.println("Sof Zman Achilas Chametz MGA 72 Minutes: " + mga72Achilas);
System.out.println("Sof Zman Biur Chametz MGA 72 Minutes: " + mga72Biur);
System.out.println("Sof Zman Achilas Chametz MGA 16.1 Deg: " + mga16Achilas);
System.out.println("Sof Zman Biur Chametz MGA 16.1 Deg: " + mga16Biur);

this would output

C:\path\to\code>javac ErevPesachZmanim.java

C:\path\to\code>java ErevPesachZmanim

Erev Pesach Zmanim for Lakewood, NJ
Sof Zman Achilas Chametz GRA: Mon Apr 18 10:42:42 EDT 2011
Sof Zman Biur Chametz GRA: : Mon Apr 18 11:49:39 EDT 2011
Sof Zman Achilas Chametz MGA 72 Minutes: Mon Apr 18 10:18:42 EDT 2011
Sof Zman Biur Chametz MGA 72 Minutes: Mon Apr 18 11:37:39 EDT 2011
Sof Zman Achilas Chametz MGA 16.1 Deg: Mon Apr 18 10:13:56 EDT 2011
Sof Zman Biur Chametz MGA 16.1 Deg: Mon Apr 18 11:35:18 EDT 2011

Zmanim API Ported to .NET (C#)

Yitzchok ported the Zmanim API from Java to a .NET API using C#. The Zmanim .NET project was released under the LGPL 2.1. This is a change from the GPL used by the Java API, something that may change shortly. Also part of the project was the creation of a C# version of the Zmanim CLI, matching Moshe Wagner’s Java Zmanim CLI. When developing the project, Yitzchok created the ZmanimTest JUnit test case class to confirm that the C# port output matched the Java API. I will likely add this to the core Zmanim API in the near future. The port currently relies on IKVM assemblies as can be seen in the Java references in the code sample below, mostly because of the lack of a native .NET equivalent of the Java TimeZone class. Yitzchok also created some examples of the use of the Zmanim .NET API that will be of help to developers. Below are two of the simpler examples in C# and VB.NET demonstrating a very simple use of the API to output zmanim from the console.

C#

using Zmanim.TimeZone;
using Zmanim.TzDatebase; //in Zmanim.TzDatebase.dll assembly
using Zmanim.Utilities;

namespace Zmanim.Samples.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            string locationName = "Lakewood, NJ";
            double latitude = 40.09596; //Lakewood, NJ
            double longitude = -74.22213; //Lakewood, NJ
            double elevation = 0; //optional elevation
            ITimeZone timeZone = new OlsonTimeZone("America/New_York");
            GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
            ComplexZmanimCalendar zc = new ComplexZmanimCalendar(location);
            //optionally set it to a specific date with a year, month and day
            //ComplexZmanimCalendar zc = new ComplexZmanimCalendar(new DateTime(1969, 2, 8), location);

            System.Console.WriteLine("Today's Zmanim for " + locationName);
            System.Console.WriteLine("Sunrise: " + zc.GetSunrise()); //output sunrise
            System.Console.WriteLine("Sof Zman Shema MGA: " + zc.GetSofZmanShmaMGA()); //output Sof Zman Shema MGA
            System.Console.WriteLine("Sof Zman Shema GRA: " + zc.GetSofZmanShmaGRA()); //output Sof Zman Shema GRA
            System.Console.WriteLine("Sunset: " + zc.GetSunset()); //output sunset

            System.Console.WriteLine("Press enter to exit.");
            System.Console.ReadLine();
        }
    }
}

VB.NET

mports Zmanim.TzDatebase 'in Zmanim.TzDatebase.dll assembly
Imports Zmanim.Utilities
Imports Zmanim.TimeZone

Module Module1

    Sub Main()
        Dim locationName As String = "Lakewood, NJ"
        Dim latitude As Double = 40.09596 'Lakewood, NJ
        Dim longitude As Double = -74.22213 'Lakewood, NJ
        Dim elevation As Double = 0 'optional elevation
        Dim timeZone As ITimeZone = New OlsonTimeZone("America/New_York")
        Dim location As New GeoLocation(locationName, latitude, longitude, elevation, timeZone)
        Dim zc As New ComplexZmanimCalendar(location)
        'optionally set it to a specific date with a year, month and day
        'Dim zc As New ComplexZmanimCalendar(New DateTime(1969, 2, 8), location)
        System.Console.WriteLine("Today's Zmanim for " & locationName)
        System.Console.WriteLine("Sunrise: " & zc.GetSunrise().ToString)
        'output sunrise
        System.Console.WriteLine("Sof Zman Shema MGA: " & zc.GetSofZmanShmaMGA().ToString)
        'output Sof Zman Shema MGA
        System.Console.WriteLine("Sof Zman Shema GRA: " & zc.GetSofZmanShmaGRA().ToString)
        'output Sof Zman Shema GRA
        System.Console.WriteLine("Sunset: " & zc.GetSunset().ToString)
        'output sunset
        System.Console.WriteLine("Press enter to exit.")
        System.Console.ReadLine()

    End Sub

End Module

The current Zmanim .NET TODO list for the project includes:

  • Remove dependency to Java (IKVM assemblies)
  • The API should follow the .NET guidelines
  • Make it Linq friendly
  • Add examples how to use this project in a ASP.NET MVC site and WPF Application
  • Try to get it to work on Silverlight

Android Zmanim Using the KosherJava Zmanim API

Android ZmanimThere are various software projects using the KosherJava Zmanim API. One of the active ones is Jay Gindin’s open source Android Zmanim app for the Android platform. Activity in the project is constant. The upcoming version allows the selection of a specific calculation for zmanim you want such as the zman Talis/Tefilin pictured here. There are plans to add direction to Yerushalayim functionality using the Zmanim API. (For more information on calculating bearing using the API, see Calculating the Bearing/Direction to Har Habayis Using the Zmanim API article.) A large part of Jay’s motivations for developing the code was lezecher nishmas his nephew Shemuel Reuven ben Yehudit Rachel who, lost his battle with cancer on October 21, 2009. The one very minor issue Jay had with the API (and documentation) was the Ashkenazi spelling of the zmanim names, something that as an Ashekenazi I do not plan to change :), but as you can see his Android Zmanim front end used Sephardi labeling. Asked how he found the project, he answered with the typical answer to this question

I Googled around, and found your project.

One of my goals with the API was to make it easy for developers to use and port. This was confirmed by Jay

I found it to be very easy to pull into my app, even on Android…no changes necessary, not even a recompile