paint-brush
Time Data Series: A Beginner's Guide to PHP Zmanimby@leonadato
273 reads

Time Data Series: A Beginner's Guide to PHP Zmanim

by Leon AdatoMarch 11th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

A tutorial covering both the theory and practical information needed to use the PHP Zmanim library to calculate Jewish religious times.
featured image - Time Data Series: A Beginner's Guide to PHP Zmanim
Leon Adato HackerNoon profile picture
                    Time Data Series: Getting Started with PHP Zmanim - AdatoSystems                                                     

Acknowledgments

In this blog, I’m explaining concepts and techniques related to both the way so-called “Jewish times” (zmanim) are calculated, as well as the techniques needed to use the PHP Zmanim library – a library of functions that let you easily calculate Jewish times.


The PHPZmanim library is maintained by Zachary Weixelbaum. As with so many things in tech today, PHP Zmanim is itself based on the foundational Kosher Java library by Eliyahu Hershfeld. I owe a huge debt of gratitude to both Zachary and Eliyahu – not only for the work they put into developing those libraries but also for the support they have given me as I came up to speed on both the technical and Jewish religious guidelines (halacha) needed to use them.


Introduction

“What time will afternoon prayers (Mincha) be this week?” is a deceptively complex question. It’s deceptive because “afternoon prayers” seems to be self-explanatory, but (as with so many things related to Jewish religious rules (halacha) there’s a vast amount of background, commentary, and specificity required.


NOTE: If you are already comfortable with Jewish time concepts (zmanim), feel free to skip to the section labeled “Installing PHP Zmanim.” I won’t be insulted nor hold it against you.


It’s difficult to understand the importance of accurate time calculations on the Jewish religious day, week, and life. It figures into everything from when a fast starts and ends to when it’s too late (or too early) to say certain prayers to the moment when simply owning (let alone eating) bread is forbidden.


To put it another way, I’ll share a quote from Rabbi Abraham Joshua Heschel in his book “The Sabbath”,


The meaning of the Sabbath is to celebrate time rather than space. Six days a week we live under the tyranny of things of space; on the Sabbath we try to become attuned to holiness in time.

Rabbi Abraham Joshua Heschel, “The Sabbath”


Even with that explanation, some readers may still wonder, “Why make such a big deal about it? Are you telling me God is going to hold it against you if you’re 5 minutes off?”


It’s a valid question and worth a moment of discussion because otherwise, the need for, let alone the impact of, this blog (and the techniques and technologies it describes) is diminished.


No, of course, God doesn’t care. Just like my track coach doesn’t “care” if I warm up before running, do my off-season workouts, or drink enough water. Let’s face it: no matter how hard I train, my coach won’t be any healthier. However, my coach – who cares for me beyond my performance in the next race, wants ME to care. They want me to be fully committed, if only because they know my experience will be more fulfilling because of it.


In the same way, God doesn’t “care.” But we know (through the texts of the Torah and Talmud) that God wants the US to care. And so Jewish scholars through the millennia have attempted – using the evidence presented in the text – to eschew simple and simplistic answers and dig deeper to uncover the details.


Back to the question at hand: “What time are afternoon prayers?” To understand that, we have to first understand what defines “day” (versus “night”), how to understand what demarcation separates “morning” from “afternoon,” how to effectively divide the day into parts, and so much more.


While this blog will introduce some of these concepts and terms as needed, it should not be considered exhaustive by any stretch of the imagination.


It comes as no surprise that computers have made quick work of calculating these times, and now there’s a wide array of websites and applications ready to do the job for us. Even for those who want to create their own programs to do these calculations, there are time-saving solutions in the form of code libraries like KosherJava and its many ports, including PHPSwift.NetJavaScriptPython, and many more.


Nevertheless, it’s important to understand the theory behind the tools. Anyone who wants to create a website or app has to be certain their program isn’t inadvertently giving the wrong times. While, as mentioned earlier, nobody will “go to hell” (so to speak) for praying at the wrong time, there is a strict commandment:


וְלִפְנֵ֣י עִוֵּ֔ר לֹ֥א תִתֵּ֖ן מִכְשֹׁ֑ל וְיָרֵ֥אתָ מֵּאֱלֹהֶ֖יךָ“lifnei iver lo titein michshol v’yareita mei-elohecha”“Don’t put a stumbling block before the blind”

(Leviticus 19:14)


It’s one thing if an individual gets something wrong by accident. It’s quite another to provide bad information that causes someone (or worse, LOTS of folks) to make a mistake, believing the information they got (from your app) was accurate and trustworthy.

The Basic Times

With that in mind, we’ll start with understanding the times that are fairly straightforward and the least affected by variations in Jewish tradition:

  • Sunrise (Netz Hachma) is a good old nautical sunrise – the moment when the top edge of the disk of the sun touches the horizon.
  • Sunset (Shkia) is the other side of the daily coin – the moment when the top edge of the sun drops just below the horizon.
  • A “seasonal hour” (sha’ah) refers to the even division of daylight, the time between sunrise and sunset. There are always 12 seasonal hours, but they may be longer or shorter than a regular (on your clock) hour because the amount of daylight fluctuates with the season.
    • Note that some traditions calculate a sha’ah as 12 divisions of the time from dawn (alot hashachar, or just “alot” when light is visible over the horizon, but before sunrise itself) to night (tzeis hakochavim, or just “tzeis”, when NO light is visible over the horizon, after sunset). We’ll get more into both dawn (a lot) and night (tzeit) later in the blog.
  • Seasonal minutes (sha’ot zmaniyot) is 1/60 of a seasonal hour and, just like a seasonal hour, may be larger or smaller than a minute on your clock.


As you can see, sunrise and sunset form the fundamental core of all other time calculations, and a great number of important Jewish times during the day are derived directly from those. For example, in some traditions, you’ll find:

  • Shabbat begins on Friday night, 18 minutes before sunset (shkia)
  • Shabbat ends on Saturday night 45 (or 50, or 72) minutes after sunset (shkia)
  • …and so on.

Calculations where “It’s Complicated”

Once you have sunrise and sunset nailed down, the next step is to identify the two critical times of dawn and night. Dawn (Alot haShachar, or just “Alot”) and night (Tzeis hakochavim, or just “Tzeis”) mirror each other the way sunrise and sunset do. Dawn is the moment when light (but not the sun) is visible over the horizon. Night is the moment when light is no longer visible.


Unfortunately, whether or not there is or isn’t “light” is highly subjective, and therefore, the way it’s calculated ranges all over the map.

  • Some traditions use a fixed number of clock minutes before sunrise or after sunset.
  • Others will use astronomy to identify the time when the sun is below the horizon by a specific number of degrees.
  • Others will use a formula, such as taking the amount of daylight (from sunrise to sunset), dividing that into 10 equal parts, and then subtracting that amount from sunrise or adding it to sunset.
  • Still, others will take the time the sun is below the horizon on an “equal” day (meaning the spring or fall equinox, when the amount of sunshine and darkness are exactly the same), calculate the difference (in clock minutes) between that time and sunrise, normalize those minutes against “seasonal minutes” (“sha’ot zmaniyot”) for the specific day in question, and finally subtract that amount from sunrise (or add THAT to sunset) for the day in question.


Sound confusing? As the title of this section says, “It’s complicated.”


My point in describing these isn’t to settle on a single “correct” calculation but rather to help you understand the ultimate goal of each type of calculation – as well as for you to understand that there are multiple ways different Jewish traditions arrive at each calculation.

The Complex times

Once you have dawn (alot), sunrise (netz), sunset (shkia), and night (tzeis), it becomes possible to calculate other important daily times. These include:

  • The earliest time for afternoon prayers (Mincha Gedola), which is often calculated as a certain number of seasonal hours (sha’ah) after either dawn or sunrise. The point of this time is that it is the earliest moment when “afternoon” (literally, after mid-day) happens.
  • The preferable time for afternoon prayers (Mincha ketana), which is calculated as a larger number of seasonal hours (sha’ah) after either sunrise (netz) or dawn (alot). The point here is that it’s more than 3/4 of the way through the day, when it’s CLEARLY afternoon – but without the risk of it accidentally being night (tzeis).
  • The latest time for afternoon prayers (Plag haMincha, or “plag”) , which is often calculated as the time between the best time for afternoon prayers (mincha ketana) and night (tzeis).


While there are several other key times that we’ll get to in a different blog, these are enough to get us started.

Installing the PHP Zmanim Library

With those technical details taken care of, we can now move on to… some technical details! Except this time, they are TECHNICAL technical details. (and for those people who skipped all the way from the introduction to this section, WELCOME! It’s great to have you back!)


PHP Zmanim is a complex library that comprises not just the import of Kosher Java into the PHP language but also some supporting modules like Carbon (a tool that helps make date and time conversions faster, easier, and more accurate); Symfony (a web design framework); and a few other smaller utilities.


The point is that all those modules work in concert with PHP Zmanim, and you need all of them installed for anything to work. The easiest way to get them all installed is using the PHP “composer” utility that manages dependencies.


If you need to run PHP Zmanim on a web server and don’t have access to run installers at the command line, you’re still in luck. Simply copy the ./vendor directory from a local installation, and – with some caveats – it will work.


What are those caveats? The main one is to make sure the version of PHP supported by your hosting provider matches the one you use when installing via Composer.


This brings me to the actual composer install command. I know we haven’t gotten to actually coding anything yet, but let’s set up a directory where the scripts are going to go. For this blog, I’m going to call it /phpzmanim_test.


In a terminal window, move to that directory:

cd /php zmanim_test


Now type the command:

composer -V

(note that’s a capital V)


This will confirm whether composer is installed or not. If not, do a quick search to find out the best way to get it installed on your operating system.


Next, type the command:composer require zachweix/php-zmanim


This will do two things:

  1. First, it will create the file composer.json in the current directory, with instructions that PHP Zmanim should be installed.
  2. It actually installs PHP Zmanim for you, into a ./vendor directory inside the current directory. No extra steps are needed.


The only other “composer” related item to note is that if you ever need to update, you can do so easily by going into the /phpzmanim_test directory (or whatever you called yours) and typing the command composer update. This will read the information in the composer.json file and update everything it finds there.


(SPOILER: this means you should NOT delete the composer.json file. You don’t, however, have to copy it to your remote site with the rest of your application if you don’t want to.)


Once this is done, you need to include the following line in every PHP script that will use the PHP Zmanim library:

require 'vendor/autoload.php';

Getting Started with PHP Zmanim

Now that PHP Zmanim is installed, you’re ready to start writing some code with it.


To do this, you’ll first create a php object – a collection (array, really) of data that are passed into various functions. This object contains both the specific date for the times you’ll want to pull and also the precise location information.

Creating an object with “Zmanim::create()”

Before you start, you’ll need to know a few things about the location where you are asking for times:

  • The latitude and longitude.
  • The time zone is formatted using the tz database format. (example: “America/New_York”).
  • The elevation of that location, if you choose to use it. (SPOILER: very rarely does elevation factor into these calculations.)
  • The year, month, and day of the times you’ll be calculating.


The format for creating your object is:

$VARNAME = Zmanim::create(YEAR, MONTH, DAY, "NAME OF LOCATION", LATITUDE, LONGITUDE, ELEVATION, "TIME ZONE");


Here’s a specific example:

$zmanim = Zmanim::create(2019, 2, 21, "New York City", 40.850519, -73.929214, 200, "America/New_York");


What that looks like as a script with some variables in place of the literal input:

<?php
require 'vendor/autoload.php';
use PhpZmanim\Zmanim;
use PhpZmanim\Calendar\ComplexZmanimCalendar;
use PhpZmanim\Geo\GeoLocation;

$getdate = date('Y-m-d');
$getyear = date('Y', strtotime($getdate));
$getmonth = date('m', strtotime($getdate));
$getday = date('d', strtotime($getdate));

$locname = "Beit Knesset Chochmat Shlomo, Beachwood, OH";
$lat = 41.4939407;
$long = -81.516709;
$elev = 0;
$tz = 'America/New_York';

$zmanim = Zmanim::create($getyear, $getmonth, $getday, $locname, $lat, $long, $elev, $tz);


With that code in place, you have an object for today’s date, for the specified location. You can even print it out using PHP’s print_r() function:

print_r($zmanim);


Which should give you output that looks something like this:

PhpZmanim\Zmanim Object
(
    [calendar:PhpZmanim\Calendar\AstronomicalCalendar:private] => Carbon\Carbon Object
        (
            [endOfTime:protected] => 
            [startOfTime:protected] => 
            [constructedObjectId:protected] => 00000000000000080000000000000000
            [localMonthsOverflow:protected] => 
            [localYearsOverflow:protected] => 
            [localStrictModeEnabled:protected] => 
            [localHumanDiffOptions:protected] => 
            [localToStringFormat:protected] => 
            [localSerializer:protected] => 
            [localMacros:protected] => 
            [localGenericMacros:protected] => 
            [localFormatFunction:protected] => 
            [localTranslator:protected] => 
            [dumpProperties:protected] => Array
                (
                    [0] => date
                    [1] => timezone_type
                    [2] => timezone
                )

(there’s more, but you get the idea).

Getting your first real-time – Sunrise (Netz HaHachma)

Once you have an object created, using it to get specific times through PHP Zmanim is almost anti-climactic. Getting sunrise is as simple as:

$sunrise = $zmanim->sunrise;


If you aren’t familiar with it or haven’t used it before, the -> indicates you’re querying an object (again, a collection of data elements) or using a built-in method.


This will return something that looks like this:

2024-12-20 07:48:52


For those following along, the complete code so far looks like this:

<?php
require 'vendor/autoload.php';
use PhpZmanim\Zmanim;
use PhpZmanim\Calendar\ComplexZmanimCalendar;
use PhpZmanim\Geo\GeoLocation;


# Set variables:
#41.4939407, -81.516709;
$locname = "Beit Knesset Chochmat Shlomo, Beachwood, OH";
$lat = 41.4939407;
$long = -81.516709;
$elev = 0;
$tz = 'America/New_York';

$getyear = 2024;
$getday = 20;
$getmonth = 12;
$testzmanim = Zmanim::create($getyear, $getmonth, $getday, $locname, $lat, $long, $elev, $tz);
$sunrise = $testzmanim->sunrise;
echo "$sunrise\n";
?>

Summary

There is a lot more to cover in PHP Zmanim, which I plan to do in the coming weeks. But this should at least get you started with building a PHP-based script or website and displaying accurate times for Jewish moments.


As always, I welcome questions, corrections, and kudos in the comments below.


Also published here.