Markus, Fabian, and all:
Lots of code in this patch. Now that the Gregorian and Julian
conversions and back-conversions have been proved, this patch will
create a version that computes and outputs both. Specifically, it:
1. Adds another set of day, month, and year parts.
2. Creates separate caches for a Gregorian and a Julian printout value.
3. Loads each set of year-month-day properties according to a calendar
model that is either specified or worked out from the input. By default,
the model to be used to create the Julian Day is the Gregorian, if the
date is October 15, 1582 or later, and otherwise the Julian. But the
user may override this rule by specifying "Gr" or "Jl" in his input. (If
he uses "OS" in English, that means "increment the year if the date
falls between 1 January and 24 March inclusive, and treat the resulting
date as Julian."
4. Performs /both/ back-conversions and stores each result separately.
5. Preserves the imprecision of the input, i.e. a month and a year as
input produces only a month and a year as output in each model.
6. Selects the printout value for the browser as follows: any date
having a JD less than the date of the Gregorian calendar proclamation
will be Julian; otherwise it will be Gregorian.
7. Creates "tooltip captions" that show the Gregorian value, then the
Julian.
At this point I'm open to suggestions as to which outputs would be
preferable. I can now produce whatever output is desired.
Now that I have shown this, I will proceed to implement the two other
calendar models that I mentioned.
The next step after that will probably be the transfer of these
improvements to the current version. Only then will I be in a position
to add the calendar model as another DBkeys element, probably $args[1].
(How many elements is $args permitted to have in the functions
getDBKeys() and parseDBkeys($args)? I had the distinct impression that
in SMW 1.4.2, the answer was two, corresponding to the old arguments
$value and $unit.)
Temlakos
--- ../SemanticMediaWiki-lng/SMW_DV_Time.php 2009-08-11 17:05:23.000000000
-0400
+++ ./SMW_DV_Time.php 2009-08-11 21:09:18.000000000 -0400
@@ -20,12 +20,16 @@
* All dates are supposed to refer either to the Gregorian calendar (October
15, 1582
* or later), or to the Julian calendar (earlier than October 15, 1582
Gregorian). Any
* date specified between October 5 and October 14, 1582 inclusive, will be
recalculated
- * according to the Julian calendar. The "OS" (Old Style) symbol is supported
in English,
- * and dates annotated with this symbol are processed accordingly: the year is
incremented
- * by one if the date falls between 1 January and 24 March inclusive, and the
resultant
- * day is converted according to Julian rules, but the printout is either
Gregorian or
- * Julian according to the epoch. Other calendar-model support is planned.
- * Historical dates are, however, still experimental.
+ * according to the Julian calendar. But users may override the default
calculation by
+ * specifying "Gr" for Gregorian or "Jl" for Julian, as desired.
+ * The "OS" (Old Style) symbol is supported in English, and dates annotated
with this
+ * symbol are processed accordingly: the year is incremented by one if the
date falls
+ * between 1 January and 24 March inclusive, and the resultant day is converted
+ * according to Julian rules, but the printout is either Gregorian or
+ * Julian according to the epoch.
+ *
+ * Other calendar-model support is planned. Historical dates are, however,
+ * still experimental.
*
* This type can handle dates across history with full precision for storing,
and
* substantial precision for sorting and querying. The range of supported past
dates
@@ -77,7 +81,8 @@
protected $m_wikivalue; // a suitable wiki input value
protected $m_xsdvalue = false; // cache for XSD value
- protected $m_printvalue = false; // cache for printout value
+ protected $m_gregvalue = false; // cache for (proleptic) Gregorian value
+ protected $m_julvalue = false; // cache for (proleptic) Julian value
protected $m_pref = false; // holds a symbol for the calendar model
protected $m_day = false; //Gregorian day, remains false if unspecified
protected $m_month = false; //Gregorian month, remains false if
unspecified
@@ -87,6 +92,9 @@
protected $m_format = false; // number of parts of the date that were
specified
protected $m_timeoffset; //contains offset (e.g. timezone)
protected $m_timeannotation; //contains am or pm
+ protected $m_dayj = false; // Julian day, remains false if unspecified
+ protected $m_monthj = false; // Julian month, remains false if
unspecified
+ protected $m_yearj = false; // Julian year, remains false if unspecified
// The following are constant (array-valued constants are not
supported, hence the decalration as variable):
protected $m_months = array("January", "February", "March", "April" ,
"May" , "June" , "July" , "August" , "September" , "October" , "November" ,
"December");
protected $m_monthsshort = array("Jan", "Feb", "Mar", "Apr", "May",
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
@@ -124,6 +132,9 @@
$this->m_timeoffset = 0;
$this->m_timeannotation = false;
$this->m_format = false;
+ $this->m_dayj = false;
+ $this->m_monthj = false;
+ $this->m_yearj = false;
$value = trim($value); // ignore whitespace
$this->m_wikivalue = $value;
@@ -232,11 +243,15 @@
$digitcount = count($array)-1; //number of digits - 1 is used
as an array index for $dateformats
$found = false;
+ $prelimModel = $this->findPrelimModel();
foreach ($dateformats[$digitcount] as $format) { //check
whether created band matches dateformats
if (!(~$band & $format)) { //check if $format => $band
("the detected band supports the current format")
$i = 0;
foreach ($this->m_formats[$format] as
$globalvar) { // map format digits to internal variables
$globalvar = 'm_'.$globalvar; // (for
searching this file) this is one of: m_year, m_month, m_day
+ if($prelimModel == 'Jl') {
+ $globalvar = $globalvar . 'j';
+ }
if (!$this->$globalvar)
$this->$globalvar = intval($array[$i]);
$i++;
}
@@ -254,7 +269,11 @@
wfLoadExtensionMessages('SemanticMediaWiki');
$this->addError(wfMsgForContent('smw_nodatetime',$value));
return true;
- } elseif ( ($this->m_year < -4713) && ($this->m_timeoffset !=
0) ) { //no support for time offsets if year < -4713
+ } elseif ( ($this->m_dayj > 0) && ($this->m_dayj >
$this->m_daysofmonths[$this->m_monthj]) ) { //date does not exist in Julian
calendar
+ wfLoadExtensionMessages('SemanticMediaWiki');
+
$this->addError(wfMsgForContent('smw_nodatetime',$value));
+ return true;
+ } elseif ( ($this->m_year == false) && ($this->m_yearj < -4713)
&& ($this->m_timeoffset != 0) ) { //no support for time offsets if year < -4713
wfLoadExtensionMessages('SemanticMediaWiki');
$this->addError(wfMsgForContent('smw_nodatetime',$value));
return true;
@@ -262,15 +281,15 @@
// Handle OS: Increment the year if earlier than March 25.
if ($this->m_pref == 'OS') {
- if(($this->m_month < 3) || (($this->m_month == 3) &&
($this->m_day < 25))) {
- $this->m_year++;
+ if(($this->m_monthj < 3) || (($this->m_monthj == 3) &&
($this->m_dayj < 25))) {
+ $this->m_yearj++;
}
}
// Handle BC: the year is negative.
if ($is_yearbc) {
- if ($this->m_year > 0) { // see class documentation on
BC, "year 0", and ISO conformance ...
- $this->m_year = -($this->m_year);
+ if ($this->m_yearj > 0) { // see class documentation on
BC, "year 0", and ISO conformance ...
+ $this->m_yearj = -($this->m_yearj);
}
}
@@ -279,7 +298,11 @@
if ($this->m_jd > -0.5) {
$this->m_jd = $this->m_jd - $this->m_timeoffset;
$this->JD2Date();
- }
+ } else {
+ $this->m_day = $this->m_dayj;
+ $this->m_month = $this->m_monthj;
+ $this->m_year = $this->m_yearj;
+ } // Copy Julian registers into Gregorian registers; needed for
the XSD value
if ($this->m_caption === false) {
$this->m_caption = $value;
@@ -287,26 +310,49 @@
return true;
}
- protected function checkDigit($digit){
+ protected function findMonth($label) {
global $smwgContLang;
+ $retVal = $smwgContLang->findMonth($label);
+ if ( $retVal !== false ) {
+ return $retVal;
+ }
+ $retVal = array_search($label, $this->m_months);
+ if ( $retVal !== false ) {
+ return $retVal + 1;
+ }
+ $retVal = array_search($label, $this->m_monthsshort);
+ if ( $retVal !== false ) {
+ return $retVal + 1;
+ }
+ return false;
+ }
+
+ protected function findPrelimModel() {
+ if(($this->m_pref == 'BC') || ($this->m_pref == 'Jl') ||
($this->m_pref == 'OS')) {
+ return 'Jl'; // Assume Julian model if specified in any
way, shape or form.
+ }
+ return 'Gr';
+ }
+
+ protected function checkDigit($digit){
if(!is_numeric($digit)){ //check for alphanumeric day or month
value
+ $prelimModel = $this->findPrelimModel();
if(preg_match("/[0-3]?[0-9](st|nd|rd|th)/u", $digit)) {
//look for day value terminated by st/nd/th
- $this->m_day =
intval(substr($digit,0,strlen($digit)-2)); //remove st/nd/th
+ $dayVal =
intval(substr($digit,0,strlen($digit)-2)); //remove st/nd/th
+ if($prelimModel == 'Jl') {
+ $this->m_dayj = $dayVal;
+ } else {
+ $this->m_day = $dayVal;
+ }
return SMW_DAY;
}
- $monthnumber = $smwgContLang->findMonth($digit);
- if ( $monthnumber !== false ) {
- $this->m_month = $monthnumber;
- return SMW_MONTH;
- }
- $monthnumber = array_search($digit, $this->m_months);
- if ( $monthnumber !== false ) {
- $this->m_month = $monthnumber + 1;
- return SMW_MONTH;
- }
- $monthnumber = array_search($digit,
$this->m_monthsshort);
+ $monthnumber = $this->findMonth($digit);
if ( $monthnumber !== false ) {
- $this->m_month = $monthnumber + 1;
+ if($prelimModel == 'Jl') {
+ $this->m_monthj = $monthnumber;
+ } else {
+ $this->m_month = $monthnumber;
+ }
return SMW_MONTH;
}
return 0;
@@ -323,6 +369,9 @@
// finds the appropriate model to use.
protected function findModel() {
+ if ($this->m_pref == 'BC') {
+ return 'Jl'; // BC dates are automatically Julian.
+ }
if ($this->m_pref == 'OS') {
$this->m_pref = ''; // Erase the OS marker; it will not
be needed after this.
return 'Jl'; // Old Style dates are converted per
Julian rules.
@@ -339,7 +388,10 @@
}
if (($this->m_year == 1582) && ($this->m_month == 10) &&
($this->m_day > 4)) {
return 'Gr';
- } // Set $model to 'Jl'
+ } // Set $model to 'Jl' and move all specified date parts to
the Julian set.
+ $this->m_dayj = $this->m_day;
+ $this->m_monthj = $this->m_month;
+ $this->m_yearj = $this->m_year;
return 'Jl';
}
@@ -349,17 +401,33 @@
if (count($d)==3)
list($this->m_year,$this->m_month,$this->m_day) = $d;
elseif (count($d)==2) list($this->m_year,$this->m_month) = $d;
elseif (count($d)==1) list($this->m_year) = $d;
- $this->createJD($this->findModel());
+ if($this->m_year < -4713) {
+ $this->m_yearj = $this->m_year;
+ $this->m_monthj = $this->m_month;
+ $this->m_dayj = $this->m_day;
+ $this->createJD('Jl'); // This date falls earlier than
the Julian Era.
+ } else {
+ $this->createJD('Gr'); // This is a Gregorian or
proleptic Gregorian date
+ }
if($this->m_jd > -0.5) {//Back-convert only if the JD is
suitable for that
$this->JD2Date();
}
$this->makePrintoutValue();
- $this->m_caption = $this->m_printvalue;
- $this->m_wikivalue = $this->m_printvalue;
+ $this->m_caption = ($this->m_jd < self::J1582) ?
$this->m_julvalue : $this->gregvalue;
+ $this->m_wikivalue = ($this->m_jd < self::J1582) ?
$this->m_julvalue : $this->gregvalue;
}
public function getShortWikiText($linked = NULL) {
- return $this->m_caption;
+ if ($this->isValid() && ($linked !== NULL) && ($linked !==
false)) {
+ $this->makeGregorianValue();
+ $this->makeJulianValue();
+ SMWOutputs::requireHeadItem(SMW_HEADER_TOOLTIP);
+ return '<span class="smwttinline">' . $this->m_caption
. '<span class="smwttcontent">' .
+ $this->m_gregvalue . ' <br />' .
+ $this->m_julvalue . '</span></span>';
+ } else {
+ return $this->m_caption;
+ }
}
public function getShortHTMLText($linker = NULL) {
@@ -371,7 +439,7 @@
return $this->getErrorText();
} else {
$this->makePrintoutValue();
- return $this->m_printvalue;
+ return ($this->m_jd < self::J1582) ? $this->m_julvalue
: $this->m_gregvalue;
}
}
@@ -419,8 +487,13 @@
* Return the year as a number corresponding to the year in the Julian
or
* Gregorian calendar and using the astronomical year numbering (0
means 1 BC).
*/
- public function getYear() {
- return $this->m_year;
+ public function getYear($model = 'Gr') {
+ switch ($model) {
+ case 'Jl':
+ return $this->m_yearj;
+ default:
+ return $this->m_year;
+ }
}
/**
@@ -430,8 +503,13 @@
* if the date is valid but has no explicitly specified month. It can
* also be set to FALSE to detect this situation.
*/
- public function getMonth($default = 1) {
- return ($this->m_month != false)?$this->m_month:$default;
+ public function getMonth($model = 'Gr', $default = 1) {
+ switch ($model) {
+ case 'Jl':
+ return ($this->m_monthj !=
false)?$this->m_monthj:$default;
+ default:
+ return ($this->m_month !=
false)?$this->m_month:$default;
+ }
}
/**
@@ -440,8 +518,13 @@
* if the date is valid but has no explicitly specified date. It can
* also be set to FALSE to detect this situation.
*/
- public function getDay($default = 1) {
- return ($this->m_day != false)?$this->m_day:$default;
+ public function getDay($model = 'Gr', $default = 1) {
+ switch ($model) {
+ case 'Jl':
+ return ($this->m_dayj !=
false)?$this->m_dayj:$default;
+ default:
+ return ($this->m_day !=
false)?$this->m_day:$default;
+ }
}
/**
@@ -482,26 +565,52 @@
}
/**
- * Build a preferred value for printout, also used as a caption when
setting up values
+ * Build preferred values for printout, to be used as captions when
setting up values
* from the store.
*/
protected function makePrintoutValue() {
+ $this->makeGregorianValue();
+ $this->makeJulianValue();
+ }
+
+ protected function makeGregorianValue() {
global $smwgContLang;
- if ($this->m_printvalue === false) {
+ if ($this->m_gregvalue === false) {
//MediaWiki date function is not applicable any more
(no support for BC Dates)
if ($this->m_year > 0) {
- $this->m_printvalue =
number_format($this->m_year, 0, '.', ''); // note: there should be no digits
after the comma anyway
+ $this->m_gregvalue =
number_format($this->m_year, 0, '.', ''); // note: there should be no digits
after the comma anyway
} else {
- $this->m_printvalue =
number_format(-($this->m_year), 0, '.', '') . ' BC'; // note: there should be
no digits after the comma anyway
+ $this->m_gregvalue =
number_format(-($this->m_year), 0, '.', '') . ' BC'; // note: there should be
no digits after the comma anyway
}
if ($this->m_month) {
- $this->m_printvalue =
$smwgContLang->getMonthLabel($this->m_month) . " " . $this->m_printvalue;
+ $this->m_gregvalue =
$smwgContLang->getMonthLabel($this->m_month) . " " . $this->m_gregvalue;
}
if ($this->m_day) {
- $this->m_printvalue = $this->m_day . " " .
$this->m_printvalue;
+ $this->m_gregvalue = $this->m_day . " " .
$this->m_gregvalue;
+ }
+ if ($this->m_time) {
+ $this->m_gregvalue .= " " . $this->m_time;
+ }
+ }
+ }
+
+ protected function makeJulianValue() {
+ global $smwgContLang;
+ if ($this->m_julvalue === false) {
+ //MediaWiki date function is not applicable any more
(no support for BC Dates)
+ if ($this->m_yearj > 0) {
+ $this->m_julvalue =
number_format($this->m_yearj, 0, '.', ''); // note: there should be no digits
after the comma anyway
+ } else {
+ $this->m_julvalue =
number_format(-($this->m_yearj), 0, '.', '') . ' BC'; // note: there should be
no digits after the comma anyway
+ }
+ if ($this->m_monthj) {
+ $this->m_julvalue =
$smwgContLang->getMonthLabel($this->m_monthj) . " " . $this->m_julvalue;
+ }
+ if ($this->m_dayj) {
+ $this->m_julvalue = $this->m_dayj . " " .
$this->m_julvalue;
}
if ($this->m_time) {
- $this->m_printvalue .= " " . $this->m_time;
+ $this->m_julvalue .= " " . $this->m_time;
}
}
}
@@ -562,27 +671,27 @@
/// Calculate a Julian day according to Gregorian calendar rules
protected function gregorian2JD(){
$this->m_jd = 0;
- $a = intval((14-$this->getMonth())/12);
+ $a = intval((14-$this->getMonth('Gr'))/12);
$y = $this->m_year + 4800 - $a;
- $m = $this->getMonth() + 12 * $a - 3;
- $this->m_jd += $this->getDay() + intval((153*$m+2)/5) + 365*$y
+ intval($y/4) - intval($y/100) + intval($y/400) - 32045.5;
+ $m = $this->getMonth('Gr') + 12 * $a - 3;
+ $this->m_jd += $this->getDay('Gr') + intval((153*$m+2)/5) +
365*$y + intval($y/4) - intval($y/100) + intval($y/400) - 32045.5;
$this->m_format = ($this->m_day != false) ? 3 :
(($this->m_month != false) ? 2 : 1);
}
/// Calculate a Julian day according to Julian calendar rules
protected function julian2JD(){
- if ($this->m_year >= -4713) {
+ if ($this->m_yearj >= -4713) {
$this->m_jd = 0;
- $y1 = ($this->m_year < 1) ? ($this->m_year + 1) :
$this->m_year;
- $m1 = $this->getMonth();
+ $y1 = ($this->m_yearj < 1) ? ($this->m_yearj + 1) :
$this->m_yearj;
+ $m1 = $this->getMonth('Jl');
$y2 = ($m1 <= 2) ? ($y1 - 1) : $y1;
$m2 = ($m1 <= 2) ? ($m1 + 12) : $m1;
- $this->m_jd += intval((365.25 * ($y2 + 4716))) +
intval((30.6001 * ($m2+1))) + $this->getDay() - 1524.5;
+ $this->m_jd += intval((365.25 * ($y2 + 4716))) +
intval((30.6001 * ($m2+1))) + $this->getDay('Jl') - 1524.5;
} else { // starting from the time when JD would be negative,
use our own "stretched" representation, currently this just ignores local time
- $time = 1 - (($this->getMonth() / 12) +
($this->getDay() / 365));
- $this->m_jd = $this->m_year - $time;
+ $time = 1 - (($this->getMonth('Jl') / 12) +
($this->getDay('Jl') / 365));
+ $this->m_jd = $this->m_yearj - $time;
}
- $this->m_format = ($this->m_day != false) ? 3 :
(($this->m_month != false) ? 2 : 1);
+ $this->m_format = ($this->m_dayj != false) ? 3 :
(($this->m_monthj != false) ? 2 : 1);
}
/// Convert the Julian Day fraction to the time string.
@@ -599,11 +708,8 @@
/// Convert Julian Day to m_year, m_month, and m_day according to the
proper model.
protected function JD2Date() {
- if($this->m_jd < self::J1582) {
- $this->JD2Julian();
- } else {
- $this->JD2Gregorian();
- }
+ $this->JD2Julian();
+ $this->JD2Gregorian();
if($this->m_time != false) { // Do not fill this in if it was
not filled in to begin with
$this->fracToTime();
}
@@ -636,9 +742,9 @@
$e = intval(($b - $d)/30.6001);
$m = intval(($e < 14) ? ($e - 1) : ($e - 13));
$y = intval(($m > 2) ? ($c - 4716) : ($c - 4715));
- $this->m_year = ($y < 1) ? ($y - 1) : $y;
- $this->m_month = ($this->m_format >= 2) ? $m : false;
- $this->m_day = ($this->m_format == 3) ? ($b - $d -
intval(30.6001 * $e)) : false;
+ $this->m_yearj = ($y < 1) ? ($y - 1) : $y;
+ $this->m_monthj = ($this->m_format >= 2) ? $m : false;
+ $this->m_dayj = ($this->m_format == 3) ? ($b - $d -
intval(30.6001 * $e)) : false;
}
}
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Semediawiki-devel mailing list
Semediawiki-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/semediawiki-devel