Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Convert(3)	      User Contributed Perl Documentation	    Convert(3)

       Date::Convert - Convert Between any two Calendrical Formats

	       use Date::DateCalc;

	       $date=new Date::Convert::Gregorian(1997,	11, 27);
	       convert Date::Convert::Hebrew $date;
	       print $date->date_string, "\n";

       Currently defined subclasses:


       Date::Convert is	intended to allow you to convert back and forth
       between any arbitrary date formats (ie. pick any	from: Gregorian,
       Julian, Hebrew, Absolute, and any others	that get added on).  It	does
       this by having a	separate subclass for each format, and requiring each
       class to	provide	standardized methods for converting to and from	the
       date format of the base class.  In this way, instead of having to code
       a conversion routine for	going between and two arbitrary	formats	foo
       and bar,	the function only needs	to convert foo to the base class and
       the base	class to bar.  Ie:

	       Gregorian <--> Base class <--> Hebrew

       The base	class includes a Convert method	to do this transparently.

       Nothing is exported because it wouldn't make any	sense to export.  :)

       Fucntion	can be split into several categories:

       o   Universal functions available for all subclasses (ie. all formats).
	   The fundamental conversion routines fit this	category.

       o   Functions that are useful but don't necessarily make	sense for all
	   subclasses.	The overwhelming majority of functions fall into this
	   category.  Even such	seemingly universal concepts as	year, for
	   instance, don't apply to all	date formats.

       o   Private functions that are required of all subclasses, ie.
	   initialize.	These should not be called by users.

       Here's the breakdown by category:

   Functions Defined for all Subclasses
       new Create a new	object in the specified	format with the	specified
	   start paramaters, ie. "$date	= new Date::Convert::Gregorian(1974,
	   11, 27)".  The start	parameters vary	with the subclass.  My
	   personal preference is to order in decreasing order of generality
	   (ie.	year first, then month,	then day, or year then week, etc.)

	   This	can have a default date, which should probably be "today".

	   Extract the date in a format	appropriate for	the subclass.
	   Preferably this should match	the format used	with new, so

		   (new	date::Convert::SomeClass(@a))->date;

	   should be an	identity function on @a	if @a was in a legitmate

	   Return the date in a	pretty format.

	   Change the date to a	new format.

   Non-universal functions
	   Return just the year	element	of date.

	   Just	like year.

       day Just	like year and month.

	   Boolean.  Note that (for ::Hebrew and ::Gregorian, at least!) this
	   can be also be used as a static.  That is, you can either say
		$date->is_leap or      is_leap Date::Convert::Hebrew 5757

   Private functions that are required of all subclasses
       You shouldn't call these, but if	you want to add	a class, you'll	need
       to write	them!  Or it, since at the moment, there's only	one.

	   Read	in args	and initialize object based on their values.  If there
	   are no args,	initialize with	the base class's initialize (which
	   will	initialize in the default way described	above for new.)	 Note
	   the American	spelling of "initialize": "z", not "s".

       The "Absolute" calendar is just the number of days from a certain
       reference point.	 Calendar people should	recognize it as	the "Julian
       Day Number" with	one minor modification:	 When you convert a Gregorian
       day n to	absolute, you get the JDN of the Gregorian day from noon on.

       Since "absolute"	has no notion of years it is an	extremely easy
       calendar	for conversion purposes.  I stole the "absolute" calendar
       format from Reingold's emacs calendar mode, for debugging purposes.

       The subclass is little more than	the base class,	and as the lowest
       common denominator, doesn't have	any special functions.

       The Gregorian calendar is a purely solar	calendar, with a month that is
       only an approximation of	a lunar	month.	It is based on the old Julian
       (Roman) calendar.  This is the calendar that has	been used by most of
       the Western world for the last few centuries.  The time of its adoption
       varies from country to country.	This ::Gregorian allows	you to
       extrapolate back	to 1 A.D., as per the prorgamming tradition, even
       though the calendar definitely was not in use then.

       In addition to the required methods, Gregorian also has year, month,
       day, and	is_leap	methods.  As mentioned above, is_leap can also be used

       This is the traditional Jewish calendar.	 It's based on the solar year,
       on the lunar month, and on a number of additional rules created by
       Rabbis to make life tough on people who calculate calendars.  :)	 If
       you actually wade through the source, you should	note that the seventh
       month really does come before the first month, that's not a bug.

       It comes	with the following additional methods: year, month, day,
       is_leap,	rosh, part_add,	and part_mult.	rosh returns the absolute day
       corresponding to	"Rosh HaShana" (New year) for a	given year, and	can
       also be invoked as a static.  part_add and part_mult are	useful
       functions for Hebrew calendrical	calculations are not for much else; if
       you're not familiar with	the Hebrew calendar, don't worry about them.

       The traditional Muslim calendar,	a purely lunar calendar	with a year
       that is a rough approximation of	a solar	year.  Currently

       The old Roman calendar, allegedly named for Julius Caesar.  Purely
       solar, with a month that	is a rough approximation of the	lunar month.
       Used extensively	in the Western world up	to a few centuries ago,	then
       the West	gradually switched over	to the more accurate Gregorian.	 Now
       used only by the	Eastern	Orthodox Church, AFAIK.

       This section describes how to extend Date::Convert to add your favorite
       date formats.  If you're	not interested,	feel free to skip it.  :)

       There are only three function you have to write to add a	new subclass:
       you need	initialize, date, and date_string.  Of course, helper
       functions would probably	help. .	.  You do not need to write a new or
       convert function, since the base	class handles them nicely.

       First, a	quick conceptual overhaul: the base class uses an "absolute
       day format" (basically "Julian day format") borrowed from emacs.	 This
       is just days numbered absolutely	from an	extremely long time ago.  It's
       really easy to use, particularly	if you have emacs and emacs' calendar
       mode.  Each Date::Convert object	is a reference to a hash (as in	all OO
       perl) and includes a special "absol" value stored under a reserved
       "absol" key.  When initialize initializes an object, say	a Gregorian
       date, it	stores whatever	data it	was given in the object	and it also
       calculates the "absol" equivalent of the	date and stores	it, too.  If
       the user	converts to another date, the object is	wiped clean of all
       data except "absol".  Then when the date	method for the new format is
       called, it calculates the date in the new format	from the "absol" data.

       Now that	I've thoroughly	confused you, here's a more compartmentalized

	   Take	the date supplied as argument as appropriate to	the format,
	   and convert it to "absol" format.  Store it as $$self{'absol'}.
	   You might also want to store	other data, ie.	::Gregorian stores
	   $$self{'year'}, $$self{'month'}, and	$$self{'day'}.	If no args are
	   supplied, explicitly	call the base class's initialize, ie.
	   "Date::Convert::initialize",	to initialize with a default 'absol'
	   date	and nothing else.

	   NOTE:  I may	move the default behavior into the new constructor.

	   Return the date in a	appropriate format.  Note that the only	fact
	   that	date can take as given is that $$self{'absol'} is defined, ie.
	   this	object may not have been initialized by	the initialize of this
	   object's class.  For	instance, you might have it check if
	   $$self{'year'} is defined.  If it is, then you have the year
	   component, otherwise, you calculate year from $$self{'absol'}.

	   This	is the easy part.  Just	call date, then	return a pretty	string
	   based on the	values.

       NOTE: The ::Absolute subclass is	a special case,	since it's nearly an
       empty subclass (ie. it's	just the base class with the required methods
       filled out).  Don't use it as an	example!  The easiest code to follow
       would have been ::Julian	except that Julian inherits from ::Gregorian.
       Maybe I'll reverse that.	. .

	       #!/usr/local/bin/perl5 -w

	       use Date::Convert;

	       $date=new Date::Convert::Gregorian(1974,	11, 27);
	       convert Date::Convert::Hebrew $date;
	       print $date->date_string, "\n";

       My Gregorian birthday is	27 Nov 1974.  The above	prints my Hebrew

	       convert Date::Convert::Gregorian	$date;
	       print $date->date_string, "\n";

       And that	converts it back and prints it in Gregorian.

	       $guy = new Date::Convert::Hebrew	(5756, 7, 8);
	       print $guy->date_string,	" -> ";
	       convert Date::Convert::Gregorian	$guy;
	       print $guy->date_string,	"\n";

       Another day, done in reverse.

	       @a=(5730, 3, 2);
	       @b=(new Date::Convert::Hebrew @a)->date;
	       print "@a\n@b\n";

       The above should	be an identity for any list @a that represents a
       legitimate date.

	       #!/usr/local/bin/perl -an

	       use Date::Convert;

	       $date = new Date::Convert::Gregorian @F;
	       convert Date::Convert::Hebrew $date;
	       print $date->date_string, "\n";

       And that's a quick Greg -> Hebrew conversion program, for those times
       when people ask.

       perl(1),	Date::DateCalc(3)

       Date::Convert 0.15 (pre-alpha)

       Mordechai T. Abzug <>

       The basic idea of using astronomical dates as an	intermediary between
       all calculations	comes from Dershowitz and Reingold.  Reingold's	code
       is the basis of emacs's calendar	mode.  Two papers describing their
       work (which I used to own, but lost!  Darn.) are:

       ``Calendrical Calculations'' by Nachum Dershowitz and Edward M.
       Reingold, Software--Practice and	Experience, Volume 20, Number 9
       (September, 1990), pages	899-928.  ``Calendrical	Calculations, Part II:
       Three Historical	Calendars'' by E. M. Reingold, N. Dershowitz, and S.
       M. Clamen, Software--Practice and Experience, Volume 23,	Number 4
       (April, 1993), pages 383-404.

       They were also scheduled	to come	out with a book	on calendrical
       calculations in Dec. 1996, but as of March 1997,	it still isn't out

       The Hebrew calendrical calculations are largely based on	a cute little
       English book called The Hebrew Calendar (I think. . .)  in a box
       somewhere at my parents'	house.	(I'm organized,	see!)  I'll have to
       dig around next time I'm	there to find it.  If you want to access the
       original	Hebrew sources,	let me give you	some advice: Hilchos Kiddush
       HaChodesh in the	Mishneh	Torah is not the Rambam's most readable
       treatment of the	subject.  He later wrote a little pamphlet called
       "MaAmar HaEibur"	which is both more complete and	easier to comprehend.
       It's included in	"Mich't'vei HaRambam" (or some such; I've got to visit
       that house), which was reprinted	just a few years ago.

       Steffen Beyer's Date::DateCalc showed me	how to use MakeMaker and write
       POD documentation.  Of course, any error	is my fault, not his!

       Copyright 1997 by Mordechai T. Abzug

       You can distribute, modify, and otherwise mangle	Date::Convert under
       the same	terms as perl.

perl v5.32.0			  2000-01-27			    Convert(3)


Want to link to this manual page? Use this URL:

home | help