11

我正在构建一个应用程序,它会告诉你的中文标志。我环顾四周,但只找到了图表(从 1900 年到 2020 年),没有逻辑可以创造出更动态的东西。

生肖的判断就没有逻辑吗?

4

8 回答 8

6

这是否回答你的问题:

public string ChineseZodiac(System.DateTime date)
{
    System.Globalization.EastAsianLunisolarCalendar cc = 
          new System.Globalization.ChineseLunisolarCalendar();
    int sexagenaryYear = cc.GetSexagenaryYear(date);
    int terrestrialBranch = cc.GetTerrestrialBranch(sexagenaryYear);

    // string[] years = "rat,ox,tiger,hare,dragon,snake,horse,sheep,monkey,fowl,dog,pig".Split(',');
    // string[] years = "Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig".Split(',');
    // string[] years = new string[]{ "rat", "ox", "tiger", "hare", "dragon", "snake", "horse", "sheep", "monkey", "fowl", "dog", "pig" };    
    string[] years = new string[]{ "Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig" };

    return years[terrestrialBranch - 1];
} // End Function ChineseZodiac

对于那些需要另一种编程语言的源代码的人:
我已经从 .NET 框架中提取了相应的源代码,这里: https ://gist.github.com/ststeiger/709354299a457e2d79b06d0127096fee

编辑:
我将此移植到 JavaScript:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChineseZodiac = void 0;
var DateTimeKind;
(function (DateTimeKind) {
    DateTimeKind[DateTimeKind["Unspecified"] = 0] = "Unspecified";
    DateTimeKind[DateTimeKind["Utc"] = 1] = "Utc";
    DateTimeKind[DateTimeKind["Local"] = 2] = "Local";
})(DateTimeKind || (DateTimeKind = {}));
var GregorianCalendar = (function () {
    function GregorianCalendar() {
    }
    GregorianCalendar.prototype.GetYear = function (time) {
        var ticks = time.JavaScriptTicks;
        var dt = new Date(ticks);
        return dt.getUTCFullYear();
    };
    GregorianCalendar.prototype.GetMonth = function (time) {
        var ticks = time.JavaScriptTicks;
        var dt = new Date(ticks);
        return (dt.getUTCMonth() + 1);
    };
    GregorianCalendar.prototype.GetDayOfMonth = function (time) {
        var ticks = time.JavaScriptTicks;
        var dt = new Date(ticks);
        return dt.getUTCDate();
    };
    return GregorianCalendar;
}());
var DotNetDateTime = (function () {
    function DotNetDateTime(ticks, dt) {
        this.m_ticks = 0;
        this.m_ticks = ticks;
    }
    DotNetDateTime.fromJsDate = function (dt) {
        var jsTicks = dt.getTime();
        var dotNetJsbaseTicks = 621355968000000000;
        var tenK = 10000;
        var dotTicks = dotNetJsbaseTicks + jsTicks * tenK;
        return new DotNetDateTime(dotTicks, DateTimeKind.Unspecified);
    };
    Object.defineProperty(DotNetDateTime.prototype, "Ticks", {
        get: function () {
            return this.m_ticks;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DotNetDateTime.prototype, "JavaScriptTicks", {
        get: function () {
            var dotNetJsbaseTicks = 621355968000000000;
            var dotNetTicksSince1970 = this.m_ticks - dotNetJsbaseTicks;
            var jsTicks = parseInt((dotNetTicksSince1970 / 10000).toString(), 10);
            return jsTicks;
        },
        enumerable: false,
        configurable: true
    });
    return DotNetDateTime;
}());
var MinLunisolarYear = 1901;
var MaxLunisolarYear = 2100;
var DaysPerYear = 365;
var DaysPer4Years = DaysPerYear * 4 + 1;
var DaysPer100Years = DaysPer4Years * 25 - 1;
var DaysPer400Years = DaysPer100Years * 4 + 1;
var DaysTo10000 = DaysPer400Years * 25 - 366;
var TicksPerMillisecond = 10000;
var TicksPerSecond = TicksPerMillisecond * 1000;
var TicksPerMinute = TicksPerSecond * 60;
var TicksPerHour = TicksPerMinute * 60;
var TicksPerDay = TicksPerHour * 24;
var MinTicks = 0;
var MaxTicks = DaysTo10000 * TicksPerDay - 1;
var MinValue = new DotNetDateTime(MinTicks, DateTimeKind.Unspecified);
var MaxValue = new DotNetDateTime(MaxTicks, DateTimeKind.Unspecified);
var Jan1Month = 1;
var Jan1Date = 2;
var nDaysPerMonth = 3;
var s_daysToMonth365 = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var s_daysToMonth366 = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
var s_yinfo = [
    [0, 2, 19, 19168],
    [0, 2, 8, 42352],
    [5, 1, 29, 21096],
    [0, 2, 16, 53856],
    [0, 2, 4, 55632],
    [4, 1, 25, 27304],
    [0, 2, 13, 22176],
    [0, 2, 2, 39632],
    [2, 1, 22, 19176],
    [0, 2, 10, 19168],
    [6, 1, 30, 42200],
    [0, 2, 18, 42192],
    [0, 2, 6, 53840],
    [5, 1, 26, 54568],
    [0, 2, 14, 46400],
    [0, 2, 3, 54944],
    [2, 1, 23, 38608],
    [0, 2, 11, 38320],
    [7, 2, 1, 18872],
    [0, 2, 20, 18800],
    [0, 2, 8, 42160],
    [5, 1, 28, 45656],
    [0, 2, 16, 27216],
    [0, 2, 5, 27968],
    [4, 1, 24, 44456],
    [0, 2, 13, 11104],
    [0, 2, 2, 38256],
    [2, 1, 23, 18808],
    [0, 2, 10, 18800],
    [6, 1, 30, 25776],
    [0, 2, 17, 54432],
    [0, 2, 6, 59984],
    [5, 1, 26, 27976],
    [0, 2, 14, 23248],
    [0, 2, 4, 11104],
    [3, 1, 24, 37744],
    [0, 2, 11, 37600],
    [7, 1, 31, 51560],
    [0, 2, 19, 51536],
    [0, 2, 8, 54432],
    [6, 1, 27, 55888],
    [0, 2, 15, 46416],
    [0, 2, 5, 22176],
    [4, 1, 25, 43736],
    [0, 2, 13, 9680],
    [0, 2, 2, 37584],
    [2, 1, 22, 51544],
    [0, 2, 10, 43344],
    [7, 1, 29, 46248],
    [0, 2, 17, 27808],
    [0, 2, 6, 46416],
    [5, 1, 27, 21928],
    [0, 2, 14, 19872],
    [0, 2, 3, 42416],
    [3, 1, 24, 21176],
    [0, 2, 12, 21168],
    [8, 1, 31, 43344],
    [0, 2, 18, 59728],
    [0, 2, 8, 27296],
    [6, 1, 28, 44368],
    [0, 2, 15, 43856],
    [0, 2, 5, 19296],
    [4, 1, 25, 42352],
    [0, 2, 13, 42352],
    [0, 2, 2, 21088],
    [3, 1, 21, 59696],
    [0, 2, 9, 55632],
    [7, 1, 30, 23208],
    [0, 2, 17, 22176],
    [0, 2, 6, 38608],
    [5, 1, 27, 19176],
    [0, 2, 15, 19152],
    [0, 2, 3, 42192],
    [4, 1, 23, 53864],
    [0, 2, 11, 53840],
    [8, 1, 31, 54568],
    [0, 2, 18, 46400],
    [0, 2, 7, 46752],
    [6, 1, 28, 38608],
    [0, 2, 16, 38320],
    [0, 2, 5, 18864],
    [4, 1, 25, 42168],
    [0, 2, 13, 42160],
    [10, 2, 2, 45656],
    [0, 2, 20, 27216],
    [0, 2, 9, 27968],
    [6, 1, 29, 44448],
    [0, 2, 17, 43872],
    [0, 2, 6, 38256],
    [5, 1, 27, 18808],
    [0, 2, 15, 18800],
    [0, 2, 4, 25776],
    [3, 1, 23, 27216],
    [0, 2, 10, 59984],
    [8, 1, 31, 27432],
    [0, 2, 19, 23232],
    [0, 2, 7, 43872],
    [5, 1, 28, 37736],
    [0, 2, 16, 37600],
    [0, 2, 5, 51552],
    [4, 1, 24, 54440],
    [0, 2, 12, 54432],
    [0, 2, 1, 55888],
    [2, 1, 22, 23208],
    [0, 2, 9, 22176],
    [7, 1, 29, 43736],
    [0, 2, 18, 9680],
    [0, 2, 7, 37584],
    [5, 1, 26, 51544],
    [0, 2, 14, 43344],
    [0, 2, 3, 46240],
    [4, 1, 23, 46416],
    [0, 2, 10, 44368],
    [9, 1, 31, 21928],
    [0, 2, 19, 19360],
    [0, 2, 8, 42416],
    [6, 1, 28, 21176],
    [0, 2, 16, 21168],
    [0, 2, 5, 43312],
    [4, 1, 25, 29864],
    [0, 2, 12, 27296],
    [0, 2, 1, 44368],
    [2, 1, 22, 19880],
    [0, 2, 10, 19296],
    [6, 1, 29, 42352],
    [0, 2, 17, 42208],
    [0, 2, 6, 53856],
    [5, 1, 26, 59696],
    [0, 2, 13, 54576],
    [0, 2, 3, 23200],
    [3, 1, 23, 27472],
    [0, 2, 11, 38608],
    [11, 1, 31, 19176],
    [0, 2, 19, 19152],
    [0, 2, 8, 42192],
    [6, 1, 28, 53848],
    [0, 2, 15, 53840],
    [0, 2, 4, 54560],
    [5, 1, 24, 55968],
    [0, 2, 12, 46496],
    [0, 2, 1, 22224],
    [2, 1, 22, 19160],
    [0, 2, 10, 18864],
    [7, 1, 30, 42168],
    [0, 2, 17, 42160],
    [0, 2, 6, 43600],
    [5, 1, 26, 46376],
    [0, 2, 14, 27936],
    [0, 2, 2, 44448],
    [3, 1, 23, 21936],
    [0, 2, 11, 37744],
    [8, 2, 1, 18808],
    [0, 2, 19, 18800],
    [0, 2, 8, 25776],
    [6, 1, 28, 27216],
    [0, 2, 15, 59984],
    [0, 2, 4, 27296],
    [4, 1, 24, 43872],
    [0, 2, 12, 43744],
    [0, 2, 2, 37600],
    [3, 1, 21, 51568],
    [0, 2, 9, 51552],
    [7, 1, 29, 54440],
    [0, 2, 17, 54432],
    [0, 2, 5, 55888],
    [5, 1, 26, 23208],
    [0, 2, 14, 22176],
    [0, 2, 3, 42704],
    [4, 1, 23, 21224],
    [0, 2, 11, 21200],
    [8, 1, 31, 43352],
    [0, 2, 19, 43344],
    [0, 2, 7, 46240],
    [6, 1, 27, 46416],
    [0, 2, 15, 44368],
    [0, 2, 5, 21920],
    [4, 1, 24, 42448],
    [0, 2, 12, 42416],
    [0, 2, 2, 21168],
    [3, 1, 22, 43320],
    [0, 2, 9, 26928],
    [7, 1, 29, 29336],
    [0, 2, 17, 27296],
    [0, 2, 6, 44368],
    [5, 1, 26, 19880],
    [0, 2, 14, 19296],
    [0, 2, 3, 42352],
    [4, 1, 24, 21104],
    [0, 2, 10, 53600],
    [8, 1, 30, 59696],
    [0, 2, 18, 54560],
    [0, 2, 7, 55968],
    [6, 1, 27, 27472],
    [0, 2, 15, 22224],
    [0, 2, 5, 19168],
    [4, 1, 25, 42216],
    [0, 2, 12, 41680],
    [0, 2, 1, 53584],
    [2, 1, 21, 55592],
    [0, 2, 9, 54560],
];

function GregorianIsLeapYear(y) {
    if ((y % 4) != 0) {
        return false;
    }
    if ((y % 100) != 0) {
        return true;
    }
    return (y % 400) == 0;
}

function GetYearInfo(lunarYear, index) {
    if (lunarYear < MinLunisolarYear || lunarYear > MaxLunisolarYear) {
        throw new Error("year");
    }
    return s_yinfo[lunarYear - MinLunisolarYear][index];
}
function CheckTicksRange(ticks) {
    if (ticks < MinValue.Ticks || ticks > MaxValue.Ticks) {
        throw new Error("time");
    }
}
function GregorianToLunar(solarYear, solarMonth, solarDate) {
    var outData = { lunarYear: 0, lunarMonth: 0, lunarDate: 0 };
    var isLeapYear = GregorianIsLeapYear(solarYear);
    var jan1Month;
    var jan1Date;
    var solarDay = isLeapYear ? s_daysToMonth366[solarMonth - 1] : s_daysToMonth365[solarMonth - 1];
    solarDay += solarDate;
    var lunarDay = solarDay;
    outData.lunarYear = solarYear;
    if (outData.lunarYear == (MaxLunisolarYear + 1)) {
        outData.lunarYear--;
        lunarDay += (GregorianIsLeapYear(outData.lunarYear) ? 366 : 365);
        jan1Month = GetYearInfo(outData.lunarYear, Jan1Month);
        jan1Date = GetYearInfo(outData.lunarYear, Jan1Date);
    }
    else {
        jan1Month = GetYearInfo(outData.lunarYear, Jan1Month);
        jan1Date = GetYearInfo(outData.lunarYear, Jan1Date);
        if ((solarMonth < jan1Month) ||
            (solarMonth == jan1Month && solarDate < jan1Date)) {
            outData.lunarYear--;
            lunarDay += (GregorianIsLeapYear(outData.lunarYear) ? 366 : 365);
            jan1Month = GetYearInfo(outData.lunarYear, Jan1Month);
            jan1Date = GetYearInfo(outData.lunarYear, Jan1Date);
        }
    }
    lunarDay -= s_daysToMonth365[jan1Month - 1];
    lunarDay -= (jan1Date - 1);
    var mask = 0x8000;
    var yearInfo = GetYearInfo(outData.lunarYear, nDaysPerMonth);
    var days = ((yearInfo & mask) != 0) ? 30 : 29;
    outData.lunarMonth = 1;
    while (lunarDay > days) {
        lunarDay -= days;
        outData.lunarMonth++;
        mask >>= 1;
        days = ((yearInfo & mask) != 0) ? 30 : 29;
    }
    outData.lunarDate = lunarDay;
    return outData;
}
function TimeToLunar(time) {
    var gregorianCalendar = new GregorianCalendar();
    var gy = gregorianCalendar.GetYear(time);
    var gm = gregorianCalendar.GetMonth(time);
    var gd = gregorianCalendar.GetDayOfMonth(time);
    var ad = GregorianToLunar(gy, gm, gd);
    return {
        year: ad.lunarYear
    };
}
function GetSexagenaryYear(time) {
    CheckTicksRange(time.Ticks);
    var x = TimeToLunar(time);
    return ((x.year - 4) % 60) + 1;
}
function GetTerrestrialBranch(sexagenaryYear) {
    if (sexagenaryYear < 1 || sexagenaryYear > 60) {
        throw new Error("sexagenaryYear");
    }
    return ((sexagenaryYear - 1) % 12) + 1;
}
function ChineseZodiac(date) {
    var dotNetDate = DotNetDateTime.fromJsDate(date);
    var sexagenaryYear = GetSexagenaryYear(dotNetDate);
    var terrestrialBranch = GetTerrestrialBranch(sexagenaryYear);
    var years = ["Rat", "Ox", "Tiger", "Rabbit", "Dragon", "Snake", "Horse", "Goat", "Monkey", "Rooster", "Dog", "Pig"];
    return years[terrestrialBranch - 1];
}
exports.ChineseZodiac = ChineseZodiac;

测试:

var exports = {};
// [copy-pasting above code]
exports.ChineseZodiac(new Date(1970,0,1))
exports.ChineseZodiac(new Date(2021,0,1))
exports.ChineseZodiac(new Date(2022,0,1))

all 返回与 dotnet 相同的值。

于 2012-12-13T08:57:16.303 回答
4

通过使用计算器

2013-4=2009
2009/12= 167.41666
167*12=2004
2009-2004=5 (5 is snake which was the animal for 2013)
于 2014-02-26T16:49:21.000 回答
2

用它来计算年份。

<?php

$year = 2013;
    switch (($year - 4) % 12) {
        case  0: $zodiac = 'Rat';       break;
        case  1: $zodiac = 'Ox';            break;
        case  2: $zodiac = 'Tiger';     break;
        case  3: $zodiac = 'Rabbit';    break;
        case  4: $zodiac = 'Dragon';    break;
        case  5: $zodiac = 'Snake';     break;
        case  6: $zodiac = 'Horse';     break;
        case  7: $zodiac = 'Goat';  break;
        case  8: $zodiac = 'Monkey';    break;
        case  9: $zodiac = 'Rooster';   break;
        case 10: $zodiac = 'Dog';   break;
        case 11: $zodiac = 'Pig';   break;
    }
    echo "{$year} is the year of the {$zodiac}.<br />";


?>
于 2014-02-26T16:45:06.367 回答
1

如果您真的想找到一种非表格机制来计算中国十二生肖的年份,那么我建议您查看具有 (LISP) 代码来处理农历新年的“日历计算,第三版” ,并从中, 推断 <相关动物>的年份是直截了当的。那本书涵盖了许多历法系统,读起来很有趣。农历是阴阳历,比较复杂;数学变得非常详细。

不过,使用表格可能更简单,也可能更紧凑,代码方面。

于 2012-05-01T18:43:02.510 回答
1

维基百科引用了 2044。

http://en.wikipedia.org/wiki/Chinese_zodiac

以鼠年为例(1984 年之后的几年),看起来鼠周期如下:

383, 353, 353, 383, 354 days

请注意,最后一个周期354很可能是由于闰年。也许使用这个公式,你可以计算出任何一年到 2100 年左右。

我用以T-SQL下来推断这些数字

select DATEDIFF(D,'02/2/1984', '02/19/1985')
select DATEDIFF(D,'02/19/1996', '02/6/1997')
select DATEDIFF(D,'02/7/2008', '01/25/2009')
select DATEDIFF(D,'01/25/2020', '02/11/2021')
select DATEDIFF(D,'02/11/2032', '01/30/2033')
于 2012-05-01T18:15:09.433 回答
0

总是有一个问题,什么是更快的测试和验证。

在 calculla 上开发生肖计算器时,我们决定使用查找表——因为这比实际测试任何算法更快、更方便(即使算法可能很简单,你仍然需要时间来测试它)。

这个查找不是一个大表,您实际上可以从我们网站的源代码中获取 javascript 代码。

于 2015-01-11T13:23:04.693 回答
0
Public Function ChineseSign(ByVal DoB As Date) As String

    Dim CSign As String = ""
    Dim YearSign As New Short
    YearSign = Year(DoB) Mod 12

    '// Uncomment the following to use Feb 12th as New Year calculation //
    'If Month(DoB) = 1 Then
    'YearSign = YearSign - 1
    'If YearSign = 0 Then YearSign = 12
    'ElseIf Month(DoB) = 2 And DoB.Day < 12 Then
    'YearSign = YearSign - 1
    'If YearSign = 0 Then YearSign = 12
    'End If

    Select Case YearSign
        Case 1
            CSign = "Rooster"
        Case 2
            CSign = "Dog"
        Case 3
            CSign = "Pig (Boar)"
        Case 4
            CSign = "Rat"
        Case 5
            CSign = "Ox"
        Case 6
            CSign = "Tiger"
        Case 7
            CSign = "Rabbit"
        Case 8
            CSign = "Dragon"
        Case 9
            CSign = "Snake"
        Case 10
            CSign = "Horse"
        Case 11
            CSign = "Goat"
        Case 12
            CSign = "Monkey"
    End Select

    Select Case CSign
        Case "Ox"
            Return "an " & CSign
        Case Else
            Return "a " & CSign
    End Select

End Function
于 2020-04-20T00:58:57.833 回答
0

首先,您必须创建一个完全如下的星座数组

DECLARE sign : [array(1.....12)]
DECLARE year : INTEGER
sign(1) ← "Rat"
sign(2) ← "Ox"
sign(3) ← "Tiger"
sign(4) ← "Rabbit"
sign(5) ← "Dragon"
sign(6) ← "Snake"
sign(7) ← "Horse"
sign(8) ← "Goat"
sign(9) ← "Monkey"
sign(10) ← "Rooster"
sign(11) ← "Dog"
sign(12) ← "Pig" 
DECLARE X, Y, N : INTEGER
X ← (year - 4)
Y ← (X DIV 12) // DIV return only the natural number
Y ← (Y * 12)
N ← N + 1
OUTPUT sign(N)
于 2018-12-25T12:12:35.063 回答