核心函數
<?php
/**
* 計算星座
* @param int $month 月份 1-12
* @param int $day 日期 1-31
* @return string|false 星座名稱或 false
*/
function get_zodiac_sign($month, $day) {
// 參數驗證
if ($month < 1 || $month > 12 || $day < 1 || $day > 31) return false;
// 星座起始日期(月份索引 0-11 對應 1-12 月)
// 格式:'起始日' => '星座名'
$signs = [
1 => ['20' => '寶瓶座'], // 1月20日開始
2 => ['19' => '雙魚座'], // 2月19日
3 => ['21' => '白羊座'], // 3月21日
4 => ['20' => '金牛座'], // 4月20日
5 => ['21' => '雙子座'], // 5月21日
6 => ['22' => '巨蟹座'], // 6月22日
7 => ['23' => '獅子座'], // 7月23日
8 => ['23' => '處女座'], // 8月23日
9 => ['23' => '天秤座'], // 9月23日
10 => ['24' => '天蠍座'], // 10月24日
11 => ['22' => '射手座'], // 11月22日
12 => ['22' => '摩羯座'], // 12月22日
];
// 獲取當月星座起始日
$current = $signs[$month];
$startDay = (int)array_key_first($current);
$signName = array_values($current)[0];
// 若日期早於起始日,則屬於上一個星座
if ($day < $startDay) {
$prevMonth = $month - 1;
if ($prevMonth === 0) $prevMonth = 12; // 1月往前推到12月
$prev = $signs[$prevMonth];
$signName = array_values($prev)[0];
}
return $signName;
}
// 測試
var_dump(get_zodiac_sign(3, 20)); // 雙魚座
var_dump(get_zodiac_sign(3, 21)); // 白羊座
var_dump(get_zodiac_sign(12, 25)); // 摩羯座
var_dump(get_zodiac_sign(1, 15)); // 摩羯座
?>
邏輯解析
- 定義每個星座的起始日期(按月份索引)。
- 取出當月星座的起始日
$startDay。
- 若輸入日期
$day 小於起始日,說明屬於上一個月的星座(即上一個星座)。
- 處理 1 月往前推到 12 月(摩羯座)的邊界情況。
優化版:使用 DateTime 驗證日期合法性
<?php
function getZodiacSign(int $month, int $day): ?string {
// 嚴格驗證日期是否真實存在(如 2月30日)
try {
$dt = new DateTime("2020-$month-$day"); // 閏年包含2月29日
if ($dt->format('m-d') !== sprintf('%02d-%02d', $month, $day)) return null;
} catch (Exception $e) {
return null;
}
$signs = [
1 => [20, '寶瓶座'], 2 => [19, '雙魚座'], 3 => [21, '白羊座'],
4 => [20, '金牛座'], 5 => [21, '雙子座'], 6 => [22, '巨蟹座'],
7 => [23, '獅子座'], 8 => [23, '處女座'], 9 => [23, '天秤座'],
10 => [24, '天蠍座'], 11 => [22, '射手座'], 12 => [22, '摩羯座'],
];
[$startDay, $name] = $signs[$month];
if ($day < $startDay) {
$prev = $month === 1 ? 12 : $month - 1;
$name = $signs[$prev][1];
}
return $name;
}
?>
應用場景
- 用戶註冊填寫生日自動顯示星座
- 星座運勢、配對、性格分析功能
- 個性化推薦(如星座主題皮膚、內容)