首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 依生日計算星座與生肖完整實作指南

     編輯:PHP 相關知識

前言

在會員系統、占卜應用或個人化推薦中,依出生日期推算星座、生肖與年齡是常見需求。本文提供兩種風格的實作:精簡版星座判斷與完整版綜合類別,並修正原始碼中存在的邏輯錯誤與編碼問題,開箱即用。

星座日期對照表(曆法依據)

星座日期區間備註
摩羯座12/22 ~ 01/19跨年界
水瓶座01/20 ~ 02/18
雙魚座02/19 ~ 03/20
白羊座03/21 ~ 04/19
金牛座04/20 ~ 05/20
雙子座05/21 ~ 06/21
巨蟹座06/22 ~ 07/22
獅子座07/23 ~ 08/22
處女座08/23 ~ 09/22
天秤座09/23 ~ 10/23
天蠍座10/24 ~ 11/22
射手座11/23 ~ 12/21
※ 以上日期為通用曆法近似值,精確劃分需參考當年節氣交節時刻。

方案一:精簡版星座判斷函式

利用「每月星座起始日」陣列,配合 array_key_exists 防呆,邏輯清晰、易維護:

/**
 * 依月份、日期回傳星座名稱
 * @param int $month 1-12
 * @param int $day   1-31
 * @return string|false 星座名稱或 false(參數錯誤)
 */
function getConstellation(int $month, int $day) {
    // 參數驗證
    if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
        return false;
    }

    // 各月星座起始日(日),索引 0=1月 ... 11=12月
    $startDays = [
        20, // 1月 水瓶座起
        19, // 2月 雙魚座起
        21, // 3月 白羊座起
        20, // 4月 金牛座起
        21, // 5月 雙子座起
        22, // 6月 巨蟹座起
        23, // 7月 獅子座起
        23, // 8月 處女座起
        23, // 9月 天秤座起
        24, // 10月 天蠍座起
        22, // 11月 射手座起
        22  // 12月 摩羯座起
    ];

    $signs = [
        '水瓶座','雙魚座','白羊座','金牛座','雙子座','巨蟹座',
        '獅子座','處女座','天秤座','天蠍座','射手座','摩羯座'
    ];

    $start = $startDays[$month - 1];
    // 日期小於起始日 → 上一個星座
    $idx = ($day < $start) ? (($month - 2 + 12) % 12) : ($month - 1);
    return $signs[$idx];
}

方案二:完整版 BirthdayInfo 類別(星座、生肖、年齡一次滿足)

採用物件導向封裝,支援單元測試、擴充性強,並修正原始碼中 strpos 邏輯錯誤、閏年計算不準等問題:

class BirthdayInfo {
    private int $year;
    private int $month;
    private int $day;

    public function __construct(int $year, int $month, int $day) {
        if (!checkdate($month, $day, $year)) {
            throw new InvalidArgumentException('無效出生日期');
        }
        $this->year  = $year;
        $this->month = $month;
        $this->day   = $day;
    }

    /** 取得星座 */
    public function getConstellation(): string {
        $startDays = [20,19,21,20,21,22,23,23,23,24,22,22];
        $signs     = ['水瓶座','雙魚座','白羊座','金牛座','雙子座','巨蟹座',
                      '獅子座','處女座','天秤座','天蠍座','射手座','摩羯座'];
        $start = $startDays[$this->month - 1];
        $idx   = ($this->day < $start) ? (($this->month - 2 + 12) % 12) : ($this->month - 1);
        return $signs[$idx];
    }

    /** 取得生肖(1900 為鼠年基準) */
    public function getZodiac(): string {
        $animals = ['鼠','牛','虎','兔','龍','蛇','馬','羊','猴','雞','狗','豬'];
        return $animals[($this->year - 1900) % 12];
    }

    /** 取得周歲(滿歲) */
    public function getAge(): int {
        $today   = new DateTime();
        $birth   = new DateTime(sprintf('%04d-%02d-%02d', $this->year, $this->month, $this->day));
        $diff    = $today->diff($birth);
        return $diff->y;
    }

    /** 取得虛歲(傳統算法:出生即 1 歲,過年加 1) */
    public function getTraditionalAge(): int {
        return $this->getAge() + 1;
    }
}

使用範例

$info = new BirthdayInfo(1990, 5, 15);
echo "星座:{$info->getConstellation()}\n";      // 金牛座
echo "生肖:{$info->getZodiac()}\n";            // 馬
echo "周歲:{$info->getAge()}\n";               // 依今日日期
echo "虛歲:{$info->getTraditionalAge()}\n";    // 周歲 + 1

常見坑點與修正說明

  1. strpos 回傳 0 視為 false:原始碼用 if (strpos(...)) 判斷 Opera 會失效,正確寫法 if (strpos(...) !== false)。
  2. 閏年與跨月界:使用 checkdate() 驗證日期合法性,DateTime::diff() 自動處理閏年、跨月。
  3. 編碼問題:原始碼出現「天蠍座)」多餘括號、全形空白等,已全部修正為 UTF-8 標準字串。

延伸應用建議

  • 整合至 Laravel/Eloquent Accessor,模型自動附屬 constellation、zodiac 屬性。
  • 搭配 Redis 快取熱門生日查詢,降低運算開銷。
  • 前端套用 flatpickr 或原生 <input type="date"> 取得標準格式,直接傳給後端。

總結

本文提供從精簡函式到完整類別的兩種實作,修正了原始碼的邏輯與編碼缺陷,並採用現代 PHP 特型宣告、例外處理、DateTime 物件,確保準確度與可維護性。直接複製即可投入生產環境,亦可依專案需求擴充農曆生日、星座運勢等功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved