赛博算命之“八字排盘“的JAVA实现

各位大佬们好呀~互三必回哦!
更多精彩:个人主页
赛博算命系列更多精彩:
赛博算命之梅花易数的JAVA实现
赛博算命之周易六十四卦的JAVA实现
赛博算命之掐指一算的JAVA实现
JAVA专栏:Java学习

文章目录

一、文化背景

​ 我们常说:八字还没一撇呢 , 生辰八字...八字,作为中国传统命理学的核心概念,承载着深厚的文化内涵。它源于古代的天干地支纪年法,通过年、月、日、时四个维度,每个维度由一个天干和一个地支组成,共八个字,故而得名 "八字"。古人认为,一个人出生时的八字信息,蕴含了其一生的命运密码,包括性格、事业、婚姻、财运等诸多方面。其实八字排盘的运算不过就是数学原理,我们可以用java来实现,开启一场赛博算命!

二、排盘原理

1.天干地支

天干有十个,分别为:甲、乙、丙、丁、戊、己、庚、辛、壬、癸。地支有十二个,分别为:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥。天干地支按顺序两两相配,从甲子到癸亥,共六十个组合,称为 "六十甲子",用于纪年、月、日、时。在代码中,我们通过数组来存储天干和地支:

java 复制代码
// 天干数组
private static final String[] TIANGAN = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
// 地支数组
private static final String[] DIZHI = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};

2.年柱的确定

年柱的天干地支可以通过查阅万年历或者使用公式计算得出。对于公元年份,计算天干的公式为:(年份 - 3)% 10,对应天干顺序;计算地支的公式为:(年份 - 3)% 12,对应地支顺序。代码实现如下:

java 复制代码
// 根据年份获取年柱
public static String getYearColumn(int year) {
    int tgIndex = (year - 3) % 10;
    int dzIndex = (year - 3) % 12;
    return TIANGAN[tgIndex] + DIZHI[dzIndex];
}

3.月柱的确定

月柱的地支是固定的,正月为寅,二月为卯,以此类推。天干则根据年干来确定,有 "五虎遁年起月诀":甲己之年丙作首,乙庚之岁戊为头,丙辛之岁寻庚上,丁壬壬寅顺水流,若问戊癸何处起,甲寅之上好追求。我们通过映射表来实现这个逻辑:

java 复制代码
// 月份地支数组
private static final String[] MONTH_DIZHI = {"寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"};
// 五虎遁年起月诀映射
private static final Map<Character, Integer> YEAR_MAP = new HashMap<>();

static {
    YEAR_MAP.put('甲', 2);
    YEAR_MAP.put('乙', 4);
    YEAR_MAP.put('丙', 6);
    YEAR_MAP.put('丁', 8);
    YEAR_MAP.put('戊', 10);
    YEAR_MAP.put('己', 2);
    YEAR_MAP.put('庚', 4);
    YEAR_MAP.put('辛', 6);
    YEAR_MAP.put('壬', 8);
    YEAR_MAP.put('癸', 10);
}

// 根据年柱和月份获取月柱
public static String getMonthColumn(String yearColumn, int month) {
    int tgIndex = YEAR_MAP.get(yearColumn.charAt(0)) + month - 1;
    tgIndex = tgIndex % 10;
    int dzIndex = month - 1;
    return TIANGAN[tgIndex] + MONTH_DIZHI[dzIndex];
}

4.日柱的确定

日柱的计算较为复杂,通常使用已知的日期和公式来推算。这里以蔡勒公式为例,蔡勒公式为:(W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1),其中(W)为星期数,(C)为世纪数减一,(y)为年份后两位,(M)为月份((M)大于等于 3,小于等于 14,即在蔡勒公式中,某年的 1、2 月要看作上一年的 13、14 月来计算),(d)为日数。得出(W)后,对 7 取模得到星期数,同时可以通过一些转换得到日柱的天干地支。以下是完整的蔡勒公式计算日柱天干地支的代码实现(假设已经有将(W)转换为天干地支的方法getTianGanDiZhiFromW):

java 复制代码
// 根据蔡勒公式计算日柱
public static String getDayColumn(int year, int month, int day) {
    int C = year / 100;
    int y = year % 100;
    if (month < 3) {
        y = y - 1;
        C = C - 1;
    }
    int M = month;
    if (month < 3) {
        M = M + 12;
    }
    int W = (C / 4) - 2 * C + y + (y / 4) + (13 * (M + 1) / 5) + day - 1;
    while (W < 0) {
        W = W + 7;
    }
    W = W % 7;
    return getTianGanDiZhiFromW(W);
}

// 假设这个方法将W转换为对应的天干地支
private static String getTianGanDiZhiFromW(int W) {
    // 这里需要根据具体的转换逻辑实现,暂未完整实现
    return "";
}

5.时柱的确定

时柱的地支根据出生时间确定,如 23 - 1 点为子时,1 - 3 点为丑时等。天干则根据日干来确定,有 "五鼠遁日起时诀":甲己还加甲,乙庚丙作初,丙辛从戊起,丁壬庚子居,戊癸何方发,壬子是真途。我们通过映射表来实现:

java 复制代码
// 五鼠遁日起时诀映射
private static final Map<Character, Integer> DAY_MAP = new HashMap<>();

static {
    DAY_MAP.put('甲', 0);
    DAY_MAP.put('乙', 2);
    DAY_MAP.put('丙', 4);
    DAY_MAP.put('丁', 6);
    DAY_MAP.put('戊', 8);
    DAY_MAP.put('己', 0);
    DAY_MAP.put('庚', 2);
    DAY_MAP.put('辛', 4);
    DAY_MAP.put('壬', 6);
    DAY_MAP.put('癸', 8);
}

// 根据日柱和时辰获取时柱
public static String getHourColumn(String dayColumn, int hour) {
    int tgIndex = DAY_MAP.get(dayColumn.charAt(0)) + hour / 2;
    tgIndex = tgIndex % 10;
    int dzIndex = hour / 2;
    return TIANGAN[tgIndex] + DIZHI[dzIndex];
}

三、代码实现

1.思路展现

步骤 1:数据准备

在进行八字排盘之前,我们需要准备好天干、地支以及相关的映射表,这些数据是后续计算的基础。

  • 天干和地支数组
    • 天干 :天干共有 10 个,依次为甲、乙、丙、丁、戊、己、庚、辛、壬、癸,在代码中用 TIANGAN 数组存储。天干用于纪年、月、日、时,其顺序是固定的,在计算八字各柱时会根据特定规则选取相应的天干。
    • 地支 :地支有 12 个,分别是子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥,用 DIZHI 数组存储。地支同样用于纪年、月、日、时,并且在传统的时间划分中,地支与一天中的时辰以及一年中的月份有对应关系。
    • 月份对应的地支 :在八字排盘中,月份的地支是固定的,正月对应寅,二月对应卯,以此类推,存储在 MONTH_DIZHI 数组中。这是基于传统的农历月份与地支的对应规则。
  • 映射表
    • YEAR_MAP :根据 "五虎遁年起月诀" 建立的映射表。"五虎遁年起月诀" 是确定月柱天干的规则,其内容为 "甲己之年丙作首,乙庚之岁戊为头,丙辛之岁寻庚上,丁壬壬寅顺水流,若问戊癸何处起,甲寅之上好追求"。例如,甲年或己年,正月的天干从丙开始,丙在天干数组中的索引为 2,所以 YEAR_MAP.put('甲', 2)。这个映射表用于根据年干确定月柱天干的起始位置。
    • DAY_MAP :依据 "五鼠遁日起时诀" 构建的映射表。"五鼠遁日起时诀" 用于确定时柱的天干,口诀是 "甲己还加甲,乙庚丙作初,丙辛从戊起,丁壬庚子居,戊癸何方发,壬子是真途"。例如,甲日或己日,子时的天干从甲开始,甲在天干数组中的索引为 0,因此 DAY_MAP.put('甲', 0)。该映射表根据日干确定时柱天干的起始位置。

步骤 2:获取用户输入

通过 Scanner 类从控制台获取用户输入的出生年份、月份、日期和时辰。这些信息是进行八字排盘的依据,代码如下:

java 复制代码
Scanner scanner = new Scanner(System.in);

System.out.print("请输入出生年份:");
int year = scanner.nextInt();

System.out.print("请输入出生月份:");
int month = scanner.nextInt();

System.out.print("请输入出生日期:");
int day = scanner.nextInt();

System.out.print("请输入出生时辰(0 - 23):");
int hour = scanner.nextInt();

步骤 3:计算年柱

  • 计算原理:年柱由年份对应的天干和地支组成。在传统的干支纪年法中,通过一个固定的公式来确定某一年对应的天干和地支。公式为:(年份 - 3)对 10 取模得到天干的索引,对 12 取模得到地支的索引。这里减去 3 是为了校正干支纪年与公元纪年的起始差异。

  • 代码实现

    java 复制代码
    public static String getYearColumn(int year) {
        int tgIndex = (year - 3) % 10;
        int dzIndex = (year - 3) % 12;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }
  • 调用示例

    java 复制代码
    String yearColumn = getYearColumn(year);

步骤 4:计算月柱

  • 计算原理 :月柱的地支根据月份是固定的,正月为寅,二月为卯,以此类推。而月柱的天干需要根据年干来确定,使用 "五虎遁年起月诀"。具体做法是先从 YEAR_MAP 中获取年干对应的天干索引偏移量,然后将偏移量加上月份减 1,得到月柱天干的索引,并对 10 取模确保索引在合法范围内。月份减 1 作为月柱地支的索引。

  • 代码实现

    java 复制代码
    public static String getMonthColumn(String yearColumn, int month) {
        int tgIndex = YEAR_MAP.get(yearColumn.charAt(0)) + month - 1;
        tgIndex = tgIndex % 10;
        int dzIndex = month - 1;
        return TIANGAN[tgIndex] + MONTH_DIZHI[dzIndex];
    }
  • 调用示例

    java 复制代码
    String monthColumn = getMonthColumn(yearColumn, month);

步骤 5:计算日柱

  • 计算原理:日柱的计算较为复杂,通常使用蔡勒公式。蔡勒公式是一种用于计算某一天是星期几的公式,经过适当的转换可以用于计算日柱的天干地支。,蔡勒公式为:(W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1),其中(W)为星期数,(C)为世纪数减一,(y)为年份后两位,(M)为月份((M)大于等于 3,小于等于 14,即在蔡勒公式中,某年的 1、2 月要看作上一年的 13、14 月来计算),(d)为日数。得出(W)后,对 7 取模得到星期数,同时可以通过一些转换得到日柱的天干地支。

  • 代码实现(简化)

    java 复制代码
    public static String getDayColumn(int year, int month, int day) {
        // 蔡勒公式核心逻辑省略,这里简单假设一个固定结果
        int tgIndex = 0;
        int dzIndex = 0;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }
  • 调用示例

    java 复制代码
    String dayColumn = getDayColumn(year, month, day);

步骤 6:计算时柱

  • 计算原理 :时柱的地支根据时辰确定,每两个小时为一个时辰,23 - 1 点为子时,1 - 3 点为丑时,以此类推。时柱的天干根据日干来确定,使用 "五鼠遁日起时诀"。具体操作是从 DAY_MAP 中获取日干对应的天干索引偏移量,将偏移量加上时辰除以 2 的结果,得到时柱天干的索引,并对 10 取模确保索引在合法范围内。时辰除以 2 作为时柱地支的索引。

  • 代码实现

    java 复制代码
    public static String getHourColumn(String dayColumn, int hour) {
        int tgIndex = DAY_MAP.get(dayColumn.charAt(0)) + hour / 2;
        tgIndex = tgIndex % 10;
        int dzIndex = hour / 2;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }
  • 调用示例

    java 复制代码
    String hourColumn = getHourColumn(dayColumn, hour);

步骤 7:输出八字结果

将计算得到的年柱、月柱、日柱和时柱组合起来,输出最终的八字结果,代码如下:

java 复制代码
System.out.println("八字为:" + yearColumn + " " + monthColumn + " " + dayColumn + " " + hourColumn);

步骤 8:关闭输入流

最后,关闭 Scanner 对象以释放资源:

java 复制代码
scanner.close();

通过以上步骤,结合相应的计算原理,就完成了根据用户输入进行八字排盘的过程。需要注意的是,日柱的计算在示例中进行了简化,实际使用时需要完整实现蔡勒公式以确保结果的准确性。

2.代码实现

java 复制代码
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class BaZiCalculator {
    // 天干数组
    private static final String[] TIANGAN = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
    // 地支数组
    private static final String[] DIZHI = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
    // 月份地支数组,正月为寅,依次类推
    private static final String[] MONTH_DIZHI = {"寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"};
    // 五虎遁年起月诀映射,用于根据年干确定月干
    private static final Map<Character, Integer> YEAR_MAP = new HashMap<>();
    // 五鼠遁日起时诀映射,用于根据日干确定时干
    private static final Map<Character, Integer> DAY_MAP = new HashMap<>();

    static {
        // 初始化五虎遁年起月诀映射
        YEAR_MAP.put('甲', 2);
        YEAR_MAP.put('乙', 4);
        YEAR_MAP.put('丙', 6);
        YEAR_MAP.put('丁', 8);
        YEAR_MAP.put('戊', 10);
        YEAR_MAP.put('己', 2);
        YEAR_MAP.put('庚', 4);
        YEAR_MAP.put('辛', 6);
        YEAR_MAP.put('壬', 8);
        YEAR_MAP.put('癸', 10);

        // 初始化五鼠遁日起时诀映射
        DAY_MAP.put('甲', 0);
        DAY_MAP.put('乙', 2);
        DAY_MAP.put('丙', 4);
        DAY_MAP.put('丁', 6);
        DAY_MAP.put('戊', 8);
        DAY_MAP.put('己', 0);
        DAY_MAP.put('庚', 2);
        DAY_MAP.put('辛', 4);
        DAY_MAP.put('壬', 6);
        DAY_MAP.put('癸', 8);
    }

    /**
     * 根据年份获取年柱
     * @param year 年份
     * @return 年柱,如 "甲辰"
     */
    public static String getYearColumn(int year) {
        int tgIndex = (year - 3) % 10;
        int dzIndex = (year - 3) % 12;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }

    /**
     * 根据年柱和月份获取月柱
     * @param yearColumn 年柱
     * @param month 月份
     * @return 月柱,如 "丁卯"
     */
    public static String getMonthColumn(String yearColumn, int month) {
        int tgIndex = YEAR_MAP.get(yearColumn.charAt(0)) + month - 1;
        tgIndex = tgIndex % 10;
        int dzIndex = month - 1;
        return TIANGAN[tgIndex] + MONTH_DIZHI[dzIndex];
    }

    /**
     * 根据蔡勒公式计算日柱,此处简化处理
     * 实际应用中需要完整实现蔡勒公式并进行精确计算
     * @param year 年份
     * @param month 月份
     * @param day 日期
     * @return 日柱,如 "丙午"
     */
    public static String getDayColumn(int year, int month, int day) {
        // 蔡勒公式核心逻辑省略,这里简单假设一个固定结果
        int tgIndex = 0;
        int dzIndex = 0;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }

    /**
     * 根据日柱和时辰获取时柱
     * @param dayColumn 日柱
     * @param hour 时辰
     * @return 时柱,如 "戊子"
     */
    public static String getHourColumn(String dayColumn, int hour) {
        int tgIndex = DAY_MAP.get(dayColumn.charAt(0)) + hour / 2;
        tgIndex = tgIndex % 10;
        int dzIndex = hour / 2;
        return TIANGAN[tgIndex] + DIZHI[dzIndex];
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入出生年份:");
        int year = scanner.nextInt();

        System.out.print("请输入出生月份:");
        int month = scanner.nextInt();

        System.out.print("请输入出生日期:");
        int day = scanner.nextInt();

        System.out.print("请输入出生时辰(0 - 23):");
        int hour = scanner.nextInt();

        // 计算年柱
        String yearColumn = getYearColumn(year);
        // 计算月柱
        String monthColumn = getMonthColumn(yearColumn, month);
        // 计算日柱
        String dayColumn = getDayColumn(year, month, day);
        // 计算时柱
        String hourColumn = getHourColumn(dayColumn, hour);

        System.out.println("八字为:" + yearColumn + " " + monthColumn + " " + dayColumn + " " + hourColumn);

        scanner.close();
    }
}

让我们来运行一下:

java 复制代码
请输入出生年份:2006
请输入出生月份:1
请输入出生日期:20
请输入出生时辰(0 - 23):5
八字为:丁亥 壬寅 甲子 丙寅

进程已结束,退出代码为 0

3.代码说明:

  1. 常量和映射表
    • TIANGANDIZHI 数组分别存储天干和地支。
    • MONTH_DIZHI 数组存储月份对应的地支。
    • YEAR_MAPDAY_MAP 分别是根据 "五虎遁年起月诀" 和 "五鼠遁日起时诀" 建立的映射表,用于确定月干和时干。
  2. 排盘方法
    • getYearColumn:根据年份计算年柱。
    • getMonthColumn:根据年柱和月份计算月柱。
    • getDayColumn:使用蔡勒公式计算日柱,但此处简化处理,实际使用时需完整实现。
    • getHourColumn:根据日柱和时辰计算时柱。
  3. 主函数
    • 使用 Scanner 类从控制台读取用户输入的年、月、日、时信息。
    • 调用上述排盘方法计算八字的各个柱。
    • 输出最终的八字结果。

注意事项:

  • getDayColumn 方法中的蔡勒公式计算部分被简化,实际开发中需要完整实现该公式以得到准确的日柱结果。
  • 代码没有对用户输入进行严格的验证,在实际应用中可以添加输入验证逻辑,确保输入的年、月、日、时信息在合理范围内。

四、总结

通过对八字排盘的文化背景、排盘原理以及 Java 代码实现的介绍,我们不仅了解了中国传统命理学的奥秘,还掌握了如何使用现代编程技术来实现这一古老的文化算法。八字排盘的 Java 实现,不仅是对传统文化的传承和创新,也是计算机技术在文化领域应用的一个有趣案例。希望本文能为对八字排盘和 Java 编程感兴趣的读者提供有益的参考。

lumn`:根据日柱和时辰计算时柱。

  1. 主函数
  • 使用 Scanner 类从控制台读取用户输入的年、月、日、时信息。
  • 调用上述排盘方法计算八字的各个柱。
  • 输出最终的八字结果。

注意事项:

  • getDayColumn 方法中的蔡勒公式计算部分被简化,实际开发中需要完整实现该公式以得到准确的日柱结果。
  • 代码没有对用户输入进行严格的验证,在实际应用中可以添加输入验证逻辑,确保输入的年、月、日、时信息在合理范围内。

四、总结

通过对八字排盘的文化背景、排盘原理以及 Java 代码实现的介绍,我们不仅了解了中国传统命理学的奥秘,还掌握了如何使用现代编程技术来实现这一古老的文化算法。八字排盘的 Java 实现,不仅是对传统文化的传承和创新,也是计算机技术在文化领域应用的一个有趣案例。希望本文能为对八字排盘和 Java 编程感兴趣的读者提供有益的参考。

相关推荐
天上掉下来个程小白3 分钟前
HttpClient-03.入门案例-发送POST方式请求
java·spring·httpclient·苍穹外卖
ModestCoder_13 分钟前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
android·java·机器人
带娃的IT创业者27 分钟前
《Python实战进阶》No39:模型部署——TensorFlow Serving 与 ONNX
pytorch·python·tensorflow·持续部署
a1800793108034 分钟前
软件工程面试题(二十二)
java·面试·软件工程
Bruce-li__34 分钟前
深入理解Python asyncio:从入门到实战,掌握异步编程精髓
网络·数据库·python
RainbowSea37 分钟前
4. RabbitMQ 发布确认的配置详细说明
java·消息队列·rabbitmq
九月镇灵将44 分钟前
6.git项目实现变更拉取与上传
git·python·scrapy·scrapyd·gitpython·gerapy
车载小杜1 小时前
基于指针的线程池
开发语言·c++
robin_suli1 小时前
Spring事务的传播机制
android·java·spring
青云交1 小时前
Java 大视界 -- Java 大数据在智能电网电力市场交易数据分析与策略制定中的关键作用(162)
java·大数据·数据分析·交易策略·智能电网·java 大数据·电力市场交易