AUTHORS0000644000175000001440000000104611622666671011330 0ustar ashkanusersAuthors of Jalali calendar library: =========================== Ashkan Ghassemi Special thanks to: ================== Navid Abdi AmirMohammad Saied Armen Baghumian Mola Pahnadayan Milad Raastian Behnam Behjatmarandi Emil Sedgh Abbas Esmaeeli Saeid Taghavi Ali Rastegar Nima Mohammadi and all others for testing and reporting bugs. autogen.sh0000755000175000001440000001613311576000673012254 0ustar ashkanusers# # autogen.sh - Tools for manipulating Jalali representation of Iranian calendar # and necessary conversations to Gregorian calendar. # Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. # # This file is part of libjalali. # # libjalali is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # libjalali 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 Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with libjalali. If not, see . # #!/bin/bash # @OPTIONS OPTS="anch" LONG_OPTS="nocolor,clean,help,alternative" # @USAGE function usage() { echo -e "Jalali calendar library autogen build script." echo -e "usage: autogen.sh [-nch]" echo -e "try \`autogen.sh --help\' for more information." } # @HELP function help() { echo -e "usage: autogen.sh [-nch]..." echo -ne "Invokes GNU build system tools in order to create" echo -e " necessary configuration scripts.\n" echo -e "Operation modes:" echo -e " -a, --alternative\tdo not invoke autoreconf" echo -e " -n, --nocolor\t\tdisable output colors" echo -ne " -c, --clean\t\tremove all auto-generated scripts" echo -e " and files from source tree" echo -e " -h, --help\t\tprint this help, then exit\n" echo -e "Report bugs to ." echo -e "Jalali calendar home page: ." } # echoes ``ok'' if parameter is zero, ''failed'' otherwise. function printk() { local STAT=$1 if [ $1 -eq 0 ]; then echo -e "${GREEN}ok${RESET}" else echo -e "${RED}failed${RESET}" fi return ${STAT} } # performs make distclean and removes auto-generated files by GNU build system. function clean() { local STAT # files local FUBARS=( "autom4te.cache" "Makefile.in" "m4" "aclocal.m4" "configure" "config.sub" "config.guess" "config.log" "config.status" "depcomp" "install-sh" "libtool" "ltmain.sh" "missing" "src/Makefile.in" "man/Makefile.in" "libjalali/Makefile.in" "INSTALL" ) echo -e "${GREEN}*${RESET} ${YELLOW}cleaning source tree...${RESET}" # Makefile is present. if test -f Makefile; then echo -ne "${GREEN}*{RESET} {YELLOW}performing distclean on" echo -ne " sources if possible...${RESET} " make distclean >/dev/null 2>&1 let STAT=$? printk ${STAT} if [ ${STAT} -ne 0 ]; then echo -ne "${RED}error${RESET}: cannot perform make distclean." echo -e " run make distclean manually and check for erros." fi fi for i in ${FUBARS[@]}; do if [ -f $i ] || [ -d $i ]; then echo -ne "${GREEN}*${RESET} ${YELLOW}deleting $i...${RESET} " rm -rf $i printk 0 fi done echo -e "${GREEN}* done${RESET}" } # Setting colors to vt100 standard values, NULL if 0 gets passed to set_color() function set_colors() { local HAS_COLOR=$1 if [ ${HAS_COLOR} -eq 1 ]; then RED="\033[1;31m" GREEN="\033[1;32m" YELLOW="\033[1;33m" CYAN="\033[1;36m" RESET="\033[0m" else RED="" GREEN="" YELLOW="" CYAN="" RESET="" fi } # @is_present() $SERVICE $NAME $OUTPUT $EXIT # Checks whether a service is present on system. # $SERVICE is the path to service. # $NAME is the service name. # $OUTPUT specifies whether is_present() should work silently or not. # $EXIT specifies whther is_present() should exit on the event of # service not found. function is_present() { local SERVICE=$1 local NAME=$2 local OUTPUT=$3 local EXIT=$4 local PRESENT=0 if [ -n "${SERVICE}" ]; then let PRESENT=1 fi if [ ${OUTPUT} -eq 1 ]; then echo -ne "${GREEN}*${RESET} checking for ${YELLOW}${NAME}${RESET}... " if [ ${PRESENT} -eq 1 ]; then echo -e "${GREEN}yes${RESET}" else echo -e "${RED}no${RESET}" fi fi if [ ${PRESENT} -eq 0 ] && [ ${EXIT} -eq 1 ]; then echo -ne "${RED}error${RESET}: ${YELLOW}${NAME}${RESET} was not found" echo -e "on your system. autogen.sh cannot continue." exit 1 fi return ${PRESENT} } # Checking for tools # aclocal, libtoolize, autoconf, automake and autoreconf function check_services() { local STAT ACLOCAL="$(which aclocal 2>/dev/null)" is_present "${ACLOCAL}" "aclocal" 1 1 # glibtoolize glue-patch LIBTOOLIZE="$(which glibtoolize 2>/dev/null)" STAT=$? is_present "${LIBTOOLIZE}" "glibtoolize" 1 0 if [ ${STAT} -ne 0 ]; then LIBTOOLIZE="$(which libtoolize 2>/dev/null)" is_present "${LIBTOOLIZE}" "libtoolize" 1 1 fi AUTOCONF="$(which autoconf 2>/dev/null)" is_present "${AUTOCONF}" "autoconf" 1 1 AUTOMAKE="$(which automake 2>/dev/null)" is_present "${AUTOMAKE}" "automake" 1 1 AUTORECONF="$(which autoreconf 2>/dev/null)" is_present "${AUTORECONF}" "autoreconf" 1 0 echo -e "${GREEN}* done${RESET}\n" } # @perform() $SERVICE $NAME $EXIT $PARAMS # runs a service with a set of parameters. # $SERVICE is the path to the service. # $NAME is the service name. # $EXIT specifies whether perform() should exit on the event of # encoutering any errors or not. # $PARAMS are the parameters passed to the service. function perform() { local SERVICE=$1 local NAME=$2 local EXIT=$3 local PARAMS=$4 local SSTAT echo -ne "${GREEN}*${RESET} running ${YELLOW}${NAME}${RESET} ${CYAN}${PARAMS}${RESET}... " ${SERVICE} ${PARAMS} >/dev/null 2>&1 let STAT=$? printk ${STAT} if [ ${STAT} -ne 0 ]; then echo -ne "${RED}error${RESET}: cannot run ${YELLOW}${NAME}${RESET}." echo -e " please run ${NAME} manually and check for errors." fi if [ ${EXIT} -eq 1 ] && [ ${STAT} -ne 0 ]; then exit 1 fi } # Operation modes. CLEAN=0 HELP=0 COLOR=1 ALTERN=0 which which 1>/dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "cannot find \`\`which''. autogen cannot continue." exit 1 fi # Parsing command-line arguments GETOPT=`which getopt 2>/dev/null` if [ -z ${GETOPT} ]; then echo -ne "warning: getopt(1) was not found on your system." echo -e " command line arguments will be ignored." else TEMP=`${GETOPT} -o ${OPTS} -l ${LONG_OPTS} -n 'autogen.sh' -- "$@"` for i in $TEMP; do case $i in -c|--clean) let CLEAN=1;; -n|--nocolor) let COLOR=0;; -h|--help) let HELP=1;; -a|--alternative) let ALTERN=1;; esac done fi # Setting colors. set_colors ${COLOR} # HELP if [ ${HELP} -eq 1 ]; then help exit 0 fi # CLEAN if [ ${CLEAN} -eq 1 ]; then clean exit 0 fi # Checking for services. check_services # alternative method. if [ -z "${AUTORECONF}" ] || [ ${ALTERN} -eq 1 ]; then echo -e "using alternative method: ${YELLO}manual${RESET}" perform "${LIBTOOLIZE}" "libtoolize" "1" "--force --copy --install" perform "${ACLOCAL}" "aclocal" "1" "--force" perform "${AUTOMAKE}" "automake" "1" "--add-missing --force-missing --copy" perform "${AUTOCONF}" "autoconf" "1" "--force" echo -e "${GREEN}* done${RESET}" # autoreconf method else echo -e "using prefered method: ${YELLOW}autoreconf${RESET}" perform "${LIBTOOLIZE}" "libtoolize" "1" "--force --copy --install" perform "${AUTORECONF}" "autoreconf" "1" "--force --install" echo -e "${GREEN}* done${RESET}" fi exit 0 ChangeLog0000644000175000001440000001702311625553213012022 0ustar ashkanusers2011-08-26 Ashkan Ghassemi * sources/ChangeLog, sources/libjalali/jalali.h, sources/src/jcal.h, sources/src/jdate.h: version string fix. * sources/ChangeLog, sources/libjalali/jtime.c: fixing __CYGWIN__ macro typo in jtime.c. * sources/ChangeLog, sources/libjalali/jalali.c, sources/libjalali/jtime.c: limiting gettimeofday() usage to windows as it doesn't work as expected on some platforms. 2011-06-15 Ashkan Ghassemi * sources/ChangeLog, sources/autogen.sh: autogen.sh: minor fixes. * docs/jalali.html, docs/jcal.html, docs/jdate.html, docs/jstrftime.html, docs/jstrptime.html, sources/autogen.sh, sources/configure.in: configure.in: minor fixes. * docs/jalali.html, docs/jcal.html, docs/jdate.html, docs/jstrftime.html, docs/jstrptime.html, sources/ChangeLog: docs updated. * sources/ChangeLog, sources/libjalali/jalali.c, sources/libjalali/jtime.c: using of non-standard time struct fields discarded. * sources/ChangeLog, sources/libjalali/jtime.c, sources/man/jdate.1, sources/src/jcal.c, sources/src/jdate.c, sources/src/jdate.h: conversion added to jdate. minor fixes to libjalali. 2011-06-10 Ashkan Ghassemi * docs/jalali.html, docs/jcal.html, docs/jdate.html, docs/jstrftime.html, docs/jstrptime.html, sources/libjalali/jalali.c, sources/libjalali/jtime.c, sources/man/jstrptime.3: added %s to jstrptime(). fix for an accidental y2k38 issue in type-casting. 2011-06-09 Ashkan Ghassemi * sources/ChangeLog, sources/libjalali/jtime.c, sources/man/jstrftime.3, sources/src/jcal.c: fix for farsi indentation problem. * sources/libjalali/jtime.c, sources/libjalali/jtime.h, sources/src/jcal.c: platform independent patch on Farsi support. 2011-06-07 Ashkan Ghassemi * docs/jalali.html, docs/jcal.html, docs/jdate.html, docs/jstrftime.html, docs/jstrptime.html, sources/ChangeLog, sources/README, sources/libjalali/jalali.h, sources/libjalali/jtime.c, sources/libjalali/jtime.h, sources/man/jcal.1, sources/man/jctime.3, sources/man/jdate.1, sources/man/jstrftime.3, sources/man/jstrptime.3, sources/src/jcal.c, sources/src/jcal.h, sources/src/jdate.h: added Farsi (utf8) output support to jcal and jdate. 2011-06-04 Ashkan Ghassemi * .gitignore, docs/jalali.html, docs/jcal.html, docs/jdate.html, docs/jstrftime.html, docs/jstrptime.html, html-docs/jalali.html, html-docs/jcal.html, html-docs/jdate.html, html-docs/jstrftime.html, html-docs/jstrptime.html, sources/AUTHORS, sources/ChangeLog, sources/README, sources/TODO, sources/libjalali/jalali.h, sources/libjalali/jtime.c, sources/man/jdate.1, sources/man/jstrftime.3, sources/src/jcal.h, sources/src/jdate.h: added utf-8 persian outputs to jstrftime. added TODO. docs updated. 2011-06-03 Ashkan Ghassemi * sources/autogen.sh, sources/configure.in, sources/libjalali/jalali.c, sources/libjalali/jalali.h, sources/libjalali/jconfig.h, sources/libjalali/jtime.c, sources/man/Makefile.am, sources/man/jctime.3, sources/src/Makefile.am, sources/src/jcal.c, sources/src/jcal.h, sources/src/jdate.c, sources/src/jdate.h: whitespace fix on sources. 2011-06-02 Ashkan Ghassemi * sources/autogen.sh: autogen help fixed. * sources/ChangeLog, sources/autogen.sh: glibtoolize fix for autogen script. * sources/ChangeLog, test_kit/elc.c, test_kit/get_date.c, test_kit/get_diff.c, test_kit/jtime/asctime.c, test_kit/jtime/compile_me.sh, test_kit/jtime/ctime.c, test_kit/jtime/gmtime.c, test_kit/jtime/jstrftime.c, test_kit/jtime/localtime.c, test_kit/jtime/mktime.c, test_kit/jyinfo.c, test_kit/leap.c, test_kit/sec_converter.c: test_kit fixes. * sources/ChangeLog, sources/README, sources/autogen.sh: added autogen.sh build script. 2011-06-01 Ashkan Ghassemi * sources/ChangeLog, sources/configure.in: minor fix to Configure.in, removed required libtool version for backward compatibility. * sources/ChangeLog, sources/libjalali/Makefile.am, sources/libjalali/jalali.c, sources/libjalali/jalali.h, sources/libjalali/jconfig.h, sources/libjalali/jtime.c, sources/libjalali/jtime.h, sources/man/jcal.1, sources/man/jctime.3, sources/man/jdate.1, sources/man/jstrftime.3, sources/man/jstrptime.3, sources/src/Makefile.am, sources/src/jcal.c, sources/src/jcal.h, sources/src/jdate.c, sources/src/jdate.h, sources/src/termcap.h: removed trailing whitespaces. ChangeLog update. 2011-05-31 Ashkan Ghassemi * sources/libjalali/jalali.c, sources/libjalali/jtime.c: usage of timezone from tzset() removed due to a faulty implementation of BSD standards in OS X and possibly others. 2011-05-30 Ashkan Ghassemi * sources/libjalali/jalali.h, sources/libjalali/jtime.c, sources/libjalali/jtime.h: BSD-compatible macros. * sources/libjalali/jtime.c, sources/man/jdate.1, sources/man/jstrftime.3, sources/man/jstrptime.3: added %h (full English transliteration for Persian weekday names) to jstrftime(), jstrptime(), and manual pages. * .gitignore, sources/src/jcal.c, test_kit/compile_me.sh, test_kit/elc.c, test_kit/get_date.c, test_kit/get_diff.c, test_kit/jtime/asctime.c, test_kit/jtime/compile_me.sh, test_kit/jtime/ctime.c, test_kit/jtime/gmtime.c, test_kit/jtime/jstrftime.c, test_kit/jtime/jstrptime.c, test_kit/jtime/localtime.c, test_kit/jtime/mktime.c, test_kit/jyinfo.c, test_kit/leap.c, test_kit/sec_converter.c: fix whole year month titles. gitignore update. test_kit update. 2011-05-29 Ashkan Ghassemi * .gitignore, sources/src/jcal.o, sources/src/jdate.o: gitignore added. unwanted files removed from repo. * html-docs/jcal.html, sources/man/jcal.1, sources/src/jcal.c, sources/src/jcal.h, sources/src/jcal.o, sources/src/jdate.o: default weekday names to Persian in jcal. 2011-05-28 Ashkan Ghassemi * html-docs/jalali.html, html-docs/jcal.html, html-docs/jdate.html, html-docs/jstrftime.html, html-docs/jstrptime.html, sources/AUTHORS, sources/ChangeLog, sources/Makefile.am, sources/NEWS, sources/README, sources/configure.in, sources/libjalali/Makefile.am, sources/libjalali/jalali.c, sources/libjalali/jalali.h, sources/libjalali/jconfig.h, sources/libjalali/jtime.c, sources/libjalali/jtime.h, sources/man/Makefile.am, sources/man/jalali_create_date_from_days.3, sources/man/jalali_create_days_from_date.3, sources/man/jalali_create_secs_from_time.3, sources/man/jalali_create_time_from_secs.3, sources/man/jalali_get_date.3, sources/man/jalali_get_diff.3, sources/man/jalali_get_jyear_info.3, sources/man/jalali_is_jleap.3, sources/man/jalali_update.3, sources/man/jasctime.3, sources/man/jasctime_r.3, sources/man/jcal.1, sources/man/jctime.3, sources/man/jctime_r.3, sources/man/jdate.1, sources/man/jgmtime.3, sources/man/jgmtime_r.3, sources/man/jlocaltime.3, sources/man/jlocaltime_r.3, sources/man/jmktime.3, sources/man/jstrftime.3, sources/man/jstrptime.3, sources/src/Makefile.am, sources/src/jcal.c, sources/src/jcal.h, sources/src/jcal.o, sources/src/jdate.c, sources/src/jdate.h, sources/src/jdate.o, sources/src/termcap.h, test_kit/compile_me.sh, test_kit/elc.c, test_kit/get_date.c, test_kit/get_diff.c, test_kit/jtime/asctime.c, test_kit/jtime/compile_me.sh, test_kit/jtime/ctime.c, test_kit/jtime/gmtime.c, test_kit/jtime/jstrftime.c, test_kit/jtime/jstrptime.c, test_kit/jtime/localtime.c, test_kit/jtime/mktime.c, test_kit/jyinfo.c, test_kit/leap.c, test_kit/sec_converter.c: Initial import configure.in0000644000175000001440000000142011575775240012565 0ustar ashkanusers# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_INIT([jcal], [0.4], [ghassemi@ftml.net]) AM_INIT_AUTOMAKE AC_PROG_LIBTOOL AC_CONFIG_MACRO_DIR([m4]) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET # Checks for header files. AC_CHECK_HEADERS([time.h limits.h stdlib.h string.h sys/time.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_STRUCT_TIMEZONE # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_MKTIME AC_CHECK_FUNCS([gettimeofday localtime_r memset strcasecmp strchr strstr tzset]) AC_CONFIG_FILES([Makefile libjalali/Makefile man/Makefile src/Makefile]) AC_OUTPUT COPYING0000644000175000001440000010451311571534054011306 0ustar ashkanusers GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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 should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . libjalali/0000755000175000001440000000000011625553350012172 5ustar ashkanuserslibjalali/jalali.c0000644000175000001440000002127311625540131013570 0ustar ashkanusers/* * jalali.c - Tools for manipulating Jalali representation of Iranian calendar * and necessary conversations to Gregorian calendar. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of libjalali. * * libjalali is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libjalali 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libjalali. If not, see . */ #include #include #include #include #include #include #include "jalali.h" #include "jconfig.h" const int cycle_patterns[] = { J_PT0, J_PT1, J_PT2, J_PT3, INT_MAX }; const int leaps[] = { J_L0, J_L1, J_L2, J_L3, INT_MAX }; const int jalali_month_len[] = { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 }; extern char* tzname[2]; /* * Jalali leap year indication function. The algorithm used here * is loosely based on the famous recurring 2820 years length period. This * period is then divided into 88 cycles, each following a 29, 33, 33, 33 * years length pattern with the exception for the last being 37 years long. * In every of these 29, 33 or 37 years long periods starting with year 0, * leap years are multiples of four except for year 0 in each period. * The current 2820 year period started in the year AP 475 (AD 1096). */ int jalali_is_jleap(int year) { int pr = year; /* Shifting ``year'' with 2820 year period epoch. */ pr -= JALALI_LEAP_BASE; pr %= JALALI_LEAP_PERIOD; /* * According to C99 standards, modulo operator's result has the same sign * as dividend. Since what we require to process has to be in range * 0-2819, we have to shift the remainder to be positive if dividend is * negative. */ if (pr < 0) { pr += JALALI_LEAP_PERIOD; } /* * Every cycle consists of one 29 year period and three identical 33 year * periods forming a 128 years length cycle. An exception applies to the * last cycle being 132 years instead and it's last 33 years long partition * will be extended for an extra 4 years thus becoming 37 years long. * JALALI_LAST_CYCLE_START literally marks the beginning of this last * cycle. */ pr = (pr > JALALI_LAST_CYCLE_START) ? (pr - JALALI_LAST_CYCLE_START) : pr % JALALI_NORMAL_CYCLE_LENGTH; /* * Classifying year in a cycle. Assigning to one of the four partitions. */ int i; for (i=0; i= cycle_patterns[i]) && (pr < cycle_patterns[i+1])) { pr -= cycle_patterns[i]; /* Handling year-0 exception */ if (!pr) /* pr is zero */ return 0; /* * If year is a multiple of four then it's leap, * ordinary otherwise. */ else return !(pr % J_LI); } } /* * Our code flow better not reach this fail-safe * return statement and I really mean it. */ return 0; } /* * Creates absolute values for day, hour, minute and seconds from time_t. * Values are signed integers. */ void jalali_create_time_from_secs(time_t t, struct ab_jtm* d) { d->ab_days = (t >= 0) ? (t / (time_t) J_DAY_LENGTH_IN_SECONDS) : ((t - (time_t) J_DAY_LENGTH_IN_SECONDS + (time_t) 1) / (time_t) J_DAY_LENGTH_IN_SECONDS); if (t >= 0) { t %= (time_t) J_DAY_LENGTH_IN_SECONDS; } else { t = (J_DAY_LENGTH_IN_SECONDS - (abs(t - J_DAY_LENGTH_IN_SECONDS) % J_DAY_LENGTH_IN_SECONDS)) % J_DAY_LENGTH_IN_SECONDS; } d->ab_hour = t / J_HOUR_LENGTH_IN_SECONDS; t %= J_HOUR_LENGTH_IN_SECONDS; d->ab_min = t / J_MINUTE_LENGTH_IN_SECONDS; d->ab_sec = t % J_MINUTE_LENGTH_IN_SECONDS; } /* * Creates a timestamp from day, hour, minute and seconds. * Values are signed integers. */ time_t jalali_create_secs_from_time(const struct ab_jtm* d) { return (time_t) ((time_t) d->ab_days * (time_t) J_DAY_LENGTH_IN_SECONDS + (time_t) d->ab_hour * (time_t) J_HOUR_LENGTH_IN_SECONDS + (time_t) d->ab_min * (time_t) J_MINUTE_LENGTH_IN_SECONDS + (time_t) d->ab_sec); } /* * Month and day of year calculation for a desired day of year. * Alters only tm_mday and tm_mon. * Zero on success, -1 on failure. */ int jalali_create_date_from_days(struct jtm* j) { int p = j->tm_yday; if (p > 365 || p < 0) return -1; p++; int i; /* Traversing all twelve months, ranging from 0 to 11 */ for (i=0; i<11; i++) { if (p > jalali_month_len[i]) p -= jalali_month_len[i]; else break; } j->tm_mday = p; j->tm_mon = i; return 0; } /* * Calculate day of year (0-365) based on month and day. */ int jalali_create_days_from_date(struct jtm* j) { int p = 0; int i; if (j->tm_mon < 0 || j->tm_mon > 11) return -1; if (j->tm_mday < 1 || j->tm_mday > 31) return -1; for (i=0; itm_mon; i++) { p+= jalali_month_len[i]; } p+= j->tm_mday - 1; j->tm_yday = p; return 0; } /* * Get useful information on a desired jalali year, including: * 1. Leap status. -lf * 2. Year position in grand leap cycle, passed and remaining years. -p, -r * 3. Passed and remaining leap years in grand leap cycle. -pl, -rl * 4. Absolute passed leap years since grand leap cycle epoch (AP 475). -apl */ void jalali_get_jyear_info(struct jyinfo* year) { int y = year->y; year->lf = jalali_is_jleap(year->y); int i; int d = (year->y >= JALALI_LEAP_BASE) ? 1 : -1; int c = 0; for (i=JALALI_LEAP_BASE; ; i+=d) { if (jalali_is_jleap(i)) { c++; } if (i == year->y) break; } year->apl = c * d; year->pl = (d > 0) ? c % JALALI_TOTAL_LEAPS_IN_PERIOD : JALALI_TOTAL_LEAPS_IN_PERIOD - (c % JALALI_TOTAL_LEAPS_IN_PERIOD); year->rl = JALALI_TOTAL_LEAPS_IN_PERIOD - year->pl; y-= JALALI_LEAP_BASE; y%= JALALI_LEAP_PERIOD; if (y < 0) y+= JALALI_LEAP_PERIOD; year->p = y; year->r = JALALI_LEAP_PERIOD - y - 1; return ; } /* * Calculates date (Jalali) based on difference factor from UTC Epoch by days. * 0 means 1 January 1970 (11 Dey 1348). */ void jalali_get_date(int p, struct jtm* j) { time_t t; struct tm lt; #if defined _WIN32 || defined __MINGW32__ || defined __CYGWIN__ struct timezone tz; struct timeval tv; #endif int wd = (p + J_UTC_EPOCH_WDAY) % J_WEEK_LENGTH; if (wd < 0) { j->tm_wday = wd + J_WEEK_LENGTH; } else { j->tm_wday = wd; } int y = J_UTC_EPOCH_YEAR, f=0; p += J_UTC_EPOCH_DIFF; int d; while (1) { d = (p >= 0 ) ? 1 : -1; f = jalali_is_jleap(((d > 0) ? y : y-1)) ? JALALI_LEAP_YEAR_LENGTH_IN_DAYS: JALALI_NORMAL_YEAR_LENGTH_IN_DAYS; if ((0 <= p) && (p < f)) break; p-= (d * f); y+= d; } j->tm_year = y; j->tm_yday = p; jalali_create_date_from_days(j); tzset(); t = p * J_DAY_LENGTH_IN_SECONDS; localtime_r(&t, <); #if defined _WIN32 || defined __MINGW32__ || defined __CYGWIN__ gettimeofday(&tv, &tz); j->tm_gmtoff = (-tz.tz_minuteswest) * J_MINUTE_LENGTH_IN_SECONDS + (tz.tz_dsttime * J_HOUR_LENGTH_IN_SECONDS); j->tm_zone = tzname[lt.tm_isdst]; #else j->tm_gmtoff = lt.tm_gmtoff; j->tm_zone = lt.tm_zone; #endif j->tm_isdst = lt.tm_isdst; } /* * Calculates UTC epoch difference of a desired date by measure of days. */ int jalali_get_diff(const struct jtm* j) { int p = 0; int i; int s, sd; int e, ed; int f = 1; if (j->tm_yday > 365 || j->tm_yday < 0) return -1; if (j->tm_year == J_UTC_EPOCH_YEAR) { p = j->tm_yday - J_UTC_EPOCH_DIFF; return p; } else if (j->tm_year > J_UTC_EPOCH_YEAR) { s = J_UTC_EPOCH_YEAR + 1; sd = J_UTC_EPOCH_DIFF; e = j->tm_year - 1; ed = j->tm_yday + 1; } else { f = -1; s = j->tm_year + 1; sd = j->tm_yday; e = J_UTC_EPOCH_YEAR - 1; ed = J_UTC_EPOCH_DIFF + 1; } for (i=s; i<=e; i++) { p+= jalali_is_jleap(i) ? JALALI_LEAP_YEAR_LENGTH_IN_DAYS : JALALI_NORMAL_YEAR_LENGTH_IN_DAYS; } int r = jalali_is_jleap(s) ? JALALI_LEAP_YEAR_LENGTH_IN_DAYS - sd - 1 : JALALI_NORMAL_YEAR_LENGTH_IN_DAYS - sd - 1; p += r + ed; p*= f; return p; } /* * Updates a jalali date struct fields based on tm_year, tm_mon and tm_mday */ void jalali_update(struct jtm* jtm) { int d; jalali_create_days_from_date(jtm); d = jalali_get_diff(jtm); jalali_get_date(d, jtm); } /* * Displays a jalali date struct fields. * should be used for debugging purposes only. */ void jalali_show_time(const struct jtm* j) { printf("%d/%02d/%02d (%02d:%02d:%02d) [%d]", j->tm_year, j->tm_mon + 1, j->tm_mday, j->tm_hour, j->tm_min, j->tm_sec, j->tm_wday); printf(" yday: %d, dst: %d, off: %ld, zone: %s\n", j->tm_yday, j->tm_isdst, j->tm_gmtoff, j->tm_zone); } libjalali/jtime.h0000644000175000001440000000350611573775367013477 0ustar ashkanusers/* * jtime.h - Tools for manipulating Jalali representation of Iranian calendar * and necessary conversations to Gregorian calendar. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of libjalali. * * libjalali is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libjalali 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libjalali. If not, see . */ #ifndef JTIME_H #define JTIME_H #ifdef __cplusplus extern "C" { #if 0 /* /me mutters something about emacs. */ } #endif #endif #define MAX_BUF_SIZE 2048 extern char* jasctime(const struct jtm* jtm); extern char* jctime(const time_t* timep); extern struct jtm* jgmtime(const time_t* timep); extern struct jtm* jlocaltime(const time_t* timep); extern time_t jmktime(const struct jtm* jtm); extern size_t jstrftime(char* s, size_t max, const char* format, const struct jtm* jtm); extern char* jstrptime(const char* s, const char* format, struct jtm* jtm); extern char* jasctime_r(const struct jtm* jtm, char* buf); extern char* jctime_r(const time_t* timep, char* buf); extern struct jtm* jgmtime_r(const time_t* timep, struct jtm* result); extern struct jtm* jlocaltime_r(const time_t* timep, struct jtm* result); extern int jalali_to_farsi(char* buf, size_t n, int padding, char* pad, int d); #ifdef __cplusplus } #endif #endif /* JTIME_H */ libjalali/Makefile.am0000644000175000001440000000153011571254364014230 0ustar ashkanusers#------------------------------------------------------------------------------ # Process this file with automake to produce Makefile.in. #------------------------------------------------------------------------------ lib_LTLIBRARIES = libjalali.la libjalali_la_SOURCES = jalali.c jtime.c # 0:0:0 # 0 -> interface version, changes whenever you change the API # 0 -> changes whenever you make a revision of an interface no # API changes... # 0 -> changes whenever you change the API but keep it backwards # compatible (have not removed a function from the API, for # example...) libjalali_la_LDFLAGS = -version-info 0:2:0 includedir= $(prefix)/include/jalali include_HEADERS = jalali.h jtime.h jconfig.h INCLUDES = -I. -I@includedir@ LIBS = @LIBS@ $(THREAD_LIBS) AM_CFLAGS = @CFLAGS@ -D_REENTRANT -W -Wall -O2 libjalali/jalali.h0000644000175000001440000000516111625552172013603 0ustar ashkanusers/* * jalali.h - Tools for manipulating Jalali representation of Iranian calendar * and necessary conversations to Gregorian calendar. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of libjalali. * * libjalali is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libjalali 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libjalali. If not, see . */ #ifndef JALALI_H #define JALALI_H #include #ifdef __cplusplus extern "C" { #if 0 /* /me mutters something about emacs. */ } #endif #endif #define LIBJALALI_VERSION "0.4.1" struct jtm { int tm_sec; /* Seconds. (0-59) */ int tm_min; /* Minutes. (0-59) */ int tm_hour; /* Hours. (0-59) */ int tm_mday; /* Day of the month. (1-31) */ int tm_mon; /* Month. (0-11) */ int tm_year; /* Year. */ int tm_wday; /* Day of the week. (0-6) */ int tm_yday; /* Day in the year. (0-365) */ int tm_isdst; /* Daylight saving time is in effect. */ long int tm_gmtoff; /* Seconds east of UTC. */ const char *tm_zone; /* Timezone abbreviation. */ }; struct ab_jtm { int ab_sec; int ab_min; int ab_hour; int ab_days; }; struct jyinfo { int lf; /* leap indicator flag */ int y; /* year */ int r; /* reamining years in grand cycle */ int p; /* passed years from grand cycle*/ int rl; /* remaining leap years in grand cycle */ int pl; /* passed leap years in grand cycle */ int apl; /* absolute passed leaps */ }; /* Jalali leap year indication function. */ extern int jalali_is_jleap(int year); extern void jalali_create_time_from_secs(time_t time, struct ab_jtm* ab_jtm); extern time_t jalali_create_secs_from_time(const struct ab_jtm* ab_jtm); extern int jalali_create_date_from_days(struct jtm* j); extern int jalali_create_days_from_date(struct jtm* j); extern void jalali_get_jyear_info(struct jyinfo* jyinfo); extern void jalali_get_date(int p, struct jtm* jtm); extern int jalali_get_diff(const struct jtm* jtm); extern void jalali_update(struct jtm* jtm); extern void jalali_show_time(const struct jtm* j); #ifdef __cplusplus } #endif #endif /* JALALI_H */ libjalali/jtime.c0000644000175000001440000005240711625551056013457 0ustar ashkanusers/* * jtime.c - Tools for manipulating Jalali representation of Iranian calendar * and necessary conversations to Gregorian calendar. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of libjalali. * * libjalali is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libjalali 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libjalali. If not, see . */ #include #include #include #include #include "jconfig.h" #include "jalali.h" #include "jtime.h" const char* GMT_ZONE = "UTC"; const char* GMT_ZONE_fa = "گرینویچ"; const char* jalali_months[] = { "Farvardin", "Ordibehesht", "Khordaad", "Tir", "Mordaad", "Shahrivar", "Mehr", "Aabaan", "Aazar", "Dey", "Bahman", "Esfand" }; const char* fa_jalali_months[] = { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند" }; const char* jalali_months_3[] = { "Far", "Ord", "Kho", "Tir", "Mor", "Sha", "Meh", "Aba", "Aza", "Dey", "Bah", "Esf" }; const char* fa_jalali_months_3[] = { "فرو", "ارد", "خرد", "تیر", "مرد", "شهر", "مهر", "آبا", "آذر", "دی ", "بهم", "اسف"}; const char* jalali_days_fa[] = { "Shanbeh", "Yek-Shanbeh", "Do-Shanbeh", "Seh-Shanbeh", "Chahaar-Shanbeh", "Panj-Shanbeh", "Jomeh" }; const char* fa_jalali_days[] = { "شنبه", "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه" }; const char* jalali_days_3_fa[] = { "Sha", "Yek", "Dos", "Ses", "Cha", "Pan", "Jom" }; const char* fa_jalali_days_3[] = { "شنب", "یکش", "دوش", "سهش", "چها", "پنج", "جمع" }; const char* jalali_days_2_fa[] = { "Sh", "Ye", "Do", "Se", "Ch", "Pa", "Jo" }; const char* fa_jalali_days_2[] = { "شن", "یک", "دو", "سه", "چه", "پن", "جم" }; const char* jalali_days[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" }; const char* jalali_days_3[] = { "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri" }; const char* jalali_days_2[] = { "Sa", "Su", "Mo", "Tu", "We", "Th", "Fr" }; const char* farsi_digits[] = { "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" }; const char* tzname_fa[2] = { "زمان زمستانی", "زمان تابستانی" }; static char in_buf[MAX_BUF_SIZE] = {0}; static struct jtm in_jtm; extern char* tzname[2]; void in_jasctime(const struct jtm* jtm, char* buf) { if (!jtm) return; if (jtm->tm_wday < 0 || jtm->tm_wday > 6) return; if (jtm->tm_mon < 0 || jtm->tm_mon > 11) return; if (jtm->tm_mday < 1 || jtm->tm_mday > 31) return; if (buf) { snprintf(buf, MAX_BUF_SIZE, "%s %s %02d %02d:%02d:%02d %d\n", jalali_days_3[jtm->tm_wday], jalali_months_3[jtm->tm_mon], jtm->tm_mday, jtm->tm_hour, jtm->tm_min, jtm->tm_sec, jtm->tm_year); memcpy(in_buf, buf, MAX_BUF_SIZE); } else { snprintf(in_buf, MAX_BUF_SIZE, "%s %s %02d %02d:%02d:%02d %d\n", jalali_days_3[jtm->tm_wday], jalali_months_3[jtm->tm_mon], jtm->tm_mday, jtm->tm_hour, jtm->tm_min, jtm->tm_sec, jtm->tm_year); } } void in_jlocaltime(const time_t* timep, struct jtm* result) { if (!timep) return; struct tm t; struct jtm c_jtm; struct ab_jtm ab; long int gmtoff; time_t c; tzset(); localtime_r(timep, &t); #if defined _WIN32 || defined __MINGW32__ || defined __CYGWIN__ struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); gmtoff = (-tz.tz_minuteswest) * J_MINUTE_LENGTH_IN_SECONDS + (tz.tz_dsttime * J_HOUR_LENGTH_IN_SECONDS); c_jtm.tm_zone = tzname[t.tm_isdst]; #else gmtoff = t.tm_gmtoff; c_jtm.tm_zone = t.tm_zone; #endif c = (*timep) + (time_t) gmtoff; jalali_create_time_from_secs(c, &ab); jalali_get_date(ab.ab_days, &c_jtm); jalali_create_date_from_days(&c_jtm); c_jtm.tm_sec = ab.ab_sec; c_jtm.tm_min = ab.ab_min; c_jtm.tm_hour = ab.ab_hour; c_jtm.tm_isdst = t.tm_isdst; c_jtm.tm_gmtoff = gmtoff; if (result) { memcpy(result, &c_jtm, sizeof(struct jtm)); } memcpy(&in_jtm, &c_jtm, sizeof(struct jtm)); } void in_jctime(const time_t* timep, char* buf) { if (!timep) return; struct jtm c_jtm; in_jlocaltime(timep, &c_jtm); if (buf) { in_jasctime(&c_jtm, buf); } else { in_jasctime(&c_jtm, 0); } } void in_jgmtime(const time_t* timep, struct jtm* result) { if (!timep) return; struct tm t; struct jtm c_jtm; struct ab_jtm ab; time_t c; tzset(); gmtime_r(timep, &t); c = *timep; jalali_create_time_from_secs(c, &ab); jalali_get_date(ab.ab_days, &c_jtm); jalali_create_date_from_days(&c_jtm); c_jtm.tm_sec = ab.ab_sec; c_jtm.tm_min = ab.ab_min; c_jtm.tm_hour = ab.ab_hour; c_jtm.tm_isdst = 0; c_jtm.tm_zone = GMT_ZONE; c_jtm.tm_gmtoff = 0; if (result) { memcpy(result, &c_jtm, sizeof(struct jtm)); } memcpy(&in_jtm, &c_jtm, sizeof(struct jtm)); } char* jasctime(const struct jtm* jtm) { if (!jtm) return 0; in_jasctime(jtm, 0); return in_buf; } char* jctime(const time_t* timep) { if (!timep) return 0; in_jctime(timep, 0); return in_buf; } struct jtm* jgmtime(const time_t* timep) { if (!timep) return 0; in_jgmtime(timep, 0); return &in_jtm; } struct jtm* jlocaltime(const time_t* timep) { if (!timep) return 0; in_jlocaltime(timep, 0); return &in_jtm; } time_t jmktime(const struct jtm* jtm) { if (!jtm) return (time_t) (-1); tzset(); int p = jalali_get_diff(jtm); time_t t; t = ((time_t) p * (time_t) J_DAY_LENGTH_IN_SECONDS) + ((time_t) jtm->tm_hour * (time_t) J_HOUR_LENGTH_IN_SECONDS) + ((time_t) jtm->tm_min * (time_t) J_MINUTE_LENGTH_IN_SECONDS) + (time_t) jtm->tm_sec - ((time_t) jtm->tm_gmtoff); return t; } size_t jstrftime(char* s, size_t max, const char* format, const struct jtm* jtm) { if (!s || max <= 0 || !format || !jtm) return -1; char _l1[10]; char _l2[10]; char _l3[10]; char _la[100]; char _lb[100]; char buf[MAX_BUF_SIZE]; int i, j; int fmt_n = strlen(format); int rb = 0; int b_n; int tmp; int tmp1; time_t t; struct jtm t_j; for (i=0; itm_wday], MAX_BUF_SIZE); break; /* The full weekday name. */ case 'A': strncpy(buf, jalali_days[jtm->tm_wday], MAX_BUF_SIZE); break; /* The abbreviated month name. */ case 'b': strncpy(buf, jalali_months_3[jtm->tm_mon], MAX_BUF_SIZE); break; /* The full month name. */ case 'B': strncpy(buf, jalali_months[jtm->tm_mon], MAX_BUF_SIZE); break; /* * The preferred date and time representation. * example: Tue 27 Ord 1390 03:28:19 IRDT. */ case 'c': tzset(); snprintf(buf, MAX_BUF_SIZE, "%s %d %s %d %02d:%02d:%02d %s", jalali_days_3[jtm->tm_wday], jtm->tm_mday, jalali_months_3[jtm->tm_mon], jtm->tm_year, jtm->tm_hour, jtm->tm_min, jtm->tm_sec, jtm->tm_zone); break; /* The century number (year/100) as a 2-digit integer. */ case 'C': snprintf(buf, MAX_BUF_SIZE, "%d", (jtm->tm_year / 100) + 1); break; /* The day of the month as a decimal number (range 01 to 31). */ case 'd': snprintf(buf, MAX_BUF_SIZE, "%02d", jtm->tm_mday); break; /* Equivalent to %Y/%m/%d. */ case 'D': snprintf(buf, MAX_BUF_SIZE, "%d/%02d/%02d", jtm->tm_year, jtm->tm_mon + 1, jtm->tm_mday); break; /* * Like %d, the day of the month as a decimal number, but * a leading zero is replaced by a space. */ case 'e': snprintf(buf, MAX_BUF_SIZE, "%2d", jtm->tm_mday); break; /* * The preferred date and time representation in Farsi. (utf8) * example: سه شنبه ۱۷ خرداد ۱۳۹۰، ساعت ۰۸:۱۹:۲۳ (IRDT) */ case 'E': tzset(); jalali_to_farsi(_l1, 10, 2, "۰", jtm->tm_hour); jalali_to_farsi(_l2, 10, 2, "۰", jtm->tm_min); jalali_to_farsi(_l3, 10, 2, "۰", jtm->tm_sec); jalali_to_farsi(_la, 100, 2, "۰", jtm->tm_mday); jalali_to_farsi(_lb, 100, 0, " ", jtm->tm_year); snprintf(buf, MAX_BUF_SIZE, "%s %s %s %s، ساعت %s:%s:%s - %s", fa_jalali_days[jtm->tm_wday], _la, fa_jalali_months[jtm->tm_mon], _lb, _l1, _l2, _l3, (jtm->tm_zone == GMT_ZONE) ? GMT_ZONE_fa : tzname_fa[jtm->tm_isdst]); break; /* * Equivalent to %Y-%m-%d (similar to the ISO 8601 date format). */ case 'F': snprintf(buf, MAX_BUF_SIZE, "%d-%02d-%02d", jtm->tm_year, jtm->tm_mon + 1, jtm->tm_mday); break; /* The abbreviated weekday name. (Farsi-UTF8) */ case 'g': strncpy(buf, fa_jalali_days_3[jtm->tm_wday], MAX_BUF_SIZE); break; /* The full weekday name. (Farsi-UTF8) */ case 'G': strncpy(buf, fa_jalali_days[jtm->tm_wday], MAX_BUF_SIZE); break; /* The abbreviated month name. (Farsi-UTF8) */ case 'v': strncpy(buf, fa_jalali_months_3[jtm->tm_mon], MAX_BUF_SIZE); break; /* The full month name. (Farsi-UTF8) */ case 'V': strncpy(buf, fa_jalali_months[jtm->tm_mon], MAX_BUF_SIZE); break; /* The abbreviated weekday name. (Farsi) */ case 'h': strncpy(buf, jalali_days_3_fa[jtm->tm_wday], MAX_BUF_SIZE); break; /* The full weekday name. (Farsi) */ case 'q': strncpy(buf, jalali_days_fa[jtm->tm_wday], MAX_BUF_SIZE); break; /* * The hour as a decimal number using a 24-hour clock * (range 00 to 23). */ case 'H': snprintf(buf, MAX_BUF_SIZE, "%02d", jtm->tm_hour); break; /* * The hour as a decimal number using a 12-hour clock * (range 01 to 12). */ case 'I': snprintf(buf, MAX_BUF_SIZE, "%02d", (jtm->tm_hour == 12) ? 12 : jtm->tm_hour % 12); break; /* * The day of the year as a decimal number * (range 001 to 366). */ case 'j': snprintf(buf, MAX_BUF_SIZE, "%03d", jtm->tm_yday + 1); break; /* * The hour (24-hour clock) as a decimal number (range 0 to 23); * single digits are preceded by a blank. * (See also %H.) */ case 'k': snprintf(buf, MAX_BUF_SIZE, "%2d", jtm->tm_hour); break; /* * The hour (12-hour clock) as a decimal number * (range 1 to 12); * single digits are preceded by a blank. * (See also %I.) */ case 'l': tmp = (jtm->tm_hour == 12) ? 12 : jtm->tm_hour % 12; snprintf(buf, MAX_BUF_SIZE, "%2d", tmp); break; /* The month as a decimal number (range 01 to 12). */ case 'm': snprintf(buf, MAX_BUF_SIZE, "%02d", jtm->tm_mon + 1); break; /* The minute as a decimal number (range 00 to 59). */ case 'M': snprintf(buf, MAX_BUF_SIZE, "%02d", jtm->tm_min); break; /* A newline character. */ case 'n': snprintf(buf, MAX_BUF_SIZE, "\n"); break; /* * Either "ق.ظ" or "ب.ظ" according to the given time value. * Noon is treated as "ق.ظ" and midnight as "ب.ظ". */ case 'O': snprintf(buf, MAX_BUF_SIZE, "%s", (jtm->tm_hour >= 0 && jtm->tm_hour < 12) ? "ق.ظ" : "ب.ظ"); break; /* * Either "AM" or "PM" according to the given time value. * Noon is treated as "PM" and midnight as "AM". */ case 'p': snprintf(buf, MAX_BUF_SIZE, "%s", (jtm->tm_hour >= 0 && jtm->tm_hour < 12) ? "AM" : "PM"); break; /* Like %p but in lowercase: "am" or "pm". */ case 'P': snprintf(buf, MAX_BUF_SIZE, "%s", (jtm->tm_hour >= 0 && jtm->tm_hour < 12) ? "am" : "pm"); break; /* * The time in a.m. or p.m. notation. * In the POSIX locale this is equivalent to %I:%M:%S %p. */ case 'r': snprintf(buf, MAX_BUF_SIZE, "%02d:%02d:%02d %s", (jtm->tm_hour == 12) ? 12 : jtm->tm_hour % 12, jtm->tm_min, jtm->tm_sec, (jtm->tm_hour >= 0 && jtm->tm_hour < 12) ? "AM" : "PM"); break; /* * The time in 24-hour notation (%H:%M). * For a version including the seconds, see %T below. */ case 'R': snprintf(buf, MAX_BUF_SIZE, "%02d:%02d", jtm->tm_hour, jtm->tm_min); break; /* * The number of seconds since the Epoch * 1970-01-01 00:00:00 +0000 (UTC). */ case 's': t = jmktime(jtm); snprintf(buf, MAX_BUF_SIZE, "%d", (int) t); break; /* The second as a decimal number (range 00 to 59). */ case 'S': snprintf(buf, MAX_BUF_SIZE, "%02d", jtm->tm_sec); break; /* A tab character. */ case 't': snprintf(buf, MAX_BUF_SIZE, "\t"); break; /* The time in 24-hour notation (%H:%M:%S). */ case 'T': snprintf(buf, MAX_BUF_SIZE, "%02d:%02d:%02d", jtm->tm_hour, jtm->tm_min, jtm->tm_sec); break; /* * The day of the week as a decimal, range 1 to 7 * Saturday being 1. See also %w. */ case 'u': snprintf(buf, MAX_BUF_SIZE, "%d", jtm->tm_wday + 1); break; /* * The week number of the current year as a decimal number, * range 00 to 53, * starting with the first Saturday as the first day of week 01. */ case 'U': memcpy(&t_j, jtm, sizeof(struct jtm)); t_j.tm_yday = 0; jalali_create_date_from_days(&t_j); tmp = (jtm->tm_yday + t_j.tm_wday) / 7; snprintf(buf, MAX_BUF_SIZE, "%02d", tmp); break; /* * The day of the week as a decimal, range 0 to 6 * Saturday being 0. See also %u. */ case 'w': snprintf(buf, MAX_BUF_SIZE, "%d", jtm->tm_wday); break; /* * The preferred date representation without the time * in Farsi. (utf8) */ case 'W': jalali_to_farsi(_la, 100, 0, " ", jtm->tm_year); jalali_to_farsi(_l1, 10, 2, "۰", jtm->tm_mon+1); jalali_to_farsi(_l2, 10, 2, "۰", jtm->tm_mday); snprintf(buf, MAX_BUF_SIZE, "%s/%s/%s", _la, _l1, _l2); break; /* The preferred date representation without the time. */ case 'x': snprintf(buf, MAX_BUF_SIZE, "%02d/%02d/%d", jtm->tm_mday, jtm->tm_mon+1, jtm->tm_year); break; /* * The preferred time representation in Farsi. (utf8) */ case 'X': jalali_to_farsi(_l1, 10, 2, "۰", jtm->tm_hour); jalali_to_farsi(_l2, 10, 2, "۰", jtm->tm_min); jalali_to_farsi(_l3, 10, 2, "۰", jtm->tm_sec); snprintf(buf, MAX_BUF_SIZE, "%s:%s:%s", _l1, _l2, _l3); break; /* * The year as a decimal number without a century * (range 00 to 99). */ case 'y': tmp = ((jtm->tm_year) % 1000) % 100; snprintf(buf, MAX_BUF_SIZE, "%02d", tmp); break; /* The year as a decimal number including the century. */ case 'Y': snprintf(buf, MAX_BUF_SIZE, "%d", jtm->tm_year); break; /* * The +hhmm or -hhmm numeric timezone * (that is, the hour and minute offset from UTC). */ case 'z': tmp = ((int)jtm->tm_gmtoff / J_HOUR_LENGTH_IN_SECONDS); tmp1 = ((int)jtm->tm_gmtoff % J_HOUR_LENGTH_IN_SECONDS) / J_MINUTE_LENGTH_IN_SECONDS; snprintf(buf, MAX_BUF_SIZE, "%s%02d%02d", (tmp >= 0) ? "+" : "-", abs(tmp), abs(tmp1)); break; /* The timezone or name or abbreviation. */ case 'Z': snprintf(buf, MAX_BUF_SIZE, "%s", jtm->tm_zone); break; /* A literal '%' character. */ case '%': snprintf(buf, MAX_BUF_SIZE, "%s", "%"); break; /* Non of the above. Ignoring modifier. */ default: break; } b_n = strlen(buf); for (j=0; j (int) (max - 2)) { s[max-1] = '\0'; return (max-1); } s[rb] = buf[j]; rb++; } i++; _la[0] = 0; _lb[0] = 0; _l1[0] = 0; _l2[0] = 0; _l3[0] = 0; } } s[rb] = '\0'; return rb; } char* jstrptime(const char* s, const char* format, struct jtm* jtm) { char buf[MAX_BUF_SIZE]; char delim[MAX_BUF_SIZE]; char* pos_n; char* pos_c; char* pos_e; char** ptr; size_t diff = 0, diff1 = 0; int s_s, fmt_s, tmp; int i, j, k, f, c = 0; char fd; struct jtm _j; time_t t; s_s = strlen(s); fmt_s = strlen(format); /* * Traversing format string for the matching characters in input string. * Each time an identical character is found, we simply pass to the * next one. In the event of finding a % (format specifier) we find the * matching argument by means of finding the delimiter between the found * format specifier and the next. If there was no format specifiers after * the current one, we consider the remaining set of characters as * delimiter. */ for (i=0, j=0; i < s_s && j < fmt_s; ) { buf[0] = 0; delim[0] = 0; /* Identical character in format and string, skipping. */ if (s[i] == format[j]) { i++; j++; continue; } /* Malformed string or format. */ if (format[j] != '%') { return NULL; } if (j+2 >= fmt_s) { diff1 = s_s; } else { pos_c = (char*) &format[j+2]; pos_n = strchr(pos_c, '%'); if (!pos_n) { diff = 1; pos_n = (char*) &format[fmt_s-1]; } else { diff = (pos_n - pos_c); } memcpy(delim, pos_c, diff); delim[diff] = 0; pos_e = strstr(&s[i], delim); /* Delimiter not found in string. */ if (!pos_e) { return NULL; } diff1 = (pos_e - &s[i]); } fd = format[j+1]; memcpy(buf, &s[i], diff1); buf[diff1] = 0; switch (fd) { /* The abbreviated or full weekday name. */ case 'a': case 'A': ptr = (fd == 'a') ? (char**) jalali_days_3 : (char**) jalali_days; f = 0; for (k=0; ktm_wday = k; f = 1; } } if (!f) return (char*) &s[i]; break; /* The abbreviated or full month name. */ case 'b': case 'B': ptr = (fd == 'b') ? (char**) jalali_months_3 : (char**) jalali_months; f = 0; for (k=0; ktm_mon = k; f = 1; } } if (!f) return (char*) &s[i]; break; /* The day of the month as a decimal number (range 01 to 31). */ case 'd': case 'e': jtm->tm_mday = atoi(buf); break; /* * The hour as a decimal number using a 24-hour clock * (range 00 to 23). */ case 'H': jtm->tm_hour = atoi(buf); break; /* The day of the year as a decimal number (range 001 to 366). */ case 'j': jtm->tm_yday = atoi(buf) - 1; break; /* The month as a decimal number (range 01 to 12). */ case 'm': jtm->tm_mon = atoi(buf) -1; break; /* The minute as a decimal number (range 00 to 59). */ case 'M': jtm->tm_min = atoi(buf); break; /* Seconds since epoch. (1970/1/1) */ case 's': t = (time_t) atol(buf); jlocaltime_r(&t, &_j); memcpy(jtm, &_j, sizeof(struct jtm)); break; /* The second as a decimal number (range 00 to 59). */ case 'S': jtm->tm_sec = atoi(buf); break; /* * The year as a decimal number without a century * (range 00 to 99). */ case 'y': tmp = atoi(buf); if (tmp >= 19 && tmp < 100) jtm->tm_year = 1300 + tmp; else jtm->tm_year = 1400 + tmp; break; /* The year as a decimal number including the century. */ case 'Y': jtm->tm_year = atoi(buf); break; /* The abbreviated or full weekday name. (Farsi) */ case 'q': case 'h': ptr = (fd == 'h') ? (char**) jalali_days_3_fa : (char**) jalali_days_fa; f = 0; for (k=0; ktm_wday = k; f = 1; } } if (!f) return (char*) &s[i]; break; default: break; } c++; j += diff + 2; i += diff1 + diff; } return (char*) &s[s_s]; } char* jasctime_r(const struct jtm* jtm, char* buf) { if (!jtm || !buf) return 0; in_jasctime(jtm, buf); return in_buf; } struct jtm* jlocaltime_r(const time_t* timep, struct jtm* result) { if (!timep || !result) return 0; in_jlocaltime(timep, result); return &in_jtm; } struct jtm* jgmtime_r(const time_t* timep, struct jtm* result) { if (!timep || !result) return 0; in_jgmtime(timep, result); return &in_jtm; } char* jctime_r(const time_t* timep, char* buf) { if (!timep || !buf) return 0; in_jctime(timep, buf); return in_buf; } /* * @Utils * Utility functions for internal use. * jalali_to_farsi() converts an integer's digits to Arabic-Indic * padding works just like printf() field width. */ int jalali_to_farsi(char* buf, size_t n, int padding, char* pad, int d) { char _buf[100] = {0}; int i=0, j=0; int p = 0; int c = 0; int cw = (pad[0] < 0) ? 2 : 1; for (i=d; i!=0; c++, _buf[p] = farsi_digits[i%10 > 0 ? i%10 : -(i%10)][1], _buf[p+1] = farsi_digits[i%10 > 0 ? i%10 : -(i%10)][0], i/=10, p+=2); if (d < 0) { _buf[p] = '-'; c++; p++; } _buf[p]= 0; buf[0] = 0; i=0; for (i=0; (i<(padding - c)) && (i*cw < (int)(n-1)); strcat(buf, pad), i++); buf[i*cw] = 0; for (j=0, i*=cw; (j. */ #ifndef JCONFIG_H #define JCONFIG_H #define JALALI_LEAP_BASE 475 /* Jalali 2820 year period epoch. */ #define JALALI_LEAP_PERIOD 2820 /* Jalali recurring pattern length. */ #define JALALI_NORMAL_CYCLE_LENGTH 128 /* A normal cycle length. */ #define JALALI_EXTRA_CYCLE_LENGTH 132 /* Last cycle length. */ /* Starting year of the last cycle in the period. */ #define JALALI_LAST_CYCLE_START 2688 #define J_PT0 0 /* No partitions passed. */ #define J_PT1 29 /* First partition passed. 0+29 */ #define J_PT2 62 /* Second partition passed. 0+29+33 */ #define J_PT3 95 /* Third partition passed. 0+29+33+33 */ #define J_L0 0 #define J_L1 7 #define J_L2 15 #define J_L3 23 #define J_C1 29 /* First type of partitions, 29 years in length. */ #define J_C2 33 /* Second type of partitions, 33 years in length. */ #define J_C2e 37 /* Extension to the second type, only one instance. */ #define J_LI 4 /* Multiples of four are leap except for zero. */ #define JALALI_TOTAL_LEAPS_IN_PERIOD 683 #define JALALI_LEAPS_EXCLUDING_LAST_CYCLE 651 #define JALALI_LEAPS_IN_NORMAL_CYCLE 31 #define JALALI_LEAPS_IN_EXTENDED_CYCLE 32 #define JALALI_NORMAL_CYCLE_LENGTH 128 #define JALALI_EXTENDED_CYCLE_LENGTH 132 #define J_DAY_LENGTH_IN_SECONDS 86400 #define J_DAY_LENGTH_IN_HOURS 24 #define J_HOUR_LENGTH_IN_SECONDS 3600 #define J_HOUR_LENGTH_IN_MINUTES 60 #define J_MINUTE_LENGTH_IN_SECONDS 60 #define J_WEEK_LENGTH 7 #define J_YEAR_LENGTH_IN_MONTHS 12 #define JALALI_LEAP_YEAR_LENGTH_IN_DAYS 366 #define JALALI_NORMAL_YEAR_LENGTH_IN_DAYS 365 #define J_UTC_EPOCH_YEAR 1348 #define J_UTC_EPOCH_MONTH 10 #define J_UTC_EPOCH_DAY 11 #define J_UTC_EPOCH_DIFF 286 #define J_UTC_EPOCH_WDAY 5 #endif /* JCONFIG_H */ Makefile.am0000644000175000001440000000007411570114566012305 0ustar ashkanusersACLOCAL_AMFLAGS = -I m4 SUBDIRS = libjalali src man man/0000755000175000001440000000000011625553350011022 5ustar ashkanusersman/jctime_r.30000644000175000001440000000002211570077055012676 0ustar ashkanusers.so man3/jctime.3 man/jalali_create_time_from_secs.30000644000175000001440000000002211570077055016737 0ustar ashkanusers.so man3/jctime.3 man/jalali_get_jyear_info.30000644000175000001440000000002211570077055015402 0ustar ashkanusers.so man3/jctime.3 man/jalali_create_date_from_days.30000644000175000001440000000002211570077055016721 0ustar ashkanusers.so man3/jctime.3 man/jalali_create_days_from_date.30000644000175000001440000000002211570077055016721 0ustar ashkanusers.so man3/jctime.3 man/jalali_get_date.30000644000175000001440000000002211570077055014172 0ustar ashkanusers.so man3/jctime.3 man/Makefile.am0000644000175000001440000000062711572037717013070 0ustar ashkanusersman_MANS = jalali_create_date_from_days.3 jalali_get_date.3 jalali_update.3\ jctime.3 jgmtime_r.3 jstrftime.3 jalali_create_days_from_date.3\ jalali_get_diff.3 jasctime.3 jctime_r.3 jlocaltime.3 jstrptime.3\ jalali_create_secs_from_time.3 jalali_get_jyear_info.3 jasctime_r.3\ jdate.1 jlocaltime_r.3 jalali_create_time_from_secs.3 jalali_is_jleap.3\ jcal.1 jgmtime.3 jmktime.3 EXTRA_DIST = $(man_MANS) man/jasctime_r.30000644000175000001440000000002211570077055013222 0ustar ashkanusers.so man3/jctime.3 man/jgmtime.30000644000175000001440000000002211570077055012536 0ustar ashkanusers.so man3/jctime.3 man/jasctime.30000644000175000001440000000002211570077055012701 0ustar ashkanusers.so man3/jctime.3 man/jstrftime.30000644000175000001440000001636111574020027013115 0ustar ashkanusers.\" * jstrftime.3 - Tools for manipulating Jalali representation of Iranian calendar .\" * and necessary conversations to Gregorian calendar. .\" * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. .\" * .\" * This file is part of libjalali. .\" * .\" * libjalali is free software: you can redistribute it and/or modify .\" * it under the terms of the GNU Lesser General Public License as published by .\" * the Free Software Foundation, either version 3 of the License, or .\" * (at your option) any later version. .\" * .\" * libjalali 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 Lesser General Public License for more details. .\" * .\" * You should have received a copy of the GNU Lesser General Public License .\" * along with libjalali. If not, see . .TH JSTRFTIME 3 2011-05-28 "GNU" "libjalali Manual" .SH NAME jstrftime \- format jalali date and time .SH SYNOPSIS .nf .B #include .sp .BI "size_t jstrftime(char *" s ", size_t " max ", const char *" format , .BI " const struct tm *" jtm ); .fi .sp Link with -ljalali .SH DESCRIPTION The .BR jstrftime () function formats the broken-down jalali time \fIjtm\fP according to the format specification \fIformat\fP and places the result in the character array \fIs\fP of size \fImax\fP. .PP The format specification is a null-terminated string and may contain special character sequences called .IR "conversion specifications", each of which is introduced by a \(aq%\(aq character and terminated by some other character known as a .IR "conversion specifier character". All other character sequences are .IR "ordinary character sequences". .PP The characters of ordinary character sequences (including the null byte) are copied verbatim from \fIformat\fP to \fIs\fP. However, the characters of conversion specifications are replaced as follows: .TP .B %a The abbreviated weekday name. .TP .B %A The full weekday name. .TP .B %b The abbreviated month name. .TP .B %B The full month name. .TP .B %c The preferred date and time representation. .TP .B %C The century number (year/100) as a 2-digit integer. .TP .B %d The day of the month as a decimal number (range 01 to 31). .TP .B %D Equivalent to .BR %Y/%m/%d . .TP .B %e Like .BR %d The day of the month as a decimal number, but a leading zero is replaced by a space. (SU) .TP .B %E The preferred date and time in Farsi. (utf8) .TP .B %F Equivalent to .B %Y-%m-%d (similar to the ISO\ 8601 date format). (C99) .TP .B %h The abbreviated Farsi transliterated weekday name. .TP .B %q The full Farsi transliterated weekday name. .TP .B %g The abbreviated Farsi weekday name. (utf8) .TP .B %G The full Farsi weekday name. (utf8) .TP .B %v The abbreviated Farsi month name. (utf8) .TP .B %V The full Farsi month name. (utf8) .TP .B %H The hour as a decimal number using a 24-hour clock (range 00 to 23). .TP .B %I The hour as a decimal number using a 12-hour clock (range 01 to 12). .TP .B %j The day of the year as a decimal number (range 001 to 366). .TP .B %k The hour (24-hour clock) as a decimal number (range 0 to 23); single digits are preceded by a blank. (See also .BR %H .) (TZ) .TP .B %l The hour (12-hour clock) as a decimal number (range 1 to 12); single digits are preceded by a blank. (See also .BR %I .) (TZ) .TP .B %m The month as a decimal number (range 01 to 12). .TP .B %M The minute as a decimal number (range 00 to 59). .TP .B %n A newline character. (SU) .TP .B %O AM or PM notation for the given time in Farsi equivalent. (utf8) .TP .B %p Either "AM" or "PM" according to the given time value. Noon is treated as "PM" and midnight as "AM". .TP .B %P Like .B %p but in lowercase: "am" or "pm" .TP .B %r The time in a.m. or p.m. notation. In the POSIX locale this is equivalent to .BR "%I:%M:%S %p" . (SU) .TP .B %R The time in 24-hour notation (\fB%H:%M\fP). (SU) For a version including the seconds, see .B %T below. .TP .B %s The number of seconds since the Epoch, 1970-01-01 (1348-10-11) 00:00:00 +0000 (UTC). (TZ) .TP .B %S The second as a decimal number (range 00 to 59). .TP .B %t A tab character. (SU) .TP .B %T The time in 24-hour notation (\fB%H:%M:%S\fP). (SU) .TP .B %u The day of the week as a decimal, range 1 to 7, Saturday being 1. See also .BR %w . (SU) .TP .B %U The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01. .TP .B %w The day of the week as a decimal, range 0 to 6, Saturday being 0. See also .BR %u . .TP .B %W The preferred date in %Y/%m/%d format and Farsi. (utf8) .TP .B %x The preferred date representation without the time. .TP .B %X The preferred time representation without the date in Farsi. (utf8) .TP .B %y The year as a decimal number without a century (range 00 to 99). .TP .B %Y The year as a decimal number including the century. .TP .B %z The .I +hhmm or .I -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU) .TP .B %Z The timezone or name or abbreviation. .TP .B %% A literal \(aq%\(aq character. .PP The broken-down time structure \fItm\fP is defined in \fI\fP. See also .BR jctime (3). .SH "RETURN VALUE" The .BR jstrftime () function returns the number of characters placed in the array \fIs\fP, not including the terminating null byte, provided the string, including the terminating null byte, fits. Otherwise, it returns max, and the contents of the array is undefined. .SH ENVIRONMENT The environment variables .B TZ and .B LC_TIME are used. .SH "CONFORMING TO" C99. .SH EXAMPLES .BR "RFC\ 2822-compliant date format" (with an English locale for %a and %b) .PP .in +2n "%a,\ %d\ %b\ %Y\ %T\ %z" .PP .BR "RFC\ 822-compliant date format" (with an English locale for %a and %b) .PP .in +2n "%a,\ %d\ %b\ %y\ %T\ %z" .SS Example Program The program below can be used to experiment with .BR jstrftime (). .PP Some examples of the result string produced by the libjalali implementation of .BR jstrftime () are as follows: .in +4n .nf .RB "$" " ./a.out \(aq%m\(aq" Result string is "11" .fi .in .PP Here's the program source: .nf #include #include #include #include #include int main(int argc, char *argv[]) { char outstr[200]; time_t t; struct tm *tmp; t = time(NULL); tmp = jlocaltime(&t); if (tmp == NULL) { perror("jlocaltime"); exit(EXIT_FAILURE); } if (jstrftime(outstr, sizeof(outstr), argv[1], tmp) == 0) { fprintf(stderr, "jstrftime returned 0"); exit(EXIT_FAILURE); } printf("Result string is \\"%s\\"\\n", outstr); exit(EXIT_SUCCESS); } .fi .SH "SEE ALSO" .BR jdate (1), .BR jcal (1), .BR time (2), .BR jctime (3), .BR sprintf (3), .BR jstrptime (3) .SH COLOPHON This page is part of release 0.2 of the libjalali .I man-pages .SH AUTHOR Written by Ashkan Ghassemi. .SH REPORTING BUGS Report libjalali bugs to libjalali home page: .SH COPYRIGHT Copyright (C) 2011 Ashkan Ghassemi. License LGPLv3+: GNU LGPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. man/jcal.10000644000175000001440000005505011573324247012025 0ustar ashkanusers.\" * .\" * jcal.1 - Unix cal-like interface to libjalali. .\" * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. .\" * .\" * This file is part of jcal. .\" * .\" * jcal 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 3 of the License, or .\" * (at your option) any later version. .\" * .\" * jcal 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 should have received a copy of the GNU General Public License .\" * along with jcal. If not, see . .\" * .Dd Khordad 6, 1390 .Dt JCAL 1 .Os .Sh NAME .Nm jcal .Nd displays a calendar .Sh SYNOPSIS .Nm jcal .Op Fl epPVjy13 .Op [ Ar month ] Ar year .Sh DESCRIPTION .Nm jcal displays a simple calendar. If arguments are not specified, the current month is displayed. The options are as follows: .Bl -tag -width Ds .It Fl 1 Display single month output. (This is the default.) .It Fl 3 Display prev/current/next month output. .It Fl j Display Julian dates (days one-based, numbered from Farvardin 1). .It Fl p Display Farsi numbers and names. .It Fl P Display year based on Pahlavi epoch. .It Fl e Display english names for weekdays. .It Fl y Display a calendar for the current year. .It Fl V Display calendar version. .El .Pp A single parameter specifies the year (1 - 9999) to be displayed; note the year must be fully specified: .Dq Li cal 90 will .Em not display a calendar for 1390. Two parameters denote the month (1 - 12) and year. If no parameters are specified, the current month's calendar is displayed. .Pp A year starts on Far 1. .Pp .Sh BRIEF EXPLANATION True solar year, also known as tropical year, was a still later discovery. One has to take equinox or solstice into account to keep an accurate track of the solar year. The equinoxes are the two intersections of the sun's apparent annual path with the celestial equator. The sun reaches the vernal equinox on 1st of Farvardin, on or about 21st March, the summer solstice on 1st of Tir, on about 22nd June, the autumnal equinox on 1st Mehr, on or about 23rd September, and the winter solstice on 1st of Dey, on or about 22 December. Because the two planes, the path of the sun and the celestial equator move in opposite directions, the equinoxes and solstices do not occur at the same points every year. This anti-clock movement of the intersection point is called precession. It moves one degree in 72 years, one Zodiac sign of 30 degrees in 2,156 years and one circle in 25,868 years. For further information on calendar, solar or tropical year, precession, and other astronomical data, refer to any good encyclopedia or a publication on astronomy and astrology. The tropical year, based on the four seasons, is precise. It is 365.24224 solar days (365 days 5 hr 48 min 45.5 sec), and the tropical lunar year is 354.36708 solar days, a difference of 10.87516 solar days. We need not go far to find a workable calendar. Of all the present calendars, the official Iranian calendar, based on the astronomical system, is the most scientific calendar in use and bears the names of what are known as Zoroastrian months. It rightly has the vernal equinox (on or about 21st March) at the beginning of the spring and the year. The fourth month begins on the summer solstice (on or about 22 June), the seventh month on the autumnal equinox (on or about 23 September), and the ninth month on the winter solstice (on or about 22 December). In the true seasonal year, the first half contains 186 days and the second half about 179.242 days. This means that the first six months are of 31 days each, the following five months of 30 days each, and the last month of 29 days, but which automatically becomes of 30 days in the so-called "leap" year. The four seasons begin on the first days of the seasonal quarters. This is exactly what the Iranian calendar follows: The first six months are of 31 days each, the next five months of 30 days each and the last month is of 29 days but of 30 days in the leap year. Reports indicate that the Central Asian republics may follow suit. Historical evidence that the five Gatha days were added at the end of summer proves that the early "Zoroastrian" calendar had this fact in view. .Sh THE INDO-IRANIAN CALENDAR Evidences from the Avesta and the Vedas show that the Indo-Iranians, like many other people, followed a lunisolar year for their animal husbandry and agricultural purpose. The names of the six Gaahaanbaars, six parts of the Vedic year and the Achaemenian months, as seen below, show that the calendar was based on various seasonal phases of the year. The Gathas speak of the paths of the sun and the stars, and speaks about the waxing and waning phases of the moon, a sure sign of an accurate lunisolar year. The language used is astronomical, and it confirms the reports written in ancient Middle Eastern and Mediterranean writings that Zarathushtra was an outstanding astronomer also. It also confirms the statement in post-Sassanian Iranian astronomy books that Zarathushtra built an observatory in Zabol, Sistan (eastern Iran) and that it was inaugurated on 21st March 1725 BCE, the day King Vishtaspa and his courtiers converted, chose the Good Religion and joined the Zarathushtrian Fellowship. It also provides us with the clue that the Good Religion was founded by Zarathushtra, exactly twelve years earlier on vernal equinox of 1737 BCE. The Vispered, dedicated only to the six seasonal festivals, the "Gaahaanbaars", also shows that the early Zarathushtrian calendar was almost the old Indo-Iranian lunisolar calendar with its waxing and waning lunar phases. The month was based on moon's phases, and the year was calculated on the solar basis. The difference was corrected by an intercalation of eleven days at the end of the year on the Hamaspathmaidhaya Gahanbar of the vernal equinox. This was 0.12484 day or 2.99616 hours shorter. Only a further intercalation of one day after eight years (precisely after 8.010253 years), could keep the seasonal festivals in their proper places. How did the Gathic people correct it, we do not know. We know this much that no complaint has been recorded by them about the festivals drifting away from their relevant agricultural seasons. Sometime during the later Avestan age, the year was made into a purely solar year of 365 days with twelve months of thirty days and the five "Gatha" days as the intercalary period. Should we believe a 9th century Pahlavi tradition, the correction of five hours and a fraction was made good every four years, or the community had to wait for 40 years to intercalate 10 days or still more for 120 years to add a thirteenth month of 30 days. The usual reference to one month intercalation at the end of 120 years only reminds us of the disorder that prevailed during the last days of the Sassanian Empire and its subsequent fall. .Sh THE LEAP YEAR A point about intercalation in a ``leap'' year: The precise time of vernal equinox is determined by the International Meridian, at present Greenwich. The usual way is to count the year of 365 days and 6 hours. Four 6 hours, or one day, is added to bring back the year on the right track. This fourth year is called the ``leap year'' because it leaps one day ahead. But the actual length of the year is 6 hours but 5 hours 48 minutes and 45.5 seconds, a difference of 11 minutes and 14.5 seconds. This amount to one day in 128 days. It was to correct this that the leap years are those eras which are divisible by 400. Even this makes the Christian or Common year 26 seconds longer than the tropical year. The Iranian calendar does not have this problem. Its new year begins exactly at the beginning of the equinox. Although the formal Iranian year of the present days has its leap year, it should never worry about it. All it has to do is to see that if the right times falls after midnight 0 hours 00 minutes and 01 seconds to 0 hours 00 minutes and 00 seconds -- the first day of the year also begins with it. This is because the Avestan day begins with the ``Ushahin Gaah,'' the Dawn Time, which begins from midnight. Yes, the Iranians have been counting their day from midnight for, at least, 3738 years and it is the West that has adopted it very late in our times. The Iranian calendar DOES NOT need a leap year at all. It is automatically within the right time. I hope that one day the authorities concerned would realize this FACT and amend the calendar by eliminating the so-called leap year. .Sh CALENDAR NAMES Each of the twelve Avestan months and thirty days were named after a deity, some of them old Aryan gods and goddesses discarded by Zarathushtra but reintroduced later by authoritative priests, and some of them Gathic principles personified by the same priests into divine entities, all now called yazatas, meaning "venerated, venerable." "Year" in general was called "yaairi" or "yaari", but the intercalated solar year was known as "saredha", Old Persian of the Achaemenians "tharda", and Pahlavi and modern Persian "saal" (compared Sanskrit "sharad", autumn, year). This calendar is followed to this day by Iranian Zartoshtis and some Parsis. It is called Fasli, a modern Persian-Arabic word meaning "seasonal" However, majority of Parsis use Shahenshahi, the "Imperial" calendar. The Parsis have not intercalated since 1126 CE. It now begins in the last week of August 21st, full seven months plus one day earlier. The Iranian Zoroastrians, who follow the Qadimi Calendar, have abandoned intercalation since 1006 CE and the 365-day year has now forwarded their new year day by eight months. As seen, the two calendars are neither precisely "Gathic" nor astronomically scientific. So is the present Zoroastrian era of 1370 followed by the Shahenshahis, Qadimis and Parsi Faslis. It is based on the ascension of the last Sassanian king Yazdegerd III (632-642 CE + 10 years of wandering until his murder by Khosrow the miller) and has no religious significance at all. Fortunately, with the exception of a minute number, mostly residing in India, all Iranian Zoroastrians have given up the Qadimi calendar in favor of the Fasli one, and they reckon the Zarathushtrian Religious Era as the beginning. At present there is a move to unify all Zoroastrians, at least in North America and Europe, to adopt the Fasli calendar. .Sh NAMES OF SEASONAL TIMINGS The Gaahaanbaars: The agricultural people were in tune with nature in their day-to-day life. They fully knew the solar and lunar movements and the changes in the seasons. They had timed their activities to suit the climate in which they lived. This timetable was kept in step with saredha, the tropical solar year of 365 days, 5 hr, 48 min, and 45.5 sec, but differed a little on certain points. Their activities were scheduled to correspond with various phases of their agricultural life on the Iranian Plateau. It was divided into six phases. The end of one phase and the beginning of other were celebrated as a special time of festivity. The six seasonal festivals were: (1) Hamaspathmaidhaya, meaning "vernal equinox," the 1st day of Farvardin, the beginning of spring, on or about 21st March, was to celebrate the end of the old year and the beginning of the new year. It was, according to the Avesta, the time to "properly set" everything and prepare for the new year. (2) Maidhyoi-zaremaya (Mid-spring), 14th day of Ardibehesht, on or about 4th May, was the time to celebrate the occasion for the cattle having delivered their young and yielded "abundance of milk" and also for appraising the crops sown in late winter or early spring. (3) Maidhyoi-shema (Midsummer), 12th day of Tir, on or about 3rd July, was the beginning of the harvesting season. (4) Paitish-hahya (Grain-reaping), 25th day of Shahrivar, on or about 16th September, marked the end of harvesting. (5) Ayaathrema (no-travel), 24th day of Mehr, on or about 16th October, was to enjoy the end of trade caravans and the time to mate cattle before the winter set in. (6) Maidhyaairya (Midyear), 15th day of Dey, on or about 4th January, heralded the passing of the winter peak and for making preparations to meet the spring with agricultural activity. .Pp Only the first two festivals coincided with the solar seasonal changes. The others were purposely put off to meet the living conditions. They were not calendarically or traditionally bound but were very practical people, a point to note. Most probably the festivals were celebrated with sacrifices to gods and goddesses and by indulging in a joyous festivity. Gahanbars and Zarathushtrians: Asho Zarathushtra, born in an agricultural environment, preached and spread his Good Religion among people engaged in crop cultivation and animal husbandry. His dynamic message introduced a completely new order in spiritual, or better, as he put it, mental sphere and purged out all evil and superstitious thoughts, misleading words, harmful deeds, and superficial, superfluous rituals, but helped to strengthen and promote all the then-existing constructive activities of a good living. And the Gahanbars were one of the constructively enjoyable festivals. .Sh Chanting and Feasting: Avestan evidences, particularly the book of Vispered, show that the early Zarathushtrians turned the Gahanbar into an occasion to fit into their new pattern of life. Each festival was traditionally celebrated for one and later for five days. They were devoted to reciting, chanting, explaining, understanding, and holding questions-and-answers on each of the five Gathas of Asho Zarathushtra. The festival was rounded up with a feast prepared by collective participation and efforts, and merrymaking. A piece in the Avesta directs that all participants should bring whatever they can afford; dairy products, meat, vegetables, legumes, grain, other food ingredients, and firewood. If one was not in a position to contribute in kind, one might put his or her labor in preparing the food in a common pot, or just join the prayers. The food, with a large variety of ingredients, was a tasty stew, resembling today's more sophisticated Iranian "aash" or the Parsi spiced "dhansaak", both relished on the occasion. Merrymaking was the folk music and dances still observed among Iranian tribes all over the Iranian Plateau and beyond. The Zarathushtrian Assembly celebrates the Gahanbars with a relevant Gahanbar prayer, Gatha recital and explanation, a brief talk on an interesting subject, potluck lunch, friendly conversation, and music and dance. .Sh Vedic Calendar: It may be noted that the Indo-Aryans had also six seasons (Sanskrit rtu, Avestan ratu) evidently modified to meet the climate in the Indus Valley. They were: Vasanta (Spring), Grishma (Summer), Varsha (The Rains), Sharad (Autumn), Hemanta (Winter), and Shishira (the Cool season). Persians and Other Iranian Calendar: The Achaemenians, Sogdians, Chorasmians, and Armenians, all Zoroastrians by faith, had their own names for their months. The names of the Achaemenian months, as given in the bas-reliefs of Darius the Great are rendered to convey (1) Irrigation-canal-cleaning month, (2) Vigorous spring, (3) Garlic-collecting month, (4) Hot-step, (7) God-veneration, (8) Wolf-birth, (9) Fire-veneration, (10) Anaamaka -- Nameless month, and (12) Digging-up. Three names have not been given in Old Persian but we have their Elamite pronunciations and all, except two, are nonreligious terms. The Achaemenians had numbers instead of names for the days of the month. (see Old Persian, Ronald G. Kent, 2nd ed., New Haven, 1953). That confirms that the months as well as the days named after pre-Zarathushtrian deities and post-Zarathushtrian personifications of Gathic abstracts is a later addition. There are indications that it was done during the reign of Artaxerxes II (405-359 BCE), and that naming the months and days in honor of deities were adopted from the Egyptians. The names of the Gahanbars, and those of the Vedic, Achaemenian, Sogdian, Chorasmian, and Armenian months show that the names of the pre-Zarathushtrian and Gathic months must have been based on the seasons and social activities, and not on deities. These old names have, however, been so well obliterated by the authoritarian priests that we do not have any inkling of what they were. .Sh Later Avestan Calendar: The names of the twelve months in modern Persian and their Avestan forms with their corresponding Zodiac names are .Pp 1. Farvardin Fravashi/Fravarti Aries 21 March .Pp 2. Ardibehesht Asha Vahishta Taurus 21 April .Pp 3. Khordaad Haurvataat Gemini 22 May .Pp 4. Tir Tishtrya Cancer 22 June .Pp 5. Amordaad Ameretaa Leo 23 July .Pp 6. Shahrivar Khshathra Vairya Virgo 23 August .Pp 7. Mehr Mithra Libra 23 Sept .Pp 8. Aabaan Ap Scorpio 23 Oct .Pp 9. Aazar Aathra Sagittarius 22 Nov .Pp 10. Dey Dathva Capricorn 22 Dec .Pp 11. Bahman Vohu Manah Aquarius 21 Jan .Pp 12. Esfand Spentaa Aaramaiti Pisces 20 Feb .Pp Note: Of these only those in bold letters are the Gathic "Primal Principles of Life," Aazar/Aathra has been mentioned in the Gathas as the symbol of the Progressive Mentality (Spenta Mainyu), and "ap" (water) is also mentioned in the Gathic texts, but the rest are later Avestan names. .Sh THE WEEK The early Avestan people had no notion of the week, a period of seven days now in universal use as a division of time. Week is a man-made unit. Its length has, among various people, been from five to ten days. But since the lunar month, one of the earliest ways of reckoning time, is alternately of 29 and 30 days with two phases of waxing and waning moon, it was quite easy to further divide it and have four quarters of seven and eight days accommodated in it. The seven planets visible to the naked eye may have also played a part in its formation. That is why weekdays are named after celestial bodies. However, the present universal week is most probably of Chaldean or Hebrew origin, and has been generalized by Jewish, Christian and Islamic persuasion. The later Avestan solar calendar, based on thirty days in a month, has four quarters -- the first two of seven days and the last two of eight days. But Avesta and Pahlavi do not have any names for each of these quarters or for the weekdays. Modern Persian follows the Hebrew pattern of having Saturday as Shanbeh, Persianized form of "Shabbath", and then counting from one to five as Yek-shanbeh, Do-shanbeh, Se-shanbeh, Chahaar-shanbeh, Panj-shanbeh, and under the Islamic influence, Aadineh or Jom'eh for Friday, the day of mass prayers. .Sh ERAS Pahlavi writings tell us that the religious era began from the day Zarathushtra proclaimed his Divine Mission to humanity. This era, based on the astronomical calculations that Zarathushtra declared his mission on the vernal equinox when, according to the precession, the period of Aries is supposed to have begun, comes to be 3738/39 in 2001 CE i.e. 1737 BCE. It has been called the "Year of Religion" in Pahlavi writings. The Zarathushtrian Assembly calls it the Zarathushtrian Religious Era (Z.E.R./ZRE) and has, since its establishment in 1990, observed it as the beginning of the Zarathushtrian calendar. The Zartoshti community in Iran joined in to observe ZRE as its calendar in 1993, and many Irani Zartoshtis in diaspora have also accepted it. Earlier, each of the Iranian kings, following the pattern set by other Middle Eastern rulers, particularly the Babylonians, observed a new era from his own ascension to the throne. With as many as 80 rulers on the Iranian throne during the thousand and odd years of Achaemenians, Macedonians, Parthians, and Sassanians, much confusion in chronology has arisen, and many dates have been misinformed, misused, misplaced, misinterpreted, miscalculated, and missed. The Yazdgerdi era reminds one of the last Emperor who got overthrown by Arab invaders. It is not a happy recollection. Sassanians and Two Calendars: The Sassanians continued to maintain both the "yaairi" of 365 days and the "saredha" of 365.24224 days. The first they called "oshmurdik" meaning "rememberable, reckonable" and the second "vihezakik" meaning "moving, progressive, intercalary." While the "rememberable" was easy for the laity to memorize and count them by names, the "intercalary" belonged to the astronomer priests, linked with the imperial court, to keep the formal year precise and in tune with the seasons. The fall of the Sassanian Empire fell the astronomer priests of their high position. Nevertheless, the intercalary year was, Pahlavi books and the present position of the Qadimi and Shahenshahi calendars tell, kept until the 11th century CE. The decline of astronomer priests put an end to Vihezakik and the lay priests have continued with their "Ushmordik," advancing about one day in every four years out of the season and the solar year. Economic and seasonal revenue collection, however, forced the Muslim Caliphs to maintain, evidently by those astronomer priests who had embraced Islam, the intercalary year in addition to the Islamic calendar of a purely lunar year. It was this Vihezakik year maintained halfheartedly by Muslim rulers, which was improved, perfected and formally restored by Omar Khayyam and other Iranian scientists. It was named the "Jalaali" calendar after its patron, Sultan Jalal al-Din Malekshah Saljuqi (1072-1092 CE). The Fasli year, officially observed by Iranians -- Zartoshtis, Jews, Christians, and Muslims -- in modern Iran, is the "saredha" of the Avestan people, "tharda" of the Achaemenian, "Vihezakik" of the Sassanians, and the "Jalali" of Omar Khayyam. The precise solar year also reckoned by all observatories in the world. It is the Universal Astronomical and Scientific Year. It is this Vihezakik (Persian "Behizaki") calendar, now called "Khorshidi" (solar), the official Iranian calendar, the precise calendar, with its dates numbered, that the Zarathushtrian Assembly follows. It is astronomically precise. It is progressively Zarathushtrian. .Sh HISTORY NO HISTORY. .Sh OTHER VERSIONS No other versions rumor to exist. .Sh AUTHOR Written by Ashkan Ghassemi. .Sh REPORTING BUGS Report jcal bugs to libjalali home page: .Sh SEE ALSO .Nm jdate (1), .Nm jctime (3), .Nm jstrftime (3), .Nm jstrptime (3) .Sh COPYRIGHT Copyright (C) 2011 Ashkan Ghassemi. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. man/jctime.30000644000175000001440000003316211573330104012356 0ustar ashkanusers.\" * jctime.3 - Tools for manipulating Jalali representation of Iranian calendar .\" * and necessary conversations to Gregorian calendar. .\" * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. .\" * .\" * This file is part of libjalali. .\" * .\" * libjalali is free software: you can redistribute it and/or modify .\" * it under the terms of the GNU Lesser General Public License as published by .\" * the Free Software Foundation, either version 3 of the License, or .\" * (at your option) any later version. .\" * .\" * libjalali 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 Lesser General Public License for more details. .\" * .\" * You should have received a copy of the GNU Lesser General Public License .\" * along with libjalali. If not, see . .TH JCTIME 3 2011-05-28 "" "libjalali Manual" .SH NAME jasctime, jctime, jgmtime, jlocaltime, jmktime, jasctime_r, jctime_r, jgmtime_r, jlocaltime_r \- transform jalali date and time to broken-down jalali time or ASCII .SH SYNOPSIS .nf .B #include .sp .BI "char *jasctime(const struct jtm *" jtm ); .br .BI "char *jasctime_r(const struct jtm *" jtm ", char *" buf ); .sp .BI "char *jctime(const time_t *" timep ); .br .BI "char *jctime_r(const time_t *" timep ", char *" buf ); .sp .BI "struct jtm *jgmtime(const time_t *" timep ); .br .BI "struct jtm *jgmtime_r(const time_t *" timep ", struct jtm *" result ); .sp .BI "struct jtm *jlocaltime(const time_t *" timep ); .br .BI "struct jtm *jlocaltime_r(const time_t *" timep ", struct jtm *" result ); .sp .BI "time_t jmktime(struct jtm *" jtm ); .br .sp .B #include .sp .BI "int jalali_is_jleap(int " year ); .sp .BI "void jalali_create_time_from_secs(time_t " time ", struct ab_jtm* " ab_jtm ); .br .BI "time_t jalali_create_secs_from_time(const struct ab_jtm* " ab_jtm ); .sp .BI "int jalali_create_date_from_days(struct jtm* " jtm ); .br .BI "int jalali_create_days_from_date(struct jtm* " jtm ); .sp .BI "void jalali_get_jyear_info(struct jyinfo* " jyinfo ); .sp .BI "void jalali_get_date(int " p ", struct jtm* " jtm ); .br .BI "int jalali_get_diff(const struct jtm* " jtm ); .sp .BI "void jalali_update(struct jtm* " jtm ); .br .fi .sp .in .ad l .sp Link with -ljalali .sp .RE .ad .SH DESCRIPTION The .BR jctime (), .BR jgmtime () and .BR jlocaltime () functions all take an argument of data type \fItime_t\fP which represents calendar time. When interpreted as an absolute time value, it represents the number of seconds elapsed since the Epoch, 1970-01-01 (1348-10-11 in Jalali) 00:00:00 +0000 (UTC). .PP The .BR jasctime () and .BR jmktime () functions both take an argument representing broken-down jalali time which is a representation separated into year, month, day, etc. .PP Broken-down jalali time is stored in the structure \fIjtm\fP which is defined in \fI\fP as follows: .sp .in +4n .nf struct jtm { int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* hours */ int tm_mday; /* day of the month */ int tm_mon; /* month */ int tm_year; /* year */ int tm_wday; /* day of the week */ int tm_yday; /* day in the year */ int tm_isdst; /* daylight saving time */ }; .fi .in .PP The members of the \fIjtm\fP structure are: .TP 10 .I tm_sec The number of seconds after the minute, in the range 0 to 59. .TP .I tm_min The number of minutes after the hour, in the range 0 to 59. .TP .I tm_hour The number of hours past midnight, in the range 0 to 23. .TP .I tm_mday The day of the month, in the range 1 to 31. .TP .I tm_mon The number of months since Farvadin, in the range 0 to 11. .TP .I tm_year Absolute year number including the century. .TP .I tm_wday The number of days since Saturday, in the range 0 to 6. .TP .I tm_yday The number of days since Farvadin 1, in the range 0 to 365. .TP .I tm_isdst A flag that indicates whether daylight saving time is in effect at the time described. The value is positive if daylight saving time is in effect, zero otherwise. .PP Information about a certain year in jalali system is stored in the structure \fIjyinfo\fP in the following format: .sp .in +4n .nf struct jyinfo { int lf; /* leap indicator flag */ int y; /* year */ int r; /* reamining years in grand cycle */ int p; /* passed years from grand cycle*/ int rl; /* remaining leap years in grand cycle */ int pl; /* passed leap years in grand cycle */ int apl; /* absolute passed leaps */ }; .fi .in .PP The members of the \fIjyinfo\fP structure are: .TP 10 .I lf A flag that indicates whether a year is leap or not. .TP .I y Absolute year number including the century. .TP .I r The number of remaining years in the grand cycle. (2820 years in length) .TP .I p The number of passed years in the grand cycle. .TP .I rl The number of remaining leap years in the grand cycle. .TP .I pl The number of passed leap years in the grand cycle. .TP .I apl The absolute number of passed leaps since Epoch. .PP Internal jalali date functions make use of passed days since UTC Epoch to calculate date and time. To store these information, the following structure is also defined: .sp .in +4n .nf struct ab_jtm { int ab_sec; int ab_min; int ab_hour; int ab_days; }; .fi .in .PP The members of the \fIab_jtm\fP structure are as follows: .TP 10 .I ab_sec The number of seconds. .TP .I ab_min The number of minutes. .TP .I ab_hour The number of hours .TP .I ab_days The absolute number of days since UTC Epoch. (1348-10-11) .PP The call .BI jctime( t ) is equivalent to .BI jasctime(jlocaltime( t )) \fR. It converts the calendar time \fIt\fP into a null-terminated string of the form .sp .RS "Jom Kho 06 22:59:17 1390\\n" .RE .sp The abbreviations for the days of the week are "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", and "Sat". Farsi transliteration for the days of the week are "Sha", "Yek", "Dos", "Ses", "Cha", "Pan", and "Jom". The abbreviations for the months are "Far", "Ord", "Kho", "Tir", "Mor", "Sha", "Meh", "Aba", "Aza", "Dey", "Bah", and "Esf". The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions. The reentrant version .BR jctime_r () does the same, but stores the string in a user-supplied buffer which should have room for at least 26 bytes. .PP The .BR jgmtime () function converts the calendar time \fItimep\fP to broken-down jalali time representation, expressed in Coordinated Universal Time (UTC). The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the jalali date and time functions. The .BR jgmtime_r () function does the same, but stores the data in a user-supplied struct. The function acts as if it called .BR tzset (3) .PP The .BR jlocaltime () function converts the calendar time \fItimep\fP to broken-down jalali time representation, expressed relative to the user's specified timezone. The function acts as if it called .BR tzset (3) and sets the external variables \fItzname\fP with information about the current timezone, \fItimezone\fP with the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and \fIdaylight\fP to a nonzero value if daylight savings time rules apply during some part of the year. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the jalali date and time functions. The .BR jlocaltime_r () function does the same, but stores the data in a user-supplied struct. .PP The .BR jasctime () function converts the broken-down jalali time value \fIjtm\fP into a null-terminated string with the same format as .BR jctime (). The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions. The .BR jasctime_r () function does the same, but stores the string in a user-supplied buffer which should have room for at least 26 bytes. .PP The .BR jmktime () function converts a broken-down jalali time structure, expressed as local time, to calendar time representation. The function ignores the values supplied by the caller in the .I tm_wday field. The value specified in the .I tm_isdst field informs .BR jmktime () whether or not daylight saving time (DST) is in effect for the time supplied in the .I jtm structure: a positive value means DST is in effect; zero means that DST is not in effect; The .BR jmktime () function modifies the fields of the .IR jtm structure as follows: .I tm_wday and .I tm_yday are set to values determined from the contents of the other fields; if structure members are outside their valid interval, they will be normalized (so that, for example, 40 Bahman is changed into 10 Esfand); Calling .BR jmktime () also sets the external variable \fItzname\fP with information about the current timezone. .BR jmktime () function does not check the values of the \fIjtm\fP structure. .PP There are a number of non-standard functions also provided to work with jalali date and time. .PP The .BR jalali_is_jleap () function returns an integer indicating whether the year specified is leap or not. It returns 1 on the event of encountering a leap year, 0 otherwise. .PP The .BR jalali_create_time_from_secs () function fills out the \fIab_jtm\fP structure members based on the absolute number of seconds elapsed since UTC Epoch. .PP The .BR jalali_create_secs_from_time () function is the converse function to .BR jalali_create_time_from_secs () which returns absolute number of seconds elapsed since UTC Epoch based on the supplied \fIab_jtm\fP structure. .PP The .BR jalali_create_date_from_days () function alters \fItm_mon\fP and \fItm_mday\fP fields of the broken-down jalali time strucutre based on it's \fItm_yday\fP field. It returns -1 on the event of encountering any errors and structure fields remain untouched. .PP The .BR jalali_create_days_from_date () function alters \fItm_yday\fP field of the broken-down jalali time structure based on it's \fItm_mon\fP and \fItm_mday\fP fields. It returns -1 on the event of encountering any errors and structure fields remain untouched. .PP The .BR jalali_get_jyear_info () function modifies \fIjyinfo\fP structure fields to match information for year specified by it's \fIy\fP field. Information regarding a year in jalali system includes leap flag, passed and reamining years in the grand cycle, passed and remaining leap years in the grand cycle and absolute number of passed leaps since UTC Epoch. .PP The .BR jalali_get_date () function calculates the jalali date based on number of days since UTC epoch. It alters the broken-down jalali time structure fields accordingly. .PP The .BR jalali_get_diff () function is the converse function of .BR jalali_get_date () and calculates the number of days passed since UTC Epoch based on a broken-down jalali time structure supplied to it. .PP The .BR jalali_update () function updates \fItm_wday\fP and \fItm_yday\fP fields of the broken-down jalali time structure based on it's \fItm_year\fP , \fItm_mon\fP and \fItm_mday\fP. \fItm_isdst\fP, \fItm_gmtoff\fP and \fItm_zone\fP fields are set accordingly. \fItm_hour\fP, \fItm_min\fP and \fItm_sec\fP fields remain untouched. .SH "EXAMPLES" The following program converts a jalali date to gregorian .nf #include #include #include #include #include int main(int argc, char ** argv) { struct tm tm; struct jtm jtm; time_t t; jtm.tm_year = atoi(argv[1]); jtm.tm_mon = atoi(argv[2]); jtm.tm_mday = atoi(argv[3]); jalali_update(&jtm); t = jmktime(&jtm); localtime_r(&t, &tm); printf("%d/%d/%d \\n", tm.tm_year, tm.tm_mon, tm.tm_mday); exit(EXIT_SUCCESS); } .SH "RETURN VALUE" Each of these functions returns the value described, or NULL (\-1 in case of .BR jmktime ()) in case an error was detected. .SH "CONFORMING TO" C99 Standards. These functions are provided with APIs similar to that of POSIX.1-2001 date and time manipulation and are .B NOT part of POSIX standard. For thread safety .BR jasctime (), .BR jctime (), .BR gmtime (), .BR localtime (), and .BR mktime () set of functions should nout be used. See reentrant versions. like POSIX.1-2008, the following functions: .BR jasctime (), .BR jasctime_r (), .BR jctime (), and .BR jctime_r () should be considered obsolete. Use .BR jstrftime (3) instead. .SH NOTES The four functions .BR jasctime (), .BR jctime (), .BR jgmtime () and .BR jlocaltime () return a pointer to static data and hence are not thread-safe. Thread-safe versions are .BR jasctime_r (), .BR jctime_r (), .BR jgmtime_r () and .BR jlocaltime_r () .LP libjalali version of \fIstruct jtm\fP has additional fields .sp .RS .nf long tm_gmtoff; /* Seconds east of UTC */ const char *tm_zone; /* Timezone abbreviation */ .fi .SH "SEE ALSO" .BR jdate (1), .BR jcal (1), .BR gettimeofday (2), .BR time (2), .BR utime (2), .BR clock (3), .BR difftime (3), .BR jstrftime (3), .BR jstrptime (3), .BR timegm (3), .BR tzset (3), .BR time (7) .SH COLOPHON This page is part of release 0.2 of the libjalali .I man-pages .SH AUTHOR Written by Ashkan Ghassemi. .SH REPORTING BUGS Report libjalali bugs to libjalali home page: .SH COPYRIGHT Copyright (C) 2011 Ashkan Ghassemi. License LGPLv3+: GNU LGPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. man/jstrptime.30000644000175000001440000001317411574337305013140 0ustar ashkanusers.\" * jstrftime.3 - Tools for manipulating Jalali representation of Iranian calendar .\" * and necessary conversations to Gregorian calendar. .\" * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. .\" * .\" * This file is part of libjalali. .\" * .\" * libjalali is free software: you can redistribute it and/or modify .\" * it under the terms of the GNU Lesser General Public License as published by .\" * the Free Software Foundation, either version 3 of the License, or .\" * (at your option) any later version. .\" * .\" * libjalali 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 Lesser General Public License for more details. .\" * .\" * You should have received a copy of the GNU Lesser General Public License .\" * along with libjalali. If not, see . .TH JSTRPTIME 3 2011-05-28 "GNU" "libjalali Manual" .SH NAME jstrptime \- convert a string representation of jalali date and time to a jalali time jtm structure .SH SYNOPSIS .B #include .sp .BI "char *jstrptime(const char *" s ", const char *" format , .BI "struct jtm *" jtm ); .sp Link with -ljalali .SH DESCRIPTION The .BR jstrptime () function is the converse function to .BR jstrftime (3) and converts the character string pointed to by .I s to values which are stored in the .I jtm structure pointed to by .IR jtm , using the format specified by .IR format . Here .I format is a character string that consists of field descriptors and text characters, reminiscent of .BR scanf (3). Each field descriptor consists of a .B % character followed by another character that specifies the replacement for the field descriptor. All other characters in the .I format string must have a matching character in the input string. There should be white\%space or other alphanumeric characters between any two field descriptors. .PP The .BR jstrptime () function processes the input string from left to right. Each of the three possible input elements (whitespace, literal, or format) are handled one after the other. If the input cannot be matched to the format string the function stops. The remainder of the format and input strings are not processed. .PP The supported input field descriptors are listed below. In case a text string (such as a weekday or month name) is to be matched, the comparison is case insensitive. In case a number is to be matched, leading zeros are permitted but not required. .TP .B %% The .B % character. .TP .BR %a " or " %A " or " %h " or " %q The weekday name in abbreviated form or the full name. .TP .BR %b " or " %B The month name in abbreviated form or the full name. .TP .BR %d " or " %e The day of month (1-31). .TP .B %H The hour (0-23). .TP .B %j The day number in the year (1-366). .TP .B %m The month number (1-12). .TP .B %M The minute (0-59). .TP .B %s Seconds since UTC Epoch. .TP .B %S The second (0-59). .TP .B %y The year within century (0-99). When a century is not otherwise specified, values in the range 19-99 refer to years in the fourteenth century (1319-1399); values in the range 00-18 refer to years in the fifteenth century (1400-1418). .TP .B %Y The year, including century (for example, 1390). .LP The broken-down jalali time structure \fIjtm\fP is defined in \fI\fP as follows: .sp .in +4n .nf struct jtm { int tm_sec; /* seconds */ int tm_min; /* minutes */ int tm_hour; /* hours */ int tm_mday; /* day of the month */ int tm_mon; /* month */ int tm_year; /* year */ int tm_wday; /* day of the week */ int tm_yday; /* day in the year */ int tm_isdst; /* daylight saving time */ }; .fi .in .SH "RETURN VALUE" The return value of the function is a pointer to the first character not processed in this function call. In case the input string contains more characters than required by the format string the return value points right after the last consumed input character. In case the whole input string is consumed the return value points to the null byte at the end of the string. If .BR jstrptime () fails to match all of the format string and therefore an error occurred the function returns NULL. .SH "CONFORMING TO" C99. .SH NOTES .LP In principle, this function does not initialize \fIjtm\fP but only stores the values specified. This means that \fIjtm\fP should be initialized before the call. libjalali does not touch those fields which are not explicitly specified. .SH EXAMPLE The following example demonstrates the use of .BR jstrptime (3) and .BR jstrftime (3). .sp .nf #include #include #include #include #include #include int main(void) { struct jtm tm; char buf[255]; memset(&jtm, 0, sizeof(struct jtm)); jstrptime("1390\-03\-17 08:33:01", "%Y\-%m\-%d %H:%M:%S", &jtm); jstrftime(buf, sizeof(buf), "%d %b %Y %H:%M", &jtm); puts(buf); exit(EXIT_SUCCESS); } .fi .SH "SEE ALSO" .BR time (2), .BR jdate (1), .BR jcal (1), .BR getdate (3), .BR scanf (3), .BR jstrftime (3), .BR jctime (3), .BR feature_test_macros (7) .SH COLOPHON This page is part of release 0.2 of the libjalali .I man-pages .SH AUTHOR Written by Ashkan Ghassemi. .SH REPORTING BUGS Report libjalali bugs to libjalali home page: .SH COPYRIGHT Copyright (C) 2011 Ashkan Ghassemi. License LGPLv3+: GNU LGPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. man/jdate.10000644000175000001440000001123211575737310012176 0ustar ashkanusers.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .\" * .\" * jcal.1 - Unix cal-like interface to libjalali. .\" * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. .\" * .\" * This file is part of jcal. .\" * .\" * jcal 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 3 of the License, or .\" * (at your option) any later version. .\" * .\" * jcal 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 should have received a copy of the GNU General Public License .\" * along with jcal. If not, see . .\" * .TH JDATE "1" "Khordad 6, 1390" "jdate" "User Commands" .SH NAME jdate \- manual page for jdate .SH SYNOPSIS .B jdate [\fIarRuhV\fR]... [\fI+OUTPUT_FORMAT\fR][\fId INPUT_FORMAT;DATE_STRING\fR] .SH DESCRIPTION Display the current date and time in the given FORMAT. .TP \fB\-d\fR, \fB\-\-date\fR=\fIFORMAT\fR;STRING display time described by STRING, not `now' .TP \fB\-a\fR, \fB\-\-access\fR=\fIFILE\fR display the last access time of FILE. .TP \fB\-r\fR, \fB\-\-reference\fR=\fIFILE\fR display the last modification time of FILE. .TP \fB\-j\fR, \fB\-\-jalali\fR=\fI%Y\fR/\fI%m\fR/\fI%d\fR converts a gregorian date to jalali. .TP \fB\-g\fR, \fB\-\-gregorian\fR=\fI%Y\fR/\fI%m\fR/\fI%d\fR converts a jalali date to gregorian. .TP \fB\-R\fR, \fB\-\-rfc\-2822\fR output date and time in RFC 2822 format. Example: Jom, 06 Khor 1390 13:44:56 \fB\-0430\fR. .TP \fB\-u\fR, \fB\-\-utc\fR, \fB\-\-universal\fR print Coordinated Universal Time. .TP \fB\-h\fR, \fB\-\-help\fR display this help and exit. .TP \fB\-V\fR, \fB\-\-version\fR output version information and exit. .TP FORMAT controls the output. Interpreted sequences are: .TP %% a literal % .TP %a abbreviated weekday name (e.g., Sun) .TP %A full weekday name (e.g., Sunday) .TP %b abbreviated month name (e.g., Khor) .TP %B full month name (e.g., Khordad) .TP %c date and time (e.g., Jome Kho 6 17:18:25 1390) .TP %C century; like %Y, except omit last two digits (e.g., 13) .TP %d day of month (e.g., 01) .TP %D date; same as %Y/%m/%d .TP %e day of month, space padded; same as %_d .TP %E date and time in Farsi. (utf8) .TP %F full date; same as %Y\-%m\-%d .TP %h abbreviated Farsi weekday name in English transliteration (e.g. Jom) .TP %q full Farsi weekday name in English transliteration (e.g. Jomeh) .TP %g abbreviated Farsi weekday name. (utf8) .TP %G full Farsi weekday name. (utf8) .TP %v abbreviated Farsi month name. (utf8) .TP %V full Farsi month name. (utf8) .TP %H hour (00..23) .TP %I hour (01..12) .TP %j day of year (001..366) .TP %k hour (0..23) .TP %l hour (1..12) .TP %m month (01..12) .TP %M minute (00..59) .TP %n a newline .TP %O AM or PM notation for time in Farsi. (utf8) .TP %p either AM or PM; blank if not known .TP %P like %p, but lower case .TP %r 12\-hour clock time (e.g., 17:24:04 PM) .TP %R 24\-hour hour and minute; same as %H:%M .TP %s seconds since 1970\-01\-01 00:00:00 UTC .TP %S second (00..59) .TP %t a tab .TP %T time; same as %H:%M:%S .TP %u day of week (1..7); 1 is Saturday .TP %U week number of year, with Saturday as first day of week (00..53) .TP %w day of week (0..6); 0 is Saturday .TP %W date representation in Farsi. (utf8) .TP %x date representation (e.g., 06/03/90) .TP %X time representation in Farsi. (utf8) .TP %y last two digits of year (00..99) .TP %Y year .TP %z +hhmm numeric time zone (e.g., +0330) .TP %Z alphabetic time zone abbreviation (e.g., IRST) .SH EXAMPLES .TP jdate -uR formats current UTC date and time in RFC2822 format. .TP jdate '+%Y-%m-%d %H:%M:%S' formats current local date and time in the above format. e.g. 1390-03-06 21:12:17 .TP jdate --access=foo.bar displays last access time for file foo.bar .TP jdate '+%s' --date='%Y/%m/%d-%H:%M:%S;1390/03/06-21:14:17' displays seconds since epoch (UTC) for local date specified by date string. .SH AUTHOR Written by Ashkan Ghassemi. .SH REPORTING BUGS Report jdate bugs to libjalali home page: .SH "SEE ALSO" .BR jcal (1), .BR jctime (3), .BR jstrftime (3), .BR jstrptime (3) .SH COPYRIGHT Copyright (C) 2011 Ashkan Ghassemi. License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. man/jalali_is_jleap.30000644000175000001440000000002211570077055014204 0ustar ashkanusers.so man3/jctime.3 man/jalali_get_diff.30000644000175000001440000000002211570077055014165 0ustar ashkanusers.so man3/jctime.3 man/jgmtime_r.30000644000175000001440000000002211570077055013057 0ustar ashkanusers.so man3/jctime.3 man/jlocaltime_r.30000644000175000001440000000002211570077055013546 0ustar ashkanusers.so man3/jctime.3 man/jlocaltime.30000644000175000001440000000002211570077055013225 0ustar ashkanusers.so man3/jctime.3 man/jalali_update.30000644000175000001440000000002211570077055013700 0ustar ashkanusers.so man3/jctime.3 man/jmktime.30000644000175000001440000000002211570077055012542 0ustar ashkanusers.so man3/jctime.3 man/jalali_create_secs_from_time.30000644000175000001440000000002211570077055016737 0ustar ashkanusers.so man3/jctime.3 NEWS0000644000175000001440000000003611570104215010734 0ustar ashkanusersPlease see the file ChangeLog README0000644000175000001440000000400511573325565011135 0ustar ashkanusers/* * README - Unix cal-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ jcal is a UNIX cal-like tool to display calendar based on jalali calendar system. jdate is UNIX date-like tool to display date and time based on jalali calendar system jcal switches in brief: -y Display a calendar for the current year. -p Display Farsi names and numbers. -P Display year based on Pahlavi epoch. -e Display English names for weekdays. -j Display Julian dates (days one-based, numbered from Farvardin 1). -1 Display single month output. (This is the default.) -3 Display prev/current/next months output. -V Display calendar version. See man jcal for more information. jdate switches in brief: -a Display the last access time for a file. -r Display the last modification time for a file. -d Interpret date according to date-string instead of ``now''. -R Ouput in RFC2822 format. -u Display Coordinated Universal Time. -h Display help. -V Display version. If you're experiencing troubles, compiling the package with GNU's build system then keep reading. Unsafe way of compilation ========================= There is a non-portable Makefile available in package tree ``Makefile.old'' If you had troubles, compiling your package with ./configure script, rename Makefile.old to Makefile, then simply invoke make and then make install as root. src/0000755000175000001440000000000011625553350011036 5ustar ashkanuserssrc/jcal.c0000644000175000001440000003236411575232017012121 0ustar ashkanusers/* * jcal.c - Unix cal-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ #include #include #include #include #include "termcap.h" #include "jcal.h" #include "../libjalali/jalali.h" #include "../libjalali/jtime.h" extern const char* jalali_months[]; extern const char* jalali_days[]; extern const char* jalali_days_fa[]; extern const char* jalali_days_3[]; extern const char* jalali_days_3_fa[]; extern const char* jalali_days_2[]; extern const char* jalali_days_2_fa[]; extern const char* fa_jalali_months[]; extern const char* fa_jalali_days_3[]; extern const char* fa_jalali_days_2[]; extern const int jalali_month_len[]; extern char* optarg; /* * @Create, set, destroy and show set of cal_matrix functions. * To avoid using cursor movement escape sequences (ANSI, vt100, etc.) * we create a matrix of calendar days to form a standard sequence of * numbers to be printed verbatim on screen. Each matrix can have unlimited * number of monthly calendars thus the current version of jcal is simple and * does not require curses or similar libraries and is effectively independent * of termcap. * To disable standard terminal escape sequences for colors completely, * compile with NO_COLOR. */ /* * Sets the matrix according to a given jalali date and prefix. */ void set_cal_matrix(struct cal_layout* l, struct jtm* ct, struct cal_matrix* mat, int prefix) { struct jtm mb; struct jtm lt; time_t t; int diff; int _prefix = prefix * (7 + l->margin); int m, c; int i, j; time(&t); jlocaltime_r(&t, <); memcpy(&mb, ct, sizeof(struct jtm)); diff = (mb.tm_mday - 1) % 7; mb.tm_wday = (mb.tm_wday - diff) % 7; if (mb.tm_wday < 0) mb.tm_wday += 7; mb.tm_mday = 1; jalali_create_days_from_date(&mb); m = (jalali_is_jleap(mb.tm_year) && mb.tm_mon == 11) ? 30 : jalali_month_len[mb.tm_mon]; j = mb.tm_wday; for (i=0,c=0; i<=mat->height && c < m; i++) { for (; j<=6 && c < m; j++) { if ((mb.tm_year == lt.tm_year) && (mb.tm_mon == lt.tm_mon) && (mb.tm_mday + c == lt.tm_mday)) { mat->m[i][j+_prefix] = (l->julian) ? 1000 + mb.tm_yday + c + 1 : 1000 + mb.tm_mday + c; } else { mat->m[i][j+_prefix] = (l->julian) ? mb.tm_yday + c + 1 : mb.tm_mday + c; } c++; } j = 0; } } /* * Returns 0, if the given column is located within margins between calendars, * 1 otherwise. */ int is_in_margin(struct cal_layout* l, struct cal_matrix* mat, int c) { int i; if (mat->n == 1) { if (c < 6) return 0; else if (c == 6) return 2; else return 1; } for (i=0; i<=mat->n - 1; i++) { if (c < (i * (7 + l->margin)) + 7 - 1) { return 0; } else if (c == (i * (7 + l->margin) + 7) - 1) { return 2; } else if ((c >= (i * (7 + l->margin) + 7)) && (c < ((i+1) * (7 + l->margin)))) { return 1; } } return 0; } /* * Displays the calendar matrix over standard screen. * @Should not be used directly. (See display_cal()) */ void show_cal_matrix(struct cal_layout* l, struct cal_matrix* mat) { int i, j, m; char buf[100]; for (i=0; iheight; i++) { for (j=0; jwidth; j++) { m = is_in_margin(l, mat, j); if (m == 1) { printf(" "); } else if (m == 0) { if (mat->m[i][j] == 0) printf((l->julian) ? " " : " "); else if (mat->m[i][j] > 1000 && l->color) { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j] - 1000); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j] - 1000); } printf("%s%s%s ", TERM_BLACK_ON_WHITE, buf, TERM_RESET); } else if (mat->m[i][j] > 1000 && !l->color) { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j] - 1000); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j] - 1000); } printf("%s ", buf); } else { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j]); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j]); } printf("%s ", buf); } } else { if (mat->m[i][j] == 0) printf((l->julian) ? " " : " "); else if (mat->m[i][j] > 1000 && l->color) { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j] - 1000); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j] - 1000); } printf("%s%s%s ", TERM_RED_ON_WHITE, buf, TERM_RESET); } else if ((mat->m[i][j] > 1000) && (!l->color)) { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j] - 1000); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j] - 1000); } printf("%s", buf); } else if (l->color) { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j]); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j]); } printf("%s%s%s", TERM_RED, buf, TERM_RESET); } else { if (l->farsi) { jalali_to_farsi(buf, 100, 2+l->julian, " ", mat->m[i][j]); } else { snprintf(buf, 100, "%*d", 2+l->julian, mat->m[i][j]); } printf("%s", buf); } } buf[0] = 0; } printf("\n"); } } /* * Allocates memory for our calendar matrix and sets it's width * and height according to number of calendars. */ void create_cal_matrix(struct cal_layout* l, struct cal_matrix* mat) { mat->width = (mat->n * 7) + ((mat->n - 1) * l->margin) ; mat->height = 6; mat->m = malloc(mat->height * sizeof(int*)); int i; for (i=0; iheight; i++) { mat->m[i] = malloc(mat->width * sizeof(int)); memset(mat->m[i], 0, mat->width * sizeof(int)); } } /* * Frees the allocated calendar memory. */ void destroy_cal_matrix(struct cal_matrix* mat) { int i; for (i=0; iheight; i++) { free(mat->m[i]); } free(mat->m); } /* * Displays calendar, including cal title and week days. */ void show_cal(struct cal_layout* l, struct cal_matrix* m, struct jtm** _j) { char** ptr_d; int i, k; int cw = (l->farsi) ? 2 : 1; int cal_width = (l->julian) ? 7 * 3 + 6 : 7 * 2 + 6; char cal_t[3][MAX_BUF_SIZE]; char cal_y[3][100]; int cal_tw[3]; char buf[100]; if (l->farsi) ptr_d = (l->julian) ? (char**) fa_jalali_days_3 : (char**) fa_jalali_days_2; else if (l->english) ptr_d = (l->julian) ? (char**) jalali_days_3 : (char**) jalali_days_2; else ptr_d = (l->julian) ? (char**) jalali_days_3_fa : (char**) jalali_days_2_fa; for (i=0; in; i++) { if (l->farsi) { jalali_to_farsi(buf, 100, 0, " ", _j[i]->tm_year + ((l->pahlavi) ? PAHLAVI_ISLAMIC_DIFF : 0)); } else { snprintf(buf, 100, "%d", _j[i]->tm_year + ((l->pahlavi) ? PAHLAVI_ISLAMIC_DIFF : 0)); } snprintf(cal_y[i], 100, "%s%s", buf, (l->pahlavi) ? ((l->farsi) ? " په" : "(pa)") : ""); buf[0] = 0; } for (i=0; in; i++) { snprintf(cal_t[i], MAX_BUF_SIZE, "%s %s", (l->farsi) ? fa_jalali_months[_j[i]->tm_mon] : jalali_months[_j[i]->tm_mon], (l->syear) ? cal_y[i] : ""); cal_tw[i] = (cal_width - (strlen(cal_t[i]) / cw)) / 2; } for (i=0; in; i++) { for (k=0; k 1) ? 1 : 0))); k++) { printf(" "); } if (i != m->n-1) { for (k=0; kmargin; k++) { printf(" "); } } } printf("\n"); for (i=0; in; i++) { for (k=0; k<6; k++) { printf("%s%s%s ", TERM_WHITE, ptr_d[k], TERM_RESET); } if (l->color) printf("%s%s%s", TERM_RED, ptr_d[6], TERM_RESET); else printf("%s%s%s", TERM_WHITE, ptr_d[6], TERM_RESET); if (i != m->n-1) { for (k=0; kmargin; k++) { printf(" "); } } } printf("\n"); create_cal_matrix(l, m); for (i=0; in; i++) { set_cal_matrix(l, _j[i], m, i); } show_cal_matrix(l, m); destroy_cal_matrix(m); } /* * Displays previous, current and next month's calendar on standard * screen according to a given jalali date. */ void show_3(struct cal_layout* l, struct jtm* j) { struct jtm** _j; struct cal_matrix m; int diff_p; int diff_c; int diff_n; int i; m.n = 3; _j = malloc(m.n * sizeof(struct jtm*)); for (i=0; itm_mday + 1); diff_n = (jalali_is_jleap(_j[1]->tm_year) && _j[1]->tm_mon == 11) ? diff_c + (30 - _j[1]->tm_mday + 1) : diff_c + (jalali_month_len[_j[1]->tm_mon] - _j[1]->tm_mday + 1); jalali_get_date(diff_p, _j[0]); jalali_get_date(diff_n, _j[2]); show_cal(l, &m, _j); for (i=0; i<3; i++) { free(_j[i]); } free(_j); } /* * Displays a calendar on standard screen according to a given jalali date. */ void show_1(struct cal_layout* l, struct jtm* j) { struct jtm** _j; struct cal_matrix m; l->syear = 1; _j = malloc(sizeof(struct jtm*)); _j[0] = malloc(sizeof(struct jtm)); memcpy(_j[0], j, sizeof(struct jtm)); m.n = 1; show_cal(l, &m, _j); free(_j[0]); free(_j); } /* * Displays a whole year calendar on standard screen according * to a given jalali date. */ void show_year(struct cal_layout* l, struct jtm* j) { struct jtm _j[4]; char title[100]; char buf[100]; int cal_width = (((l->julian) ? (3 * 7 + 6) : (2 * 7 + 6)) * 3) + (2 * l->margin); int cal_tw; int i; if (l->farsi) { jalali_to_farsi(buf, 100, 0, " ", j->tm_year + ((l->pahlavi) ? PAHLAVI_ISLAMIC_DIFF : 0)); } else { snprintf(buf, 100, "%d", j->tm_year + ((l->pahlavi) ? PAHLAVI_ISLAMIC_DIFF : 0)); } snprintf(title, 100, "%s%s", buf, (l->pahlavi) ? (l->farsi ? " پهلوی" : " (Pahlavi)") : ""); cal_tw = (cal_width - strlen(title)) / 2; for (i=0; isyear = 0; _j[0].tm_year = j->tm_year; _j[0].tm_mon = 1; _j[0].tm_mday = 1; jalali_update(&_j[0]); _j[1].tm_year = j->tm_year; _j[1].tm_mon = 4; _j[1].tm_mday = 1; jalali_update(&_j[1]); _j[2].tm_year = j->tm_year; _j[2].tm_mon = 7; _j[2].tm_mday = 1; jalali_update(&_j[2]); _j[3].tm_year = j->tm_year; _j[3].tm_mon = 10; _j[3].tm_mday = 1; jalali_update(&_j[3]); show_3(l, &_j[0]); show_3(l, &_j[1]); show_3(l, &_j[2]); show_3(l, &_j[3]); } int main(int argc, char** argv) { struct cal_layout l; struct jtm j; time_t t; int opt; int i, c = 0; int def_date[3]; void (*show) (struct cal_layout*, struct jtm*); show = &show_1; time(&t); jlocaltime_r(&t, &j); /* Default values for display date */ def_date[0] = 1; def_date[1] = 1; def_date[2] = j.tm_year; l.color = 1; l.pahlavi = 0; l.farsi = 0; l.julian = 0; l.english = 0; l.margin = 3; /* Parsing date values. (YYYY MM DD) */ for (i=1; i 0) { def_date[2 - c] = opt; c++; } } if (c > 0) { if (c == 1) show = &show_year; else show = &show_1; if (def_date[0] > 31 || def_date[0] < 1) { printf("%s: illegal day value: use 1-31\n", argv[0]); exit(EXIT_FAILURE); } if (def_date[1] > 12 || def_date[1] < 1) { printf("%s: illegal month value: use 1-12\n", argv[0]); exit(EXIT_FAILURE); } j.tm_year = def_date[2]; j.tm_mon = def_date[1] - 1; j.tm_mday = def_date[0]; jalali_update(&j); } /* Parsing short options. */ while ((opt = getopt(argc, argv, JCAL_VALID_ARGS)) != -1) { switch (opt) { /* Using Pahlavi instead of Islamic Epoch. */ case 'P': l.pahlavi = 1; break; case 'p': l.farsi = 1; l.english = 0; break; /* Displays Julian days (Day of year) instead of day of month. */ case 'j': l.julian = 1; break; /* Displays English names of weekdays. */ case 'e': l.english = 1; break; /* Display one-month calendar for a given date. */ case '1': show = &show_1; break; /* * Display previous, current and next month's calendar * for the given date. */ case '3': l.syear = 1; show = &show_3; break; /* Whole-year calendar for a given date. */ case 'y': show = &show_year; break; /* No-color. */ case 'N': l.color = 0; break; /* Version information. */ case 'V': printf("jcal version %s (libjalali-%s)\n", JCAL_VERSION, LIBJALALI_VERSION); printf("Written by Ashkan Ghassemi.\n"); exit(EXIT_SUCCESS); break; /* Unknown parameter. */ default: printf("usage: jcal [-13jypPV] [year [month[day]]]\n"); exit(EXIT_FAILURE); } } show(&l, &j); exit(EXIT_SUCCESS); } src/Makefile.am0000644000175000001440000000050111572037204013062 0ustar ashkanusersbin_PROGRAMS = jcal jdate INCLUDES = -I. -I.. -I../libjalali -I@includedir@ AM_CFLAGS = @CFLAGS@ -fno-inline -D_REENTRANT -Wall\ -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE jcal_SOURCES = jcal.c jdate_SOURCES = jdate.c LDADD = ../libjalali/libjalali.la -L@libdir@ LIBS = @LIBS@ $(THREAD_LIBS) src/jcal.h0000644000175000001440000000426411625552737012136 0ustar ashkanusers/* * jcal.h - Unix cal-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ #ifndef JCAL_H #define JCAL_H #include "../libjalali/jalali.h" #include "../libjalali/jtime.h" #define JCAL_VALID_ARGS "13jyVNePp" #define PAHLAVI_ISLAMIC_DIFF 1180 #define JCAL_VERSION "0.4.1" struct cal_layout { int color; /* If enabled, drawer tries to colorize output. */ int julian; /* Displays julian days (1-366) instead of month days. */ int pahlavi; /* jcal uses Pahlavi instead of Islamic epoch. */ int english; /* Use Farsi transliteration for weekday names. */ int farsi; /* Use Farsi utf8 names and numbers. */ int margin; /* Marginal space between two cals. */ int syear; /* If enabled, jcal shows year above cals. */ }; struct cal_matrix { int n; /* Calendar numbers within matrix. */ int** m; /* Calendar matrix. */ int width; /* Matrix width. */ int height; /* Matrix height. */ }; void set_cal_matrix(struct cal_layout* l, struct jtm* ct, struct cal_matrix* mat, int prefix); int is_in_margin(struct cal_layout* l, struct cal_matrix* mat, int c); void show_cal_matrix(struct cal_layout* l, struct cal_matrix* mat); void create_cal_matrix(struct cal_layout* l, struct cal_matrix* mat); void destroy_cal_matrix(struct cal_matrix* mat); void show_cal(struct cal_layout* l, struct cal_matrix* m, struct jtm** _j); void show_3(struct cal_layout* l, struct jtm* j); void show_1(struct cal_layout* l, struct jtm* j); void show_year(struct cal_layout* l, struct jtm* j); #endif /* JCAL_H */ src/jdate.h0000644000175000001440000001153311625552726012307 0ustar ashkanusers/* * jdate.h - Unix date-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ #ifndef JDATE_H #define JDATE_H #define JDATE_VERSION "0.4.1" /* short options */ #define JDATE_VALID_ARGS "a:r:d:j:g:RuhV" /* long options */ #define DATE_OPT "date" #define REF_OPT "reference" #define ACC_OPT "access" #define JALALI_OPT "jalali" #define GREGORIAN_OPT "gregorian" #define RFC2822_OPT "rfc-2822" #define UTC_OPT "utc" #define UNIVERSAL_OPT "universal" #define HELP_OPT "help" #define VERSION_OPT "version" /* help string */ #define HELP_STR "Usage: jdate [arRuhV]... [+OUTPUT_FORMAT]\ [d INPUT_FORMAT;DATE_STRING]\n\ Display the current date and time in the given FORMAT.\n\ \n\ -d, --date=FORMAT;STRING\tdisplay time described by STRING, not `now'\n\ -a, --access=FILE\t\tdisplay the last access time of FILE.\n\ -r, --reference=FILE\t\tdisplay the last modification time of FILE.\n\ \n\ -j, --jalali=%Y/%m/%d\t\tconverts a gregorian date to jalali.\n\ -g, --gregorian=%Y/%m/%d\tconverts a jalali date to gregorian.\n\ \n\ -R, --rfc-2822\t\toutput date and time in RFC 2822 format.\n\ \t\t\t\tExample: Jom, 06 Khor 1390 13:44:56 -0430.\n\ -u, --utc, --universal\tprint Coordinated Universal Time.\n\ -h, --help\t\t\tdisplay this help and exit.\n\ -V, --version\t\t\toutput version information and exit.\n\ \n\ FORMAT controls the output. Interpreted sequences are:\n\ \n\ %% a literal %\n\ %a abbreviated weekday name (e.g., Sun)\n\ %A full weekday name (e.g., Sunday)\n\ %b abbreviated month name (e.g., Khor)\n\ %B full month name (e.g., Khordad)\n\ %c date and time (e.g., Jome Kho 6 17:18:25 1390)\n\ %C century; like %Y, except omit last two digits (e.g., 13)\n\ %d day of month (e.g., 01)\n\ %D date; same as %Y/%m/%d\n\ %e day of month, space padded; same as %d\n\ %E date and time in Farsi (utf8)\n\ %F full date; same as %Y-%m-%d\n\ %h abbreviated weekday name in Farsi transliteration (e.g. Jom)\n\ %g abbreviated Farsi weekday name (utf8)\n\ %G full Farsi weekday name (utf8)\n\ %v abbreviated Farsi month name (utf8)\n\ %V full Farsi month name (utf8)\n\ %H hour (00..23)\n\ %I hour (01..12)\n\ %j day of year (001..366)\n\ %k hour (0..23)\n\ %l hour (1..12)\n\ %m month (01..12)\n\ %M minute (00..59)\n\ %n a newline\n\ %O AM or PM notation for time in Farsi (utf8)\n\ %p either AM or PM; blank if not known\n\ %P like %p, but lower case\n\ %r 12-hour clock time (e.g., 17:24:04 PM)\n\ %R 24-hour hour and minute; same as %H:%M\n\ %s seconds since 1970-01-01 00:00:00 UTC\n\ %S second (00..59)\n\ %t a tab\n\ %T time; same as %H:%M:%S\n\ %u day of week (1..7); 1 is Saturday\n\ %U week number of year, with Saturday as first day of week (00..53)\n\ %w day of week (0..6); 0 is Saturday\n\ %W date representation in Farsi (utf8)\n\ %x date representation (e.g., 06/03/90)\n\ %X time representation in Farsi (utf8)\n\ %y last two digits of year (00..99)\n\ %Y year\n\ %z +hhmm numeric time zone (e.g., +0330)\n\ %Z alphabetic time zone abbreviation (e.g., IRST)\n\ \n\ Report jdate bugs to ghassemi@ftml.net\n\ libjalali home page: " /* *@action_handler */ struct jdate_action { int normal; /* standard representation: %h %b %m %H:%M:%S %Z %Y */ int reference; /* last modification time */ char* reference_ptr; /* last modification time argument */ int access; /* last access */ char* access_ptr; /* last access argument */ int date; /* use date string instead of 'now' */ char* date_ptr; /* date string argument */ int jalali; /* convert a gregorian date to jalali */ char* jalali_ptr; /* jalali conversion argument */ int gregorian; /* convert a jalali date to gregorian */ char* gregorian_ptr; /* gregorian conversion argument */ int format; /* +FORMAT. uses jstrftime() to format output */ char* format_ptr; /* +FORMAT argument */ int rfc2822; /* rfc2822 date and time: %h, %m %b %Y %H:%M:%S %z */ int utc; /* Coordinated Universal Time */ int help; /* help */ int version; /* version */ }; #endif /* JDATE_H */ src/termcap.h0000644000175000001440000000343711571254276012656 0ustar ashkanusers/* * termcap.h - Unix cal-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ #ifndef TERMCAP_H #define TERMCAP_H #define CURSOR_UP "\033[%dA" #define CURSOR_DOWN "\033[%dB" #define CURSOR_RIGHT "\033[%dC" #define CURSOR_LEFT "\033[%dD" #define CURSOR_C "\033b\033[%dC" #if !defined NO_COLOR /* Foreground colors on black. */ #define TERM_BLACK "\033[30m" #define TERM_RED "\033[31m" #define TERM_GREEN "\033[32m" #define TERM_YELLOW "\033[33m" #define TERM_BLUE "\033[34m" #define TERM_MAGENTA "\033[35m" #define TERM_CYAN "\033[36m" #define TERM_WHITE "\033[37m" /* Mixed sets. */ #define TERM_WHITE_ON_RED "\033[41;37m" #define TERM_BLACK_ON_WHITE "\033[30;47m" #define TERM_RED_ON_WHITE "\033[31;47m" /* Attribute reset.*/ #define TERM_RESET "\033[0m" #else /* NO_COLORS*/ #define TERM_BLACK "" #define TERM_RED "" #define TERM_GREEN "" #define TERM_YELLOW "" #define TERM_BLUE "" #define TERM_MAGENTA "" #define TERM_CYAN "" #define TERM_WHITE "" #define TERM_WHITE_ON_RED "" #define TERM_BLACK_ON_WHITE "" #define TERM_RED_ON_WHITE "" #define TERM_RESET "" #endif /* !NO_COLOR */ #endif /* TERMCAP_H */ src/jdate.c0000644000175000001440000001507611575744460012312 0ustar ashkanusers/* * jdate.c - Unix date-like interface to libjalali. * Copyright (C) 2006, 2007, 2009, 2010, 2011 Ashkan Ghassemi. * * This file is part of jcal. * * jcal 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 3 of the License, or * (at your option) any later version. * * jcal 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 should have received a copy of the GNU General Public License * along with jcal. If not, see . */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #include #include #include #include #include #include #include #include "../libjalali/jalali.h" #include "../libjalali/jtime.h" #include "jdate.h" extern char* optarg; /* * Unix timestamp of last modification/access time for a file. * Returns 0 on success, -1 on errors. * Based on a given action, it returns the following values: * for 'a' equal zero: st_mtime (last modification time) * otherwise: st_atime (last access time) */ int mod_time(const char* path, time_t* t, int a) { struct stat st; int err; err = stat(path, &st); if (err == -1) return err; *t = (a == 0) ? st.st_mtime : st.st_atime; return 0; } int main(int argc, char** argv) { int opt; int i; int err; int option_index; char buf[MAX_BUF_SIZE]; char date_format[MAX_BUF_SIZE]; char date_string[MAX_BUF_SIZE]; struct jtm j; struct tm g; struct jdate_action action = {0}; /* Long options, see 'jdate.h' for complete list. */ struct option long_options[] = { {DATE_OPT, 1, 0, 'd'}, {REF_OPT, 1, 0, 'r'}, {ACC_OPT, 1, 0, 'a'}, {RFC2822_OPT, 0, 0, 'R'}, {UTC_OPT, 0, 0, 'u'}, {JALALI_OPT, 1, 0, 'j'}, {GREGORIAN_OPT, 1, 0, 'g'}, {UNIVERSAL_OPT, 0, 0, 'u'}, {HELP_OPT, 0, 0, 'h'}, {VERSION_OPT, 0, 0, 'V'}, {0, 0, 0, 0} }; action.normal = 1; time_t t; time(&t); jlocaltime_r(&t, &j); while ((opt = getopt_long(argc, argv, JDATE_VALID_ARGS, long_options, &option_index)) != -1) { switch (opt) { /* last access time. */ case 'a': action.access = 1; action.access_ptr = optarg; break; /* last modification time. */ case 'r': action.reference = 1; action.reference_ptr = optarg; break; /* display time described by FORMAT and DATE_STRING, not `now'. */ case 'd': action.date = 1; action.date_ptr = optarg; break; /* convert a jalali date to gregorian. */ case 'g': action.gregorian = 1; action.gregorian_ptr = optarg; break; /* convert a gregorian date to jalali. */ case 'j': action.jalali = 1; action.jalali_ptr = optarg; break; /* * output date and time in RFC 2822 format. * %h, %m %b %Y %H:%M:%S %z */ case 'R': action.normal = 0; action.format = 0; action.rfc2822 = 1; break; /* print Coordinated Universal Time */ case 'u': action.utc = 1; break; /* help */ case 'h': action.help = 1; action.normal = 0; action.format = 0; action.rfc2822 = 0; break; /* version */ case 'V': action.version = 1; action.help = 0; action.normal = 0; action.format = 0; action.rfc2822 = 0; break; default: fprintf(stderr, "jdate: usage [OPTION]... [+FORMAT]\n"); exit(EXIT_FAILURE); } } /* * Format string handler. INPUT_FORMAT and DATE_STRING * are separated using a semicolon. ';' * e.g. "%Y/%m/%d %H:%M:%S;1390/03/06 18:35:41" */ for (i=1; i