Last commit for v1/cpp/prayertimes.cpp: 17ee68cff3d814bae3fcf7dc55beaf3e49909889

All code licences changed to LGPL v3.0

Hamid [2012-07-05 10:38:10]
All code licences changed to LGPL v3.0
/*-------------------- In the name of God ----------------------*\

    PrayerTimes 0.3
    Islamic prayer times calculator

Developed by:
  Mohammad Ebrahim Mohammadi Panah <ebrahim at mohammadi dot ir>

------------------------------------------------------------------

Copyright 2009, Mohammad Ebrahim Mohammadi Panah

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can get a copy of the GNU General Public License from
http://www.gnu.org/copyleft/gpl.html

\*--------------------------------------------------------------*/

#include <ctime>
#include <cmath>
#include <cstring>
#include <unistd.h>
#include <getopt.h>

#include "prayertimes.hpp"

#define PROG_NAME "prayertimes"
#define PROG_NAME_FRIENDLY "PrayerTimes"
#define PROG_VERSION "0.3"

static const char* TimeName[] =
{
	"Fajr",
	"Sunrise",
	"Dhuhr",
	"Asr",
	"Sunset",
	"Maghrib",
	"Isha",
};

void print_help(FILE* f)
{
	fputs(PROG_NAME_FRIENDLY " " PROG_VERSION "\n\n", stderr);
	fputs("Usage: " PROG_NAME " options...\n"
	      "\n"
		  " Options\n"
	      "    --help                      -h  you're reading it\n"
	      "    --version                   -v  prints name and version, then exits\n"
	      "    --date arg                  -d  get prayer times for arbitrary date\n"
	      "    --timezone arg              -z  get prayer times for arbitrary timezone\n"
	      "  * --latitude arg              -l  latitude of desired location\n"
	      "  * --longitude arg             -n  longitude of desired location\n"
	      "    --calc-method arg           -c  select prayer time calculation method\n"
	      "    --asr-juristic-method arg   -a  select Juristic method for calculating Asr prayer time\n"
	      "    --high-lats-method arg      -i  select adjusting method for higher latitude\n"
	      "    --dhuhr-minutes arg             minutes after mid-way for calculating Dhuhr prayer time\n"
	      " ** --maghrib-minutes arg           minutes after sunset for calculating Maghrib prayer time\n"
	      " ** --isha-minutes arg              minutes after Maghrib for calculating Isha prayer time\n"
	      " ** --fajr-angle arg                angle for calculating Fajr prayer time\n"
	      " ** --maghrib-angle arg             angle for calculating Maghrib prayer time\n"
	      " ** --isha-angle arg                angle for calculating Isha prayer time\n"
		  "\n"
		  "  * These options are required\n"
		  " ** By providing any of these options the calculation method is set to custom\n"
	      "\n"
		  " Possible arguments for --calc-method\n"
	      "    jafari        Ithna Ashari\n"
	      "    karachi       University of Islamic Sciences, Karachi\n"
	      "    isna          Islamic Society of North America (ISNA)\n"
	      "    mwl           Muslim World League (MWL)\n"
	      "    makkah        Umm al-Qura, Makkah\n"
	      "    egypt         Egyptian General Authority of Survey\n"
	      "    custom        Custom Setting\n"
          "\n"
		  " Possible arguments for --asr-juristic-method\n"
	      "    shafii        Shafii (standard)\n"
	      "    hanafi        Hanafi\n"
          "\n"
		  " Possible arguments for --high-lats-method\n"
	      "    none          No adjustment\n"
	      "    midnight      middle of night\n"
	      "    oneseventh    1/7th of night\n"
	      "    anglebased    angle/60th of night\n"
		  , stderr);

}

int main(int argc, char* argv[])
{
	PrayerTimes prayer_times;
	double latitude = NAN;		// 35.7061
	double longitude = NAN;		// 51.4358
	time_t date = time(NULL);
	double timezone = NAN;

	// Parse options
	for (;;)
	{
		static option long_options[] =
		{
			{ "help",                no_argument,       NULL, 'h' },
			{ "version",             no_argument,       NULL, 'v' },
			{ "date",                required_argument, NULL, 'd' },
			{ "timezone",            required_argument, NULL, 'z' },
			{ "latitude",            required_argument, NULL, 'l' },
			{ "longitude",           required_argument, NULL, 'n' },
			{ "calc-method",         required_argument, NULL, 'c' },
			{ "asr-juristic-method", required_argument, NULL, 'a' },
			{ "high-lats-method",    required_argument, NULL, 'i' },
			{ "dhuhr-minutes",       required_argument, NULL, 0   },
			{ "maghrib-minutes",     required_argument, NULL, 0   },
			{ "isha-minutes",        required_argument, NULL, 0   },
			{ "fajr-angle",          required_argument, NULL, 0   },
			{ "maghrib-angle",       required_argument, NULL, 0   },
			{ "isha-angle",          required_argument, NULL, 0   },
			{ 0, 0, 0, 0 }
		};

		enum	// long options missing a short form
		{
			DHUHR_MINUTES = 9,
			MAGHRIB_MINUTES,
			ISHA_MINUTES,
			FAJR_ANGLE,
			MAGHRIB_ANGLE,
			ISHA_ANGLE,
		};

		int option_index = 0;
		int c = getopt_long(argc, argv, "hvd:z:l:n:c:a:i:", long_options, &option_index);

		if (c == -1)
			break;		// Last option

		if (!optarg && c != 'h' && c != 'v')
		{
			fprintf(stderr, "Error: %s option requires an argument\n", long_options[option_index].name);
			return 2;
		}

		switch (c)
		{
			case 0:
				double arg;
				if (sscanf(optarg, "%lf", &arg) != 1)
				{
					fprintf(stderr, "Error: Invalid number '%s'\n", optarg);
					return 2;
				}
				switch (option_index)
				{
					case DHUHR_MINUTES:
						prayer_times.set_dhuhr_minutes(arg);
						break;
					case MAGHRIB_MINUTES:
						prayer_times.set_maghrib_minutes(arg);
						break;
					case ISHA_MINUTES:
						prayer_times.set_isha_minutes(arg);
						break;
					case FAJR_ANGLE:
						prayer_times.set_fajr_angle(arg);
						break;
					case MAGHRIB_ANGLE:
						prayer_times.set_maghrib_angle(arg);
						break;
					case ISHA_ANGLE:
						prayer_times.set_isha_angle(arg);
						break;
					default:
						fprintf(stderr, "Error: Invalid command line option\n");
						return 2;
				}
				break;
			case 'h':		// --help
				print_help(stdout);
				return 0;
			case 'v':		// --version
				puts(PROG_NAME_FRIENDLY " " PROG_VERSION);
				return 0;
			case 'd':		// --date
			{
				tm* new_date = getdate(optarg);
				if (!new_date)
				{
					fprintf(stderr, "Error: Failed to parse '%s' as date (%m)\n", optarg);
					return 2;
				}
				date = mktime(new_date);
				break;
			}
			case 'z':		// --timezone
				if (sscanf(optarg, "%lf", &timezone) != 1)
				{
					fprintf(stderr, "Error: Invalid timezone '%s'\n", optarg);
					return 2;
				}
				break;
			case 'l':		// --latitude
				if (sscanf(optarg, "%lf", &latitude) != 1)
				{
					fprintf(stderr, "Error: Invalid latitude '%s'\n", optarg);
					return 2;
				}
				break;
			case 'n':		// --longitude
				if (sscanf(optarg, "%lf", &longitude) != 1)
				{
					fprintf(stderr, "Error: Invalid longitude '%s'\n", optarg);
					return 2;
				}
				break;
			case 'c':		// --calc-method
				if (strcmp(optarg, "jafari") == 0)
					prayer_times.set_calc_method(PrayerTimes::Jafari);
				else if (strcmp(optarg, "karachi") == 0)
					prayer_times.set_calc_method(PrayerTimes::Karachi);
				else if (strcmp(optarg, "isna") == 0)
					prayer_times.set_calc_method(PrayerTimes::ISNA);
				else if (strcmp(optarg, "mwl") == 0)
					prayer_times.set_calc_method(PrayerTimes::MWL);
				else if (strcmp(optarg, "makkah") == 0)
					prayer_times.set_calc_method(PrayerTimes::Makkah);
				else if (strcmp(optarg, "egypt") == 0)
					prayer_times.set_calc_method(PrayerTimes::Egypt);
				else if (strcmp(optarg, "custom") == 0)
					prayer_times.set_calc_method(PrayerTimes::Custom);
				else
				{
					fprintf(stderr, "Error: Unknown method '%s'\n", optarg);
					return 2;
				}
				break;
			case 'a':		// --asr-juristic-method
				if (strcmp(optarg, "shafii") == 0)
					prayer_times.set_asr_method(PrayerTimes::Shafii);
				else if (strcmp(optarg, "hanafi") == 0)
					prayer_times.set_asr_method(PrayerTimes::Hanafi);
				else
				{
					fprintf(stderr, "Error: Unknown method '%s'\n", optarg);
					return 2;
				}
				break;
			case 'i':		// --high-lats-method
				if (strcmp(optarg, "none") == 0)
					prayer_times.set_high_lats_adjust_method(PrayerTimes::None);
				else if (strcmp(optarg, "midnight") == 0)
					prayer_times.set_high_lats_adjust_method(PrayerTimes::MidNight);
				else if (strcmp(optarg, "oneseventh") == 0)
					prayer_times.set_high_lats_adjust_method(PrayerTimes::OneSeventh);
				else if (strcmp(optarg, "anglebased") == 0)
					prayer_times.set_high_lats_adjust_method(PrayerTimes::AngleBased);
				else
				{
					fprintf(stderr, "Error: Unknown method '%s'\n", optarg);
					return 2;
				}
				break;
			default:
				fprintf(stderr, "Error: Unknown option '%c'\n", c);
				print_help(stderr);
				return 2;
		}
	}

	if (isnan(latitude) || isnan(longitude))
	{
		fprintf(stderr, "Error: You must provide both latitude and longitude\n");
		return 2;
	}

	fputs(PROG_NAME_FRIENDLY " " PROG_VERSION "\n\n", stderr);

	if (isnan(timezone))
		timezone = PrayerTimes::get_effective_timezone(date);

	double times[PrayerTimes::TimesCount];
	fprintf(stderr, "date          : %s", ctime(&date));
	fprintf(stderr, "timezone      : %.1lf\n", timezone);
	fprintf(stderr, "latitude      : %.5lf\n", latitude);
	fprintf(stderr, "longitude     : %.5lf\n", longitude);
	puts("");
	prayer_times.get_prayer_times(date, latitude, longitude, timezone, times);
	for (int i = 0; i < PrayerTimes::TimesCount; ++i)
		printf("%8s : %s\n", TimeName[i], PrayerTimes::float_time_to_time24(times[i]).c_str());
	return 0;
}
ViewGit