1
0
Fork 0

feat: use customizer to more accurately generate calendar data file

feat: brand new UI to display upcoming/current calendar events
feat: add holidays, shabbat torah readings, and time display to clock
master
Michael Salaverry 2022-02-09 23:11:02 +02:00 committed by Michael Salaverry
parent b7b64c2cfe
commit 34f02fd1da
8 changed files with 569 additions and 351 deletions

View File

@ -1,4 +1,6 @@
0.01: New App!
0.02: using TS and rollup to bundle
0.03: bug fixes and support bangle 1
0.04: removing TS
0.04: removing TS
0.05: major overhaul; now you customize your calendar based on your location for candle lighting times
0.06: bug fixes and improvements

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,19 +1,22 @@
# Hebrew Calendar
Displays the current hebrew calendar date
Add screen shots (if possible) to the app folder and link then into this file with ![](<name>.png)
Displays the current hebrew calendar date and upcoming holidays alongside a clock
![](./HebrewCalendar-Screenshot.png)
## Usage
Open the app, and it shows a menu with the date components
Set it up as your clock in the settings
## Features
Shows the hebrew date, month, and year; alongside the gregorian date
- Shows the hebrew date, month, and year; alongside the gregorian date
- Shows when upcoming holidays start
- Shows the gregorian day of week, date, and current time
## Controls
Name the buttons and what they are used for
N/A
## Requests
@ -22,5 +25,5 @@ Michael Salaverry (github.com/barakplasma)
## Creator
Michael Salaverry
with help from https://github.com/IonicaBizau/hebrew-date (MIT license)
with help from https://github.com/hebcal/hebcal-es6 (MIT license) which is used to calculate the calendar
<div>Icons made by <a href="https://www.flaticon.com/authors/smashicons" title="Smashicons">Smashicons</a> from <a href="https://www.flaticon.com/" title="Flaticon">[www.flaticon.com](https://www.flaticon.com/premium-icon/calendar_3130060?term=jewish&page=1&position=10&page=1&position=10&related_id=3130060&origin=tag)</a></div>

View File

@ -1,26 +1,181 @@
g.clear();
const dayInMS = 86400000;
let now = new Date();
const DateProvider = { now: () => Date.now() };
let today = require('hebrewDate').hebrewDate(now);
const Layout = require("Layout");
const Locale = require("locale");
var mainmenu = {
"": {
"title": "Hebrew Date"
},
greg: {
// @ts-ignore
value: require('locale').date(now, 1),
},
date: {
value: today.date,
},
month: {
value: today.month_name,
},
year: {
value: today.year,
let nextEndingEvent;
function getCurrentEvents() {
const now = DateProvider.now();
const current = hebrewCalendar.filter(
(x) => x.startEvent <= now && x.endEvent >= now
);
nextEndingEvent = current.reduce((acc, ev) => {
return Math.min(acc, ev.endEvent);
}, Infinity);
return current.map((event, i) => {
return {
type: "txt",
font: "12x20",
id: "currentEvents" + i,
label: event.desc,
pad: 2,
bgCol: g.theme.bg,
};
});
}
function getUpcomingEvents() {
const now = DateProvider.now();
const futureEvents = hebrewCalendar.filter(
(x) => x.startEvent >= now && x.startEvent <= now + dayInMS
);
let warning;
let eventsLeft = hebrewCalendar.filter(
(x) => x.startEvent >= now && x.startEvent <= now + dayInMS * 14
).length;
if (eventsLeft < 14) {
warning = {
startEvent: 0,
type: "txt",
font: "4x6",
id: "warning",
label: "only " + eventsLeft + " events left in calendar; update soon",
pad: 2,
bgCol: g.theme.bg,
};
}
};
// @ts-ignore
E.showMenu(mainmenu);
return futureEvents
.slice(0, 2)
.map((event, i) => {
return {
startEvent: event.startEvent,
type: "txt",
font: "6x8",
id: "upcomingEvents" + 1,
label: event.desc + " at " + Locale.time(new Date(event.startEvent), 1),
pad: 2,
bgCol: g.theme.bg,
};
})
.concat(warning)
.sort(function (a, b) {
return a.startEvent - b.startEvent;
});
}
function dateTime() {
return (
Locale.dow(new Date(), 1) +
" " +
Locale.date(new Date(), 1) +
" " +
Locale.time(new Date(), 1)
);
}
function makeLayout() {
return new Layout(
{
type: "v",
c: [
{
type: "txt",
font: "6x8",
id: "title",
label: "-- Hebrew Calendar Events --",
pad: 2,
bgCol: g.theme.bg2,
},
{
type: "txt",
font: "6x8",
id: "currently",
label: "Currently",
pad: 2,
bgCol: g.theme.bgH,
},
]
.concat(getCurrentEvents())
.concat([
{
type: "txt",
font: "6x8",
label: "Upcoming",
id: "upcoming",
pad: 2,
bgCol: g.theme.bgH,
},
])
.concat(getUpcomingEvents())
.concat([
{
type: "txt",
font: "Vector14",
id: "time",
label: dateTime(),
pad: 2,
bgCol: undefined,
},
]),
},
{ lazy: true }
);
}
let layout = makeLayout();
// see also https://www.espruino.com/Bangle.js+Layout#updating-the-screen
// timeout used to update every minute
let drawTimeout;
function draw() {
layout.time.label = dateTime();
layout.render();
// schedule a draw for the next minute
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function () {
drawTimeout = undefined;
draw();
}, 60000 - (DateProvider.now() % 60000));
console.log("updated time");
}
// update time and draw
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
draw();
function findNextEvent() {
return hebrewCalendar.find((ev) => {
return ev.startEvent > DateProvider.now();
});
}
function updateCalendar() {
layout.clear();
layout = makeLayout();
layout.forgetLazyState();
layout.render();
let nextChange = Math.min(
findNextEvent().startEvent - DateProvider.now() + 5000,
nextEndingEvent - DateProvider.now() + 5000
);
setTimeout(updateCalendar, nextChange);
console.log("updated events");
}
updateCalendar();
Bangle.setUI("clock");

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hebrew Calendar Customizer</title>
<link rel="stylesheet" href="https://banglejs.com/apps/css/spectre.min.css">
</head>
<body>
<div class="container grid-sm">
<div class="panel center">
<div class="panel-header">
<div class="panel-title text-center h5 mt-10">Hebrew Calendar Loader</div>
</div>
<div class="panel-body">
<div class="h4">Your location</div>
<form method="GET">
<div class="form-group">
<label class="form-label" for="lat">Latitude</label>
<input class="form-input" type="number" id="lat" name="lat" required min="-90" max="90" step="0.0000001" value="31.776580" placeholder="31.776580">
<label class="form-label" for="lon">Longitude</label>
<input class="form-input" type="number" id="lon" name="lon" required min="-180" max="180" step="0.0000001" value="35.233706" placeholder="35.233706">
<div>get your latitude and longitude from <a href="https://plus.codes/map">plus.codes</a> or:</div>
<button class="btn btn-secondary input-group-btn" id="geoloc">Get Latitude and Longitude automatically (using location permission)</button>
<label class="form-switch">
<input type="checkbox" id="inIL" name="inIL" checked>
<i class="form-icon"></i> In Israel?
</label>
<button class="btn btn-primary input-group-btn" type="submit">Upload</button>
</div>
</form>
</div>
<div class="panel-footer">
<div class="text-center h6"><a href="https://github.com/hebcal/hebcal-es6">With help from @hebcal/core</a></div>
<div class="text-center" id="hDate"></div>
</div>
</div>
<script src="https://banglejs.com/apps/core/lib/customize.js"></script>
<script type="module" src="customizer.mjs"></script>
</div>
</body>
</html>

View File

@ -0,0 +1,329 @@
import {
HebrewCalendar,
HDate,
Location,
Zmanim,
} from "https://cdn.skypack.dev/@hebcal/core@^3?min";
function onload(event) {
event.preventDefault();
const latLon = getLatLonFromForm();
const events = generateHebCal(latLon);
const calendar = serializeEvents(events);
console.debug(calendar);
globalThis["cal"] = calendar;
loadWatch(calendar);
}
function loadWatch(json) {
sendCustomizedApp({
id: "hebrew_calendar",
storage: [
{
name: "hebrew_calendar.app.js",
url: "app.js",
// content below is same as app.js except for the first line which customizes the hebrewCalendar object used
content: `
let hebrewCalendar = ${json};
const dayInMS = 86400000;
const DateProvider = { now: () => Date.now() };
const Layout = require("Layout");
const Locale = require("locale");
let nextEndingEvent;
function getCurrentEvents() {
const now = DateProvider.now();
const current = hebrewCalendar.filter(
(x) => x.startEvent <= now && x.endEvent >= now
);
nextEndingEvent = current.reduce((acc, ev) => {
return Math.min(acc, ev.endEvent);
}, Infinity);
return current.map((event, i) => {
return {
type: "txt",
font: "12x20",
id: "currentEvents" + i,
label: event.desc,
pad: 2,
bgCol: g.theme.bg,
};
});
}
function getUpcomingEvents() {
const now = DateProvider.now();
const futureEvents = hebrewCalendar.filter(
(x) => x.startEvent >= now && x.startEvent <= now + dayInMS
);
let warning;
let eventsLeft = hebrewCalendar.filter(
(x) => x.startEvent >= now && x.startEvent <= now + dayInMS * 14
).length;
if (eventsLeft < 14) {
warning = {
startEvent: 0,
type: "txt",
font: "4x6",
id: "warning",
label: "only " + eventsLeft + " events left in calendar; update soon",
pad: 2,
bgCol: g.theme.bg,
};
}
return futureEvents
.slice(0, 2)
.map((event, i) => {
return {
startEvent: event.startEvent,
type: "txt",
font: "6x8",
id: "upcomingEvents" + 1,
label: event.desc + " at " + Locale.time(new Date(event.startEvent), 1),
pad: 2,
bgCol: g.theme.bg,
};
})
.concat(warning)
.sort(function (a, b) {
return a.startEvent - b.startEvent;
});
}
function dateTime() {
return (
Locale.dow(new Date(), 1) +
" " +
Locale.date(new Date(), 1) +
" " +
Locale.time(new Date(), 1)
);
}
function makeLayout() {
return new Layout(
{
type: "v",
c: [
{
type: "txt",
font: "6x8",
id: "title",
label: "-- Hebrew Calendar Events --",
pad: 2,
bgCol: g.theme.bg2,
},
{
type: "txt",
font: "6x8",
id: "currently",
label: "Currently",
pad: 2,
bgCol: g.theme.bgH,
},
]
.concat(getCurrentEvents())
.concat([
{
type: "txt",
font: "6x8",
label: "Upcoming",
id: "upcoming",
pad: 2,
bgCol: g.theme.bgH,
},
])
.concat(getUpcomingEvents())
.concat([
{
type: "txt",
font: "Vector14",
id: "time",
label: dateTime(),
pad: 2,
bgCol: undefined,
},
]),
},
{ lazy: true }
);
}
let layout = makeLayout();
// see also https://www.espruino.com/Bangle.js+Layout#updating-the-screen
// timeout used to update every minute
let drawTimeout;
function draw() {
layout.time.label = dateTime();
layout.render();
// schedule a draw for the next minute
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function () {
drawTimeout = undefined;
draw();
}, 60000 - (DateProvider.now() % 60000));
console.log("updated time");
}
// update time and draw
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
draw();
function findNextEvent() {
return hebrewCalendar.find((ev) => {
return ev.startEvent > DateProvider.now();
});
}
function updateCalendar() {
layout.clear();
layout = makeLayout();
layout.forgetLazyState();
layout.render();
let nextChange = Math.min(
findNextEvent().startEvent - DateProvider.now() + 5000,
nextEndingEvent - DateProvider.now() + 5000
);
setTimeout(updateCalendar, nextChange);
console.log("updated events");
}
updateCalendar();
Bangle.setUI("clock");
`,
},
],
});
}
document
.querySelector("button[type=submit]")
.addEventListener("click", onload, false);
document.querySelector("#geoloc")?.addEventListener("click", (event) => {
event.preventDefault();
navigator.geolocation.getCurrentPosition(
(pos) => {
const {
coords: { latitude, longitude },
} = pos;
locationElements[0].value = latitude;
locationElements[1].value = longitude;
console.debug(pos);
},
(err) => {
if (err.PERMISSION_DENIED) {
alert("permission required to use geolocation api; enter manually");
}
if (err.POSITION_UNAVAILABLE) {
alert("position unavailable; enter manually");
}
},
{ enableHighAccuracy: false }
);
});
document.querySelector(
"#hDate"
).innerText = `Today is ${new Date().toLocaleDateString()} & ${new HDate().toString()}`;
const locationElements = [
document.querySelector("#lat"),
document.querySelector("#lon"),
];
function getLatLonFromForm() {
const latLon = locationElements.map((el) => el.value);
if (locationElements.every((x) => x.checkValidity())) {
return latLon;
} else {
console.debug("lat lon invalid error");
return [0, 0];
}
}
function groupBy(arr, fn) {
return arr
.map(typeof fn === "function" ? fn : (val) => val[fn])
.reduce((acc, val, i) => {
acc[val] = (acc[val] || []).concat(arr[i]);
return acc;
}, {});
}
function generateHebCal(latLon) {
const location = new Location(
...latLon,
document.querySelector("#inIL").checked
);
const now = new Date();
const options = {
year: now.getFullYear(),
isHebrewYear: false,
candlelighting: true,
location,
addHebrewDates: true,
addHebrewDatesForEvents: true,
sedrot: true,
start: now,
end: new Date(now.getFullYear(), now.getMonth() + 3),
};
const events = HebrewCalendar.calendar(options).map((ev) => {
const { desc, eventTime, startEvent, endEvent } = ev;
const zman = new Zmanim(ev.date, ...latLon.map(Number));
let output = {
desc,
startEvent: startEvent?.eventTime?.getTime() || zman.gregEve().getTime(),
endEvent: endEvent?.eventTime?.getTime() || zman.shkiah().getTime(),
};
if (eventTime) {
delete output.startEvent;
delete output.endEvent;
output.startEvent = eventTime.getTime();
output.endEvent = eventTime.getTime() + 60000 * 15;
}
return output;
});
// console.table(events)
return events.sort((a, b) => {
return a.startEvent - b.startEvent;
});
}
function enc(data) {
return btoa(heatshrink.compress(new TextEncoder().encode(data)));
}
function serializeEvents(events) {
// const splitByGregorianMonth = groupBy(events, (evt) => {
// return new Date(evt.startEvent).getMonth();
// });
return JSON.stringify(events);
}

View File

@ -1,311 +0,0 @@
/*!
* This script was taked from this page http://www.shamash.org/help/javadate.shtml and ported to Node.js by Ionică Bizău in https://github.com/IonicaBizau/hebrew-date
*
* This script was adapted from C sources written by
* Scott E. Lee, which contain the following copyright notice:
*
* Copyright 1993-1995, Scott E. Lee, all rights reserved.
* Permission granted to use, copy, modify, distribute and sell so long as
* the above copyright and this permission statement are retained in all
* copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
*
* Bill Hastings
* RBI Software Systems
* bhastings@rbi.com
*/
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var GREG_SDN_OFFSET = 32045, DAYS_PER_5_MONTHS = 153, DAYS_PER_4_YEARS = 1461, DAYS_PER_400_YEARS = 146097;
var HALAKIM_PER_HOUR = 1080, HALAKIM_PER_DAY = 25920, HALAKIM_PER_LUNAR_CYCLE = 29 * HALAKIM_PER_DAY + 13753, HALAKIM_PER_METONIC_CYCLE = HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7);
var HEB_SDN_OFFSET = 347997, NEW_MOON_OF_CREATION = 31524, NOON = 18 * HALAKIM_PER_HOUR, AM3_11_20 = 9 * HALAKIM_PER_HOUR + 204, AM9_32_43 = 15 * HALAKIM_PER_HOUR + 589;
var SUN = 0, MON = 1, TUES = 2, WED = 3, THUR = 4, FRI = 5, SAT = 6;
function weekdayarr(d0, d1, d2, d3, d4, d5, d6) {
this[0] = d0;
this[1] = d1;
this[2] = d2;
this[3] = d3;
this[4] = d4;
this[5] = d5;
this[6] = d6;
}
function gregmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11) {
this[0] = m0;
this[1] = m1;
this[2] = m2;
this[3] = m3;
this[4] = m4;
this[5] = m5;
this[6] = m6;
this[7] = m7;
this[8] = m8;
this[9] = m9;
this[10] = m10;
this[11] = m11;
}
function hebrewmontharr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13) {
this[0] = m0;
this[1] = m1;
this[2] = m2;
this[3] = m3;
this[4] = m4;
this[5] = m5;
this[6] = m6;
this[7] = m7;
this[8] = m8;
this[9] = m9;
this[10] = m10;
this[11] = m11;
this[12] = m12;
this[13] = m13;
}
function monthsperyeararr(m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18) {
this[0] = m0;
this[1] = m1;
this[2] = m2;
this[3] = m3;
this[4] = m4;
this[5] = m5;
this[6] = m6;
this[7] = m7;
this[8] = m8;
this[9] = m9;
this[10] = m10;
this[11] = m11;
this[12] = m12;
this[13] = m13;
this[14] = m14;
this[15] = m15;
this[16] = m16;
this[17] = m17;
this[18] = m18;
}
var gWeekday = new weekdayarr("Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur"), gMonth = new gregmontharr("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), hMonth = new hebrewmontharr("Tishri", "Heshvan", "Kislev", "Tevet", "Shevat", "AdarI", "AdarII", "Nisan", "Iyyar", "Sivan", "Tammuz", "Av", "Elul"), mpy = new monthsperyeararr(12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13);
/**
* hebrewDate
* Convert the Gregorian dates into Hebrew calendar dates.
*
* @name hebrewDate
* @function
* @param {Date|Number} inputDate The date object (representing the Gregorian date) or the year.
* @return {Object} An object containing:
*
* - `year`: The Hebrew year.
* - `month`: The Hebrew month.
* - `month_name`: The Hebrew month name.
* - `date`: The Hebrew date.
*/
function hebrewDate(inputDateOrYear) {
var inputMonth, inputDate;
var hebrewMonth = 0, hebrewDate = 0, hebrewYear = 0, metonicCycle = 0, metonicYear = 0, moladDay = 0, moladHalakim = 0;
function GregorianToSdn(inputYear, inputMonth, inputDay) {
var year = 0, month = 0, sdn = void 0;
// Make year a positive number
if (inputYear < 0) {
year = inputYear + 4801;
}
else {
year = inputYear + 4800;
}
// Adjust the start of the year
if (inputMonth > 2) {
month = inputMonth - 3;
}
else {
month = inputMonth + 9;
year--;
}
sdn = Math.floor(Math.floor(year / 100) * DAYS_PER_400_YEARS / 4);
sdn += Math.floor(year % 100 * DAYS_PER_4_YEARS / 4);
sdn += Math.floor((month * DAYS_PER_5_MONTHS + 2) / 5);
sdn += inputDay - GREG_SDN_OFFSET;
return sdn;
}
function SdnToHebrew(sdn) {
var tishri1 = 0, tishri1After = 0, yearLength = 0, inputDay = sdn - HEB_SDN_OFFSET;
FindTishriMolad(inputDay);
tishri1 = Tishri1(metonicYear, moladDay, moladHalakim);
if (inputDay >= tishri1) {
// It found Tishri 1 at the start of the year.
hebrewYear = metonicCycle * 19 + metonicYear + 1;
if (inputDay < tishri1 + 59) {
if (inputDay < tishri1 + 30) {
hebrewMonth = 1;
hebrewDate = inputDay - tishri1 + 1;
}
else {
hebrewMonth = 2;
hebrewDate = inputDay - tishri1 - 29;
}
return;
}
// We need the length of the year to figure this out,so find Tishri 1 of the next year.
moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear];
moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY);
moladHalakim = moladHalakim % HALAKIM_PER_DAY;
tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim);
}
else {
// It found Tishri 1 at the end of the year.
hebrewYear = metonicCycle * 19 + metonicYear;
if (inputDay >= tishri1 - 177) {
// It is one of the last 6 months of the year.
if (inputDay > tishri1 - 30) {
hebrewMonth = 13;
hebrewDate = inputDay - tishri1 + 30;
}
else if (inputDay > tishri1 - 60) {
hebrewMonth = 12;
hebrewDate = inputDay - tishri1 + 60;
}
else if (inputDay > tishri1 - 89) {
hebrewMonth = 11;
hebrewDate = inputDay - tishri1 + 89;
}
else if (inputDay > tishri1 - 119) {
hebrewMonth = 10;
hebrewDate = inputDay - tishri1 + 119;
}
else if (inputDay > tishri1 - 148) {
hebrewMonth = 9;
hebrewDate = inputDay - tishri1 + 148;
}
else {
hebrewMonth = 8;
hebrewDate = inputDay - tishri1 + 178;
}
return;
}
else {
if (mpy[(hebrewYear - 1) % 19] == 13) {
hebrewMonth = 7;
hebrewDate = inputDay - tishri1 + 207;
if (hebrewDate > 0)
return;
hebrewMonth--;
hebrewDate += 30;
if (hebrewDate > 0)
return;
hebrewMonth--;
hebrewDate += 30;
}
else {
hebrewMonth = 6;
hebrewDate = inputDay - tishri1 + 207;
if (hebrewDate > 0)
return;
hebrewMonth--;
hebrewDate += 30;
}
if (hebrewDate > 0)
return;
hebrewMonth--;
hebrewDate += 29;
if (hebrewDate > 0)
return;
// We need the length of the year to figure this out,so find Tishri 1 of this year.
tishri1After = tishri1;
FindTishriMolad(moladDay - 365);
tishri1 = Tishri1(metonicYear, moladDay, moladHalakim);
}
}
yearLength = tishri1After - tishri1;
moladDay = inputDay - tishri1 - 29;
if (yearLength == 355 || yearLength == 385) {
// Heshvan has 30 days
if (moladDay <= 30) {
hebrewMonth = 2;
hebrewDate = moladDay;
return;
}
moladDay -= 30;
}
else {
// Heshvan has 29 days
if (moladDay <= 29) {
hebrewMonth = 2;
hebrewDate = moladDay;
return;
}
moladDay -= 29;
}
// It has to be Kislev.
hebrewMonth = 3;
hebrewDate = moladDay;
}
function FindTishriMolad(inputDay) {
// Estimate the metonic cycle number. Note that this may be an under
// estimate because there are 6939.6896 days in a metonic cycle not
// 6940,but it will never be an over estimate. The loop below will
// correct for any error in this estimate.
metonicCycle = Math.floor((inputDay + 310) / 6940);
// Calculate the time of the starting molad for this metonic cycle.
MoladOfMetonicCycle();
// If the above was an under estimate,increment the cycle number until
// the correct one is found. For modern dates this loop is about 98.6%
// likely to not execute,even once,because the above estimate is
// really quite close.
while (moladDay < inputDay - 6940 + 310) {
metonicCycle++;
moladHalakim += HALAKIM_PER_METONIC_CYCLE;
moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY);
moladHalakim = moladHalakim % HALAKIM_PER_DAY;
}
// Find the molad of Tishri closest to this date.
for (metonicYear = 0; metonicYear < 18; metonicYear++) {
if (moladDay > inputDay - 74)
break;
moladHalakim += HALAKIM_PER_LUNAR_CYCLE * mpy[metonicYear];
moladDay += Math.floor(moladHalakim / HALAKIM_PER_DAY);
moladHalakim = moladHalakim % HALAKIM_PER_DAY;
}
}
function MoladOfMetonicCycle() {
var r1 = void 0, r2 = void 0, d1 = void 0, d2 = void 0;
// Start with the time of the first molad after creation.
r1 = NEW_MOON_OF_CREATION;
// Calculate gMetonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32
// bits of the result will be in r2 and the lower 16 bits will be in r1.
r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF);
r2 = r1 >> 16;
r2 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE >> 16 & 0xFFFF);
// Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1,the
// upper 16 bits of the quotient will be in d2 and the lower 16 bits
// will be in d1.
d2 = Math.floor(r2 / HALAKIM_PER_DAY);
r2 -= d2 * HALAKIM_PER_DAY;
r1 = r2 << 16 | r1 & 0xFFFF;
d1 = Math.floor(r1 / HALAKIM_PER_DAY);
r1 -= d1 * HALAKIM_PER_DAY;
moladDay = d2 << 16 | d1;
moladHalakim = r1;
}
function Tishri1(metonicYear, moladDay, moladHalakim) {
var tishri1 = moladDay, dow = tishri1 % 7, leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 || metonicYear == 18, lastWasLeapYear = metonicYear == 3 || metonicYear == 6 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14 || metonicYear == 17 || metonicYear == 0;
// Apply rules 2,3 and 4
if (moladHalakim >= NOON || !leapYear && dow == TUES && moladHalakim >= AM3_11_20 || lastWasLeapYear && dow == MON && moladHalakim >= AM9_32_43) {
tishri1++;
dow++;
if (dow == 7)
dow = 0;
}
// Apply rule 1 after the others because it can cause an additional delay of one day.
if (dow == WED || dow == FRI || dow == SUN) {
tishri1++;
}
return tishri1;
}
var inputYear = inputDateOrYear;
if ((typeof inputYear === "undefined" ? "undefined" : _typeof(inputYear)) === "object") {
inputMonth = inputDateOrYear.getMonth() + 1;
inputDate = inputDateOrYear.getDate();
inputYear = inputDateOrYear.getFullYear();
}
SdnToHebrew(GregorianToSdn(inputYear, inputMonth, inputDate));
return {
year: hebrewYear,
month: hebrewMonth,
date: hebrewDate,
month_name: hMonth[hebrewMonth - 1]
};
}
exports.hebrewDate = hebrewDate;

View File

@ -2,25 +2,19 @@
"id": "hebrew_calendar",
"name": "Hebrew Calendar",
"shortName": "HebCal",
"version": "0.04",
"description": "lists the date according to the hebrew calendar",
"version": "0.06",
"description": "lists the date & holidays according to the hebrew calendar",
"icon": "app.png",
"allow_emulator": false,
"tags": "tool,locale",
"tags": "clocks,tools",
"custom": "customizer.html",
"supports": [
"BANGLEJS",
"BANGLEJS2"
],
"type": "clock",
"readme": "README.md",
"storage": [
{
"name": "hebrew_calendar.app.js",
"url": "app.js"
},
{
"name": "hebrewDate",
"url": "hebrewDate.js"
},
{
"name": "hebrew_calendar.img",
"url": "app-icon.js",