Forensic Zmanim Calculations

Claude Monet's Cliff at Etretat, SunsetClaude Monet's Cliff at Etretat, Sunset

Unrelated to practical zmanim calculations, it is fascinating to see that with enough work, astronomers were able to pinpoint the exact date and time that Claude Monet painted the Cliff at Etretat, Sunset painting based on the position of the sun at sunset. Researchers from Texas State University published information showing that the masterpiece was painted (or more accurately, visualized in Claude Monet's mind) at 4:53PM on February 5th, 1883.
The picture of the Kosel below was taken by my grandfather Sidney (Nesanel) Siegfried. While I can’t pinpoint the exact time the picture was taken, I do know that it was taken in the early afternoon on Aug 1st, 1932 כ״ח תמוז תרצ״ב. I leave it to the readers of this post to try and calculate the exact time the picture was taken based on the shadows.

Picture of the Kosel taken by Sidney (Nesanel) Siegfried on Aug 1, 1932 כ״ח תמוז תרצ״ב

Using the Zmanim API 1.3.0 Jewish Calendar Code

Java CalendarThe recently released Zmanim API 1.3.0 added Jewish calendar support to the API. Previously, the API had zmanim support, but no Jewish calendar support. While the calendar code is in beta mode and is subject to API changes, below are some simple code examples using the current 1.3.0 release. These examples of the use of the JewishCalendar and HebrewDateFormatter classes do not fully cover the functionality available in the Zmanim API. Please read the JavaDocs and experiment. Please let me know if there are any calendar related items that you feel should change or be added to the API.

Setting and outputting formatted dates

JewishCalendar jd = new JewishCalendar(); // current date 23 Nissan, 5773
HebrewDateFormatter hdf = new HebrewDateFormatter();
System.out.println(jd); // prints hebrew date in English chars - 23 Nissan, 5773
hdf.setHebrewFormat(true); // change formatting to Hebrew
System.out.println(hdf.format(jd)); // date formatted in Hebrew
jd.setJewishDate(5729, JewishDate.SHEVAT, 21); // set the date to 21 Shevat, 5729
System.out.println(hdf.format(jd)); // date formatted in Hebrew
jd.setJewishDate(5772, JewishDate.NISSAN, 18); // set date to third day of Pesach
System.out.println(hdf.format(jd));
System.out.println(hdf.formatYomTov(jd)); //output Chol Hamoed Pesach in Hebrew
hdf.setHebrewFormat(false); // change formatting to default
System.out.println(hdf.format(jd)); // prints Hebrew date in English chars - 18 Nissan, 5772
System.out.println(hdf.formatYomTov(jd)); //output Chol Hamoed Pesach

Output:

23 Nissan, 5773
כ״ג ניסן תשע״ג
כ״א שבט תשכ״ט
י״ח ניסן תשע״ב
חול המועד פסח
18 Nissan, 5772
Chol Hamoed Pesach

Parshas Hashavua

Please note that the parsha will only input if the date is a Shabbos. This is something that may change down the line.

HebrewDateFormatter hdf = new HebrewDateFormatter();
JewishCalendar jd = new JewishCalendar(5773, JewishDate.NISSAN, 12);
System.out.println(hdf.formatParsha(jd));
hdf.setHebrewFormat(true);
System.out.println(hdf.formatParsha(jd));
jd.back();
System.out.println("Parsha on Friday [" + hdf.formatParsha(jd) + "]"); //no Parsha output on a non Shabbos
jd.setJewishDate(5773, JewishDate.TAMMUZ, 28); //double parsha
System.out.println(hdf.formatParsha(jd));

Output:

Tzav
צו
Parsha on Friday []
מטות מסעי

Rosh Chodesh

HebrewDateFormatter hdf = new HebrewDateFormatter();
JewishCalendar jd = new JewishCalendar(5773, JewishDate.NISSAN, 1);
if(jd.isRoshChodesh()){ //not necessary for formatter
	System.out.println(hdf.formatRoshChodesh(jd));
}
hdf.setHebrewFormat(true);
System.out.println(hdf.formatRoshChodesh(jd));
jd.forward();// roll calendar to second day of Nisan
System.out.println("output[" + hdf.formatRoshChodesh(jd) + "]"); //no output for Rosh Chodesh Formatting

Output:

Rosh Chodesh Nissan
ראש חודש ניסן
output[]

Daf Yomi

JewishCalendar jd = new JewishCalendar();
HebrewDateFormatter hdf = new HebrewDateFormatter();
System.out.println(hdf.format(jd)); //output current formatted date "13 Nissan, 5773"
Daf daf = jd.getDafYomiBavli(); //get the current daf
System.out.println(daf.getMasechtaTransliterated()); //outout transliterated masechta name "Eruvin"
System.out.println(daf.getDaf()); //output current daf (page) number "16"
System.out.println(hdf.formatDafYomiBavli(daf)); //outout the formatted date "Eruvin 16"
hdf.setHebrewFormat(true); //set formatted to Hebrew
System.out.println(hdf.format(jd)); //output date in Hebrew "י״ג ניסן תשע״ג"
System.out.println(daf.getMasechta()); // output masechta name in Hebrew "עירובין"
System.out.println(hdf.formatHebrewNumber(daf.getDaf()));//output the daf number formatted in Hebrew "ט״ז"
System.out.println(hdf.formatDafYomiBavli(daf)); //output daf and masechta in Hebrew "עירובין ט״ז"

Output:

13 Nissan, 5773
Eruvin
16
Eruvin 16
י״ג ניסן תשע״ג
עירובין
ט״ז
עירובין ט״ז

Chanukah

JewishCalendar jd = new JewishCalendar(5772, JewishDate.KISLEV, 25); //set date to first day of Chanukah
HebrewDateFormatter hdf = new HebrewDateFormatter();
System.out.println(jd);//output current transliterated date
System.out.println(jd.getDayOfChanukah()); //output #1
System.out.println(hdf.formatYomTov(jd)); //output Chanukah 1
hdf.setHebrewFormat(true); //set format to hebrew
System.out.println(hdf.formatHebrewNumber(jd.getDayOfChanukah())); //output 1 in Hebrew
System.out.println(hdf.formatYomTov(jd)); // output Chanukah 1 in hebrew

Output:

25 Kislev, 5772
1
Chanukah 1
א׳
א׳ חנוכה

Note, that there is no simple way at this point to output just Chanukah. This will likely change in the future to match Chanukah to the behavior of other Yomim Tovim.

Loop and output an entire year

JewishCalendar jc = new JewishCalendar(5773, JewishDate.TISHREI, 1);
jc.setInIsrael(false); //default false for clarity but not needed. Set to true for Israel
HebrewDateFormatter hdf = new HebrewDateFormatter();
hdf.setHebrewFormat(true);
HebrewDateFormatter hdfTransliterated = new HebrewDateFormatter();
String hebrewOutput = "";
String transliteratedOutput = "";
while(jc.getJewishYear() == 5773){
	hebrewOutput = hdf.format(jc);
	transliteratedOutput = hdfTransliterated.format(jc);
	if (jc.isYomTov() || jc.isTaanis()) {
		hebrewOutput += ", " + hdf.formatYomTov(jc);
		transliteratedOutput += ", " + hdfTransliterated.formatYomTov(jc);
	} else if(jc.getDayOfWeek() == 7){
		hebrewOutput += " - " + hdf.formatParsha(jc);
		transliteratedOutput += " - " + hdfTransliterated.formatParsha(jc);
	}
	if (jc.isChanukah()) {
		if (hebrewOutput.length() > 0) {
			hebrewOutput += ", ";
			transliteratedOutput += ", ";
		}
		hebrewOutput += hdf.formatYomTov(jc);
		transliteratedOutput  += hdfTransliterated.formatYomTov(jc);
	}
	if (jc.isRoshChodesh()) {
		if (hebrewOutput.length() > 0) {
			hebrewOutput += ", ";
			transliteratedOutput += ", ";
		}
		hebrewOutput += hdf.formatRoshChodesh(jc);
		transliteratedOutput += hdfTransliterated.formatRoshChodesh(jc);
	}
	if(jc.getDayOfOmer() > 0){
		hebrewOutput += ", ";
		transliteratedOutput += ", ";
		hebrewOutput += hdf.formatOmer(jc);
	}
	System.out.println(transliteratedOutput + " - " + hebrewOutput);
	jc.forward();
}

Output (most days removed for brevity):

1 Tishrei, 5773, Rosh Hashana - א׳ תשרי תשע״ג, ראש השנה
2 Tishrei, 5773, Rosh Hashana - ב׳ תשרי תשע״ג, ראש השנה
3 Tishrei, 5773, Fast of Gedalyah - ג׳ תשרי תשע״ג, צום גדליה
4 Tishrei, 5773 - ד׳ תשרי תשע״ג
...
6 Tishrei, 5773 - Vayeilech - ו׳ תשרי תשע״ג - וילך
...
10 Tishrei, 5773, Yom Kippur - י׳ תשרי תשע״ג, יום כיפור
...
15 Tishrei, 5773, Succos - ט״ו תשרי תשע״ג, סוכות
16 Tishrei, 5773, Succos - ט״ז תשרי תשע״ג, סוכות
17 Tishrei, 5773, Chol Hamoed Succos - י״ז תשרי תשע״ג, חול המועד סוכות
18 Tishrei, 5773, Chol Hamoed Succos - י״ח תשרי תשע״ג, חול המועד סוכות
19 Tishrei, 5773, Chol Hamoed Succos - י״ט תשרי תשע״ג, חול המועד סוכות
20 Tishrei, 5773, Chol Hamoed Succos - כ׳ תשרי תשע״ג, חול המועד סוכות
21 Tishrei, 5773, Hoshana Rabbah - כ״א תשרי תשע״ג, הושענא רבה
22 Tishrei, 5773, Shemini Atzeres - כ״ב תשרי תשע״ג, שמיני עצרת
23 Tishrei, 5773, Simchas Torah - כ״ג תשרי תשע״ג, שמחת תורה
...
30 Tishrei, 5773, Rosh Chodesh Cheshvan - ל׳ תשרי תשע״ג, ראש חודש חשוון
1 Cheshvan, 5773, Rosh Chodesh Cheshvan - א׳ חשוון תשע״ג, ראש חודש חשוון
...
25 Kislev, 5773, Chanukah 1 - כ״ה כסלו תשע״ג, א׳ חנוכה
26 Kislev, 5773, Chanukah 2 - כ״ו כסלו תשע״ג, ב׳ חנוכה
27 Kislev, 5773, Chanukah 3 - כ״ז כסלו תשע״ג, ג׳ חנוכה
28 Kislev, 5773, Chanukah 4 - כ״ח כסלו תשע״ג, ד׳ חנוכה
29 Kislev, 5773, Chanukah 5 - כ״ט כסלו תשע״ג, ה׳ חנוכה
1 Teves, 5773, Chanukah 6, Rosh Chodesh Teves - א׳ טבת תשע״ג, ו׳ חנוכה, ראש חודש טבת
2 Teves, 5773 - Miketz, Chanukah 7 - ב׳ טבת תשע״ג - מקץ, ז׳ חנוכה
3 Teves, 5773, Chanukah 8 - ג׳ טבת תשע״ג, ח׳ חנוכה
...
10 Teves, 5773, Tenth of Teves - י׳ טבת תשע״ג, עשרה בטבת
...
15 Shevat, 5773, Tu B'Shvat - ט״ו שבט תשע״ג, ט״ו בשבט
...
21 Shevat, 5773 - כ״א שבט תשע״ג
...
11 Adar, 5773, Fast of Esther - י״א אדר תשע״ג, תענית אסתר
...
14 Adar, 5773, Purim - י״ד אדר תשע״ג, פורים
15 Adar, 5773, Shushan Purim - ט״ו אדר תשע״ג, פורים שושן
...
27 Adar, 5773 - Vayakhel Pekudei - כ״ז אדר תשע״ג - ויקהל פקודי
...
15 Nissan, 5773, Pesach - ט״ו ניסן תשע״ג, פסח
16 Nissan, 5773, Pesach,  - ט״ז ניסן תשע״ג, פסח, א׳ בעומר
17 Nissan, 5773, Chol Hamoed Pesach,  - י״ז ניסן תשע״ג, חול המועד פסח, ב׳ בעומר
18 Nissan, 5773, Chol Hamoed Pesach,  - י״ח ניסן תשע״ג, חול המועד פסח, ג׳ בעומר
19 Nissan, 5773, Chol Hamoed Pesach,  - י״ט ניסן תשע״ג, חול המועד פסח, ד׳ בעומר
20 Nissan, 5773, Chol Hamoed Pesach,  - כ׳ ניסן תשע״ג, חול המועד פסח, ה׳ בעומר
21 Nissan, 5773, Pesach,  - כ״א ניסן תשע״ג, פסח, ו׳ בעומר
22 Nissan, 5773, Pesach,  - כ״ב ניסן תשע״ג, פסח, ז׳ בעומר
23 Nissan, 5773,  - כ״ג ניסן תשע״ג, ח׳ בעומר
...
26 Nissan, 5773 - Shmini,  - כ״ו ניסן תשע״ג - שמיני, י״א בעומר
...
6 Sivan, 5773, Shavuos - ו׳ סיוון תשע״ג, שבועות
7 Sivan, 5773, Shavuos - ז׳ סיוון תשע״ג, שבועות
...
17 Tammuz, 5773, Seventeenth of Tammuz - י״ז תמוז תשע״ג, שבעה עשר בתמוז
...
9 Av, 5773, Tishah B'Av - ט׳ אב תשע״ג, תשעה באב
...
15 Av, 5773, Tu B'Av - ט״ו אב תשע״ג, ט״ו באב
...

Zmanim API 1.3.0 Released

Zmanim API 1.3.0 ReleaseThe Zmanim API version 1.3.0 was released on March 4th, 2013 כ״א אדר תשע״ג. Various changes in the new release VS the previous version 1.2.1 that was released in May 2010 can be seen below. This release includes beta support for Jewish Calendar calculations as well as a number of updated zmanim and refactored code. The Jewish Calendar support in the Zmanim API is based on Avrom Finkelstien’s HebrewDate project released in 2002. Unlike the Zmanim code, the Jewish calendar interfaces may change significantly in the future (see Jay Gindin’s various changes that may make it into this API) and should therefore be considered beta.

Changes in the Zmanim API 1.3.0 release

Changes since March 23, 2011 have been in SVN and detailed changes can be seen there.

Zmanim Map 3.5 adds Date and Algorithm Selection

World mapThe Zmanim Map was recently updated to version 3.5. This new release adds a number of new features (listed below), and some technical changes over the previous Zmanim Map 3.0 release. With this release, the main focus of the map has shifted to the zmanim tabs. The direction to Yerushalayim tab with davening directions using both the rhumb line and great circle route to Yerushalayim is still present, but is no longer the default tab.

Zmanim Map v3.5

  • The date can now be selected by the user. In previous versions the date was always the current date on the user’s computer (though the map always supported passing the date on the URL using the undocumented date=1969-02-08 parameter). The current date is still the default, but the user can now change the date.
  • The calculation algorithm is now selectable. The Zmanim API supports both the USNO and NOAA algorithms. The map has always used the USNO algorithm, and this remains the default, but users can now use the NOAA algorithm.
  • The Zmanim tab is now the default tab. This reflects user feedback indicating that most people use the map for zmanim.
  • An About tab now provides a mini user guide and general information about the map.
  • The timezone look-up now uses the Google Timezone API. Previously the map had been using the Geo Names web service. Since the elevation service also uses Google, the change to a single stable source will hopefully result in fewer outages.
  • The currently selected tab persists across location changes, so if you were viewing zmanim for a location, and changed the location to see how the zmanim were affected, you will no longer have to change tabs after each move.
  • Candle Lighting was added for Fridays. Erev Yom Tov will not show candle lighting at this point.
  • Performance improvements, minor enhancements, bug fixes and refactoring

KosherJava Zmanim API Powering Many Mobile Apps

Mobile apps using Kosher Java Zmanim APIIn the past I posted about Android Zmanim, Jay Gindin’s open source zmanim project that uses the KosherJava Zmanim API. The fact that Android development uses Java natively means that it is very simple for Android developers to include zmanim in their apps. Since that time there have been a number of other applications (including iPhone apps) using the code. Moshe’s KosherCocoa Obj-C port of the KosherJava Zmanim API will probably result in additional iPhone apps that use the API. Yitzchok’s older Zmanim .NET port of the KosherJava Zmanim API also opened the door for Windows Phone zmanim applications as well (Ari Polski’s Zmaim app already uses it, and there are others in the works). I may post additional details about some of them in the future, including an updated post about Jay’s latest Android Zmanim release. I am aware of the following mobile applications that use the KosherJava Zmanim API.

There are also a few secular apps that are non-zmanim specific that use the API for sunrise and sunset calculations. One that I know of is Jeffrey Blattman’s Dawn to Dusk Widget, and I know that there are some photography apps that use it for sunrise/set calculations as well. There are likely more that I have missed, and a few that are in active development but unreleased. If you are aware of any missed apps, please let me know.

FAQ: Outputting Zmanim for A Different Time Zone With the the Zmanim API

Zmanim API FAQ

Question:

Why does the output of zmanim for a different time zone appear incorrect?

Answer:

One of the common issues encountered by developers using the API is that zmanim generated for a different time zone than the user’s time zone may return output that appears incorrect. For example a user in Lakewood, NJ trying to calculate sunrise for Yerushalayim may attempt to use the following code:

String locationName = "Jerusalem";
double latitude = 31.778; // Har habayis
double longitude = 35.2354;// Har Habayis
double elevation = 0;
TimeZone timeZone = TimeZone.getTimeZone("Asia/Jerusalem");
GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
ZmanimCalendar zc = new ZmanimCalendar(location);
zc.getCalendar().set(2011, Calendar.FEBRUARY, 8);
System.out.println("Sunrise: " + zc.getSunrise());
System.out.println("Sunset: " + zc.getSunset());

While you would expect a sunrise of 6:27:41 AM and sunset of 5:19:19 PM, running this code on a computer anywhere in the Eastern Standard time zone would generate the following time that appears to be 7 hours early:

Sunrise: Mon Feb 07 23:27:41 EST 2011
Sunset: Tue Feb 08 10:19:19 EST 2011

The issue is simple, and the sunrise and sunset returned above are actually accurate. Zmanim are returned by the Zmanim API as a Java Date object that represents a moment in time (stored internally by Java as Unix Time – the number of milliseconds since the January 1, 1970 GMT). Sunrise in Yerushalayim on February 8th actually happens at 11:27:41 PM on February 7th EST. Java is simply outputting the Date as a String formatted to the users default time zone (EST in this example). The user probably intends to output the time in IST – Israel Standard Time (“Asia/Jerusalem” in the Olson database). To do this you have to output the zmanim using a formatter set to use the “Asia/Jerusalem” time zone.

DateFormat zmanimFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
zmanimFormat.setTimeZone(location.getTimeZone());

System.out.println("sunrise: " + zmanimFormat.format(zc.getSunrise()));
System.out.println("sunset:" + zmanimFormat.format(zc.getSunset()));

will output the expected

sunrise: Tue Feb 08 06:27:41 IST 2011
sunset:Tue Feb 08 17:19:19 IST 2011

Below is the full code example.

import net.sourceforge.zmanim.*;
import net.sourceforge.zmanim.util.*;
import java.util.TimeZone;
public class FormatZmanim{
	public static void main(String [] args) {
		String locationName = "Jerusalem";
		double latitude = 31.778; //latitude of Har habayis
		double longitude = 35.2354; //longitude of Har Habayis
		double elevation = 0; //optional elevation
		//use a Valid Olson Database timezone listed in java.util.TimeZone.getAvailableIDs()
		TimeZone timeZone = TimeZone.getTimeZone("Asia/Jerusalem");
		//create the location object
		GeoLocation location = new GeoLocation(locationName, latitude, longitude, elevation, timeZone);
		ZmanimCalendar zc = new ZmanimCalendar(location); //create the ZmanimCalendar
		zc.getCalendar().set(2011, Calendar.FEBRUARY, 8); //set the date
		DateFormat zmanimFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy"); //Create the formatter
		zmanimFormat.setTimeZone(location.getTimeZone()); //set the formatter's time zone
		System.out.println("sunrise: " + zmanimFormat.format(zc.getSunrise()));
		System.out.println("sunset:" + zmanimFormat.format(zc.getSunset()));
	}
}