0

我有多个 JavaScript 函数来计算玛雅星座,我将其转换为单个 PHP 类。一切都很好,除了一些日期。例如,日期06.10.1977使用 PHP 类给我一个 NULL 结果,但等效 JavaScript 函数中的这个日期返回一个正确的值。也许我在 PHP 中出了点问题,有人可以帮我检查一下吗?

JAVASCRIPT:

function leap_gregorian(year) {
    return ((year % 4) == 0) && (!(((year % 100) == 0) && ((year % 400) != 0)));
}

//  GREGORIAN_TO_JD  --  Determine Julian day number from Gregorian calendar date
var GREGORIAN_EPOCH = 1721425.5;

function gregorian_to_jd(year, month, day) {
    return (GREGORIAN_EPOCH - 1) +
           (365 * (year - 1)) +
           Math.floor((year - 1) / 4) +
           (-Math.floor((year - 1) / 100)) +
           Math.floor((year - 1) / 400) +
           Math.floor((((367 * month) - 362) / 12) +
           ((month <= 2) ? 0 : (leap_gregorian(year) ? -1 : -2)) +
           day);
}

var MAYAN_COUNT_EPOCH = 584282.5;
//  JD_TO_MAYAN_COUNT  --  Calculate Mayan long count from Julian day

    function jd_to_mayan_count(jd) {
        var d, baktun, katun, tun, uinal, kin;

        jd = Math.floor(jd) + 0.5;
        d = jd - MAYAN_COUNT_EPOCH;
        baktun = Math.floor(d / 144000);
        d = mod(d, 144000);
        katun = Math.floor(d / 7200);
        d = mod(d, 7200);
        tun = Math.floor(d / 360);
        d = mod(d, 360);
        uinal = Math.floor(d / 20);
        kin = mod(d, 20);

        return new Array(baktun, katun, tun, uinal, kin);
    }

 //  JD_TO_MAYAN_HAAB  --  Determine Mayan Haab "month" and day from Julian day
var MAYAN_HAAB_MONTHS = new Array("Pop", "Uo", "Zip", "Zotz", "Tzec", "Xul",
                                  "Yaxkin", "Mol", "Chen", "Yax", "Zac", "Ceh",
                                  "Mac", "Kankin", "Muan", "Pax", "Kayab", "Cumku", "Uayeb");

function jd_to_mayan_haab(jd) {
    var lcount, day;

    jd = Math.floor(jd) + 0.5;
    lcount = jd - MAYAN_COUNT_EPOCH;
    day = mod(lcount + 8 + ((18 - 1) * 20), 365);

    return new Array(Math.floor(day / 20) + 1, mod(day, 20));
}

//  JD_TO_MAYAN_TZOLKIN  --  Determine Mayan Tzolkin "month" and day from Julian day
var MAYAN_TZOLKIN_MONTHS = new Array("Imix", "Ik", "Akbal", "Kan", "Chicchan",
                                     "Cimi", "Manik", "Lamat", "Muluc", "Oc",
                                     "Chuen", "Eb", "Ben", "Ix", "Men",
                                     "Cib", "Caban", "Etznab", "Cauac", "Ahau");

var MAYAN_TZOLKIN_MONTHS_EN = new Array("Crocodile", "Wind", "House", "Lizard", "Serpent",
                                        "Death", "Deer", "Rabbit", "Water", "Dog",
                                        "Monkey", "Grass", "Reed", "Jaguar", "Eagle", 
                                        "Vulture", "Earth", "Knife", "Storm", "Flower");

function jd_to_mayan_tzolkin(jd) {
    var lcount;

     jd = Math.floor(jd) + 0.5;
     lcount = jd - MAYAN_COUNT_EPOCH;
     return new Array(amod(lcount + 20, 20), amod(lcount + 4, 13));
}

function getMayanSign(sign, month, day, year) {

    var isValidated = true;
    var result = "";

    if (!IsNumeric(month.value) || month.value <= 0 || month.value > 12) {
        month.value = "MM";
        isValidated = false;
    }

    if (!IsNumeric(day.value) || day.value <= 0 || day.value > 31) {
        day.value = "DD";
        isValidated = false;
    }

    if (!IsNumeric(year.value) || year.value < 1900 ) {
        year.value = "YYYY";
        isValidated = false;
    }

    if (isValidated) {
        year = new Number(year.value);
        mon = new Number(month.value);
        mday = new Number(day.value);
        hour = min = sec = 0;

        //  Update Julian day
        j = gregorian_to_jd(year, mon + 0, mday) +
           (Math.floor(sec + 60 * (min + 60 * hour) + 0.5) / 86400.0);

            maytzolkincal = jd_to_mayan_tzolkin(j);
            result = MAYAN_TZOLKIN_MONTHS_EN[maytzolkincal[0] - 1];
        } else result = "INVALID BIRTHDAY";

        sign.value = result;
    }

PHP类:

class MayanCalculator {

        //  JD_TO_MAYAN_TZOLKIN  --  Determine Mayan Tzolkin "month" and day from Julian day
        private $MAYAN_TZOLKIN_MONTHS = array("Imix", "Ik", "Akbal", "Kan", "Chicchan",
                                             "Cimi", "Manik", "Lamat", "Muluc", "Oc",
                                             "Chuen", "Eb", "Ben", "Ix", "Men",
                                             "Cib", "Caban", "Etznab", "Cauac", "Ahau");

        private $MAYAN_TZOLKIN_MONTHS_EN = array("Crocodile", "Wind", "House", "Lizard", "Serpent",
                                        "Death", "Deer", "Rabbit", "Water", "Dog",
                                        "Monkey", "Grass", "Reed", "Jaguar", "Eagle", 
                                        "Vulture", "Earth", "Knife", "Storm", "Flower");

        private $GREGORIAN_EPOCH = 1721425.5;

        private $MAYAN_COUNT_EPOCH = 584282.5;

        private $MAYAN_HAAB_MONTHS = array("Pop", "Uo", "Zip", "Zotz", "Tzec", "Xul",
                                  "Yaxkin", "Mol", "Chen", "Yax", "Zac", "Ceh",
                                  "Mac", "Kankin", "Muan", "Pax", "Kayab", "Cumku", "Uayeb");

        private $_day;
        private $_month;
        private $_year;
        private $sign;
        private $signm;

        function __construct($day, $month, $year) {
                $this->_day = $day;
                $this->_month = $month;
                $this->_year = $year;
        }

        public function getMayanSign() {

            $this->sign = $this->getSign();
            $this->signm = $this->getMayanSignOnMayan();    

            $ids = new getIDS(null,null,$this->sign);
            $id = $ids->returnIDS();
            return array("mayan_sign" => $this->sign, "mayan_sign_on_mayan" => $this->signm, "mayan_sign_id" => $id["mayan_id"]);

        }

        private function getSign() {
            $isValidated = true;
            $result = null;

            if (!is_numeric($this->_month) || $this->_month <= 0 || $this->_month > 12) :
                $isValidated = false;
            endif;  

            if (!is_numeric($this->_day) || $this->_day <= 0 || $this->_day > 31) :
                $isValidated = false;
            endif;  

            if (!is_numeric($this->_year) || $this->_year < 1900) :
                $isValidated = false;
            endif;  

            if ($isValidated) : 

                $hour = 0;
                $min = 0;
                $sec = 0;

                //update julian day
                $j = $this->gregorian_to_jd($this->_year, $this->_month+0, $this->_day) + (floor($sec + 60 * ($min + 60 * $hour) + 0.5) / 86400.0);
                $maytzolkincal = $this->jd_to_mayan_tzolkin($j);
                $result = $this->MAYAN_TZOLKIN_MONTHS_EN[$maytzolkincal[0]-1];
            else :

            $result = 'Wrong date '.  $this->_day . '.' . $this->_month . '.' . $this->_year;

            endif;

            return $result; 
        }

        private function getMayanSignOnMayan() {
            $isValidated = true;
            $result = null;

            if (!is_numeric($this->_month) || $this->_month <= 0 || $this->_month > 12) :
                $isValidated = false;
            endif;  

            if (!is_numeric($this->_day) || $this->_day <= 0 || $this->_day > 31) :
                $isValidated = false;
            endif;  

            if (!is_numeric($this->_year) || $this->_year < 1900) :
                $isValidated = false;
            endif;  

            if ($isValidated) : 

                $hour = 0;
                $min = 0;
                $sec = 0;

                //update julian day
                $j = $this->gregorian_to_jd($this->_year, $this->_month+0, $this->_day) + (floor($sec + 60 * ($min + 60 * $hour) + 0.5) / 86400);
                $maytzolkincal = $this->jd_to_mayan_tzolkin($j);
                $result = $this->MAYAN_TZOLKIN_MONTHS[$maytzolkincal[0]]-1;
            else :

            $result = 'Wrong date '.  $this->_day . '.' . $this->_month . '.' . $this->_year;

            endif;

            return $result; 
        }

        private function leap_gregorian($year) {
                    return (($year % 4) == 0) && (!((($year % 100) == 0) && (($year % 400) != 0)));
        }

        private function gregorian_to_jd($year, $month, $day) {
            $result = ($this->GREGORIAN_EPOCH - 1) +
                   (365 * ($year - 1)) +
                   floor(($year - 1) / 4) +
                   (-floor(($year - 1) / 100)) +
                   floor(($year - 1) / 400) +
                   floor((((367 * $month) - 362) / 12) +
                   (($month <= 2) ? 0 : ($this->leap_gregorian($year) ? -1 : -2)) +
                   $day);
            return $result;
        }

        private function jd_to_mayan_count($jd) {
        $jd = floor($jd) + 0.5;
        $d = $jd - $this->MAYAN_COUNT_EPOCH;
        $baktun = floor($d / 144000);
        $d = $d % 144000;
        $katun = floor($d / 7200);
        $d = $d % 7200;
        $tun = floor($d / 360);
        $d = $d % 360;
        $uinal = floor($d / 20);
        $kin = $d % 20;

        return array($baktun, $katun, $tun, $uinal, $kin);
        }

        private function jd_to_mayan_haab($jd) {

            $jd = floor($jd) + 0.5;
            $lcount = $jd - $this->MAYAN_COUNT_EPOCH;
            $day = ($lcount + 8 + ((18 - 1) * 20)) % 365;

            return array(floor($day / 20) + 1, $day % 20);
        }

        private function jd_to_mayan_tzolkin($jd) {
             $jd = floor($jd) + 0.5;
             $lcount = $jd - $this->MAYAN_COUNT_EPOCH;
             return array(($lcount + 20) % 20, ($lcount + 4) % 13);
        }

}
4

1 回答 1

1

第一:总是发布所有相关的脚本。您缺少对解决您的问题至关重要的 JavaScript 函数 amod(),我在原始版本中找到了

您的 PHP 函数jd_to_mayan_tzolkin()与您的 JavaScript 函数不同jd_to_mayan_tzolkin()

而 JavaScript 使用单独的函数amod()来计算模数并在模数结果为时返回分子0

//  AMOD  --  Modulus function which returns numerator if modulus is zero
function amod($a, $b) {
  return $this->mod($a - 1, $b) + 1;
}

您的 php 函数只返回可能的模数,0因此您的 PHP 的进一步处理失败。

将以下两个函数添加到您的类中:

/*  MOD  --  Modulus function which works for non-integers.  */
private function mod($a, $b) {
  return $a - ($b * floor($a / $b));
}

//  AMOD  --  Modulus function which returns numerator if modulus is zero
private function amod($a, $b) {
  return $this->mod($a - 1, $b) + 1;
}   

并更改PHP方法jd_to_mayan_tzolkin()如下:

private function jd_to_mayan_tzolkin($jd) {
     $jd = floor($jd) + 0.5;
     $lcount = $jd - $this->MAYAN_COUNT_EPOCH;
     return array($this->amod(($lcount + 20),20), $this->amod(($lcount + 4),13));
}
于 2012-10-31T13:34:37.417 回答