diff --git a/CHANGELOG.md b/CHANGELOG.md index 66091e7..da47150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,3 +38,9 @@ ## [1.1.2] - 2024-08-19 1. 优化:十神计算逻辑。 2. 修复:获取起运时间报错的问题。 + +## [1.1.3] - 2024-10-04 +1. 优化:代码。 +2. 修复:吉神宜趋、凶神宜忌错误。 +3. 新增:Lunar的2种起运流派。 +4. 新增:支持八字晚子时日柱算当天。 diff --git a/src/culture/God.php b/src/culture/God.php index f2b697b..f5da79d 100644 --- a/src/culture/God.php +++ b/src/culture/God.php @@ -22,8 +22,8 @@ class God extends LoopTyme ';000A00220362463C44;010B00072128291D334F50645D;02360002230605534855423F59;03000212300F24060568695A;0400042E27342A495C403C8C;050C04184A5E6B3E66788D76;06091A1B2B15014C4D4E;07352D321C14175B636151526577;0811130E16080147546C433C6A3D5F;0920070D190801563D60;0A0A032C2F104541;0B0B252631031E1F57584B3E;0C362203056246717B3C3F6D44;0D072128291D334F50645D;0E020423065348554259;0F00020C0412300F240668696E5A;1009002E12342A495C403C;113500184A5E6B3E66;12001A1B2B15014C4D4E;13002D321C14175B63615152656D77;140A11130E0316080147546C433C6F6A3D5F;150B20070D03190801563D60;1636032C2F104541733F;17252631031E1F5758727B4B3E;1804220362463C44;190C04072128291D334F50645D;1A09022306055348554259;1B3502120D0F24060568695A;1C2E27342A495C403C;1D184A5E6B3E66;1E0A381A1B2B15014C4D4E;1F0B2D321C14175B63615152657F;20363711130E0316080147546C433C6A3F3D5F;2120070D03190801563D60;2204032C2F104541;230C042526311E1F57584B3E;2409220562463C44;2535072128291D334F50645D;26022306055348554259;270212300F24060568695A;280A2E27342A495C403C6F;290B184A5E6B3E66;2A361A1B2B15014C4D4E3F81;2B2D321C14175B6361515265678074;2C0411130E03160847546C433C6A3D5F;2D000C0420070D190801566E3D60;2E09002C2F104541;2F35002526311E1F57584B3E;300022056246703C44;3100072128291D334F50645D676D;320A02230605534855426759;330B02120D0F2406056869755A;34362E27342A495C403C3F;35184A5E6B3E6676;36041A1B2B154C4D4E81;370C042D321C14175B6361515265677774;380911130E16080147546C433C6A3D675F;393520070D190801563D60;3A2C2F104541;3B2526311E1F5758704B3E87;', ';00001D2F10575868694F503C;0100122B1F495C5564;0209000207222829140605655D44;03000216063305474C4D4E51526A4B3F;04000C042E300F193C6159;0504182C43403E5A;06271A1E2A014A5E6B6C5B6342;070B2D1B1366;080A112526321C0815013C3D;0920032308170153546246413D;0A07210D310324565F;0B0E033448453E60;0C091D2F1005575868694F50717B3C6D;0D122B1F495C553F;0E020C04072228291406655D44;0F000204160633474C4D4E51526A4B;10002E300F193C6159;110B00182C43403E5A;120A00271A1E2A014A5E6B6C5B6342;13002D1B13036D66;14112526321C030815013C6F3D;1520032308170153546246413D;160907210D31032456735F;170E344845727B3F3E60;180C041D2F10575868694F503C;1904122B1F495C5564;1A0207222829140605655D44;1B0B0216063305474C4D4E51526A4B;1C0A2E300F193C6159;1D182C43403E5A;1E38271A1E2A014A5E6B6C5B6342;1F2D1B130366;2009112526321C030815013C3D;21202308170153546246413F3D;220C0407210D3103565F;23040E3448453E60;241D2F1005575868694F503C;250B122B1F495C5564;260A0207222829140605655D44;270216063305474C4D4E51526A4B;282E300F193C6F616E59;29182C43403E5A;2A09271A1E2A014A5E6B6C5B63427988;2B372D1B133F6766;2C0C04112526321C0308153C3D;2D0004202308170153546246413D;2E0007210D3124565F;2F0B000E3448453E60;300A001D2F1005575868694F50703C89;3100122B1F495C5564676D;320207222829140605655D6744;330216063305474C4D4E7551526A4B;34092E300F193C6159;35182C43403F3E5A;360904271A1E2A4A5E6B6C5B634278;37042D1B136766;38112526321C0815013C3D67;390B202308170153546246413D;3A0A07210D3124566E5F;3B0E03344845703E60;', ';003509001E2F554C4D4E453C51525D5F;010057586C646160;0200020E06100543;0300020721282923061F0565;0400042E2224533C7344;05360B04182526300F34335B633F3E74;060A1A13016246404B59;070C2D2B4A5E6B5A;0827111B0314082A0148413C3D;0920321C310316080148413C3D;0A35090319154754495C42;0B12070D1D2C174F50563E;0C1E2F05554C4D4E45717B3C51525D6D5F;0D57586C646160;0E02040E061043;0F360B0002040721282923061F653F;100A002E2224533C44;11000C182526300F34335B633E;12001A1303016246404B59;13002D032B4A5E6B6D5A;14350927111B0314082A0148413C6F3D;1520321C310316080168696A3D66;1619154754495C426E;1712070D1D2C174F5056727B3E;18041E2F554C4D4E453C51525D5F;19360B0457586C64613F60;1A0A020E06100543;1B020C0721282923061F0565;1C2E2224533C44;1D182526300F34335B633E;1E3509381A1303016246404B59;1F2D032B4A5E6B5A;2027111B14082A0148413C3D;2120321C3116080168696A3D66;22040319154754495C42;23360B0412070D1D2C174F50563F3E;240A1E2F05554C4D4E453C51525D5F;250C57586C646160;26020E06100543;27020721282923061F0565;2835092E2224533C6F44;29182526300F34335B633E;2A1A13016246404B5982;2B2D2B4A5E6B675A76;2C0427111B0314082A48413C3D;2D360B000420321C3116080168696A3F3D66;2E0A0019154754495C42;2F000C12070D1D2C174F50563E;30001E2F05554C4D4E45703C51525D5F;310057586C6461676D608E;323509020E0610054367;33020721282923061F057565;342E2224533C6E44;35182526300F34335B633E7974;3637041A13036246404B5982;37360B042D2B4A5E6B3F675A76;380A27111B14082A0148413C3D67;390C20321C3116080168696A3D66;3A0319154754495C42;3B12070D1D2C174F5056703E;', - ';0000302007210D341556;01000217455D;020A0025262B2F060557586C5F;030B001406056246603C8F;0436000207282916105B6364656A;0537130E191F47483E;0622300F2C0168693F44;07021E33495C40413C;08090C04184A5E423D59;093504121A1B0308014C4D4E51524B3D5A;0A02272D321C1D232A4F507E61;0B1124535455433E66;0C0A2E2007210D341505566D;0D0B0217455D;0E3625262B2F0657586C;0F00140662463C4260;10000207282916105B6364656A3F79;1100130E191F47483E;1209350C0422300F032C01686944;1335000204031E33495C40413C6D;1418310308014A5E6B3D59;15121A1B0308014C4D4E51524B3D5A;160B1124535455433C6F6E3E66;17362E2007210D341556;180217455D;1925262B060557586C3F5F;1A14060562463C4260;1B09020C0407282916105B6364656A;1C3504130E03191F47483E;1D22300F032C01686944;1E02031E495C40413C;1F0A183108014A5E6B3D59;200B121A1B08014C4D4E51524B3D5A;213602272D321C1D232A4F507E61;221124535455433C3E66;232E2007210D34150556717C3F;24021745735D;25090C0425262B2F060557586C5F;26350414060562463C4260;270207282916105B6364656A74;28130E03191F47483E;290A22300F2C01686944;2A0B021E33495C40413C6F67;2B36381831034A5E6B3D59;2C00121A1B08014C4D4E51524B3D5A;2D0002272D321C1D232A4F507E613F;2E00112453545543727C3C3E66;2F09000C042E2007210D34150556;303500020417455D676D;3125262B2F060557586C70675F;321406056246703C426084;330A0207282916105B6364656A;340B130E191F47486E3E;353622300F032C7544;36021E33495C40413C67;37183108014A5E6B3F3D675976;38121A1B08014C4D4E51524B3D5A;3909020C04272D321C1D232A4F507E61;3A35041124535455433C3E66;3B0A002E27202C2A475462464B;', - ';000B0002070D1E5666;01002F06150548456E5D;0200061705575868695B633C;030002130323495C645F;0407212829249060;0509341001534C4D4E415152;060212300F31031F3C61423F;070418220E032B080143403D44;080C041A1D14080833014A5E6B6C4F503D;090A022D1B16556A59;0A0B112526321C193C653E5A;0B2E27202C2A05475462464B6D;0C02070D1E5666;0D2F061548455D;0E000617575868695B633C85;0F090002371323495C645F;10000721282903243F3E60;11000403341001534C4D4E415152;1200020C0412300F31031F3C61426D;130A18220E032B080143403D44;140B1A1D140833014A5E6B6C4F503D;15022D1B16556A59;16112526321C193C6F653E5A;172E27202C2A475462464B;1802070D1E5666;19092F06150548455D;1A061705575868695B633C3F79;1B0204130323495C645F;1C0C040721282903243E60;1D0A03341001534C4D4E415152;1E0B0227300F311F3C6142;1F18220E2B080143406E3D44;201A1D140833014A5E6B6C4F503D;210A02272D321C1D232A4F507E61;22022D1B16556A59;23112526321C193C653E5A;24092E27202C2A0547546246717C4B;2502070D1E56733F66;26042F06150548455D;270C04061705575868695B633C;280A02130323495C645F;290B07212829243E60;2A341001534C4D4E415152;2B0212300F311F3C6F614267;2C3818220E032B0843403D44;2D001A1D140833014A5E6B5B4F503D78;2E0900022D1B16556A59;2F00112526321C19727C3C653F3E5A;3000042E27202C2A05475462464B;3100020C04070D1E56676D66;320A2F0615054845705D67;330B061705575868695B63703C74;34021323495C645F;3507212829243E60;36033410534C4D4E41755152;370212300F311F3C614267;380918220E2B080143403D6744;391A1D140833014A5E6B6C4F503F3D76;3A02042D1B16556A59;3B0C04112526321C193C653E5A;', + ';0000302007210D341556;01000217455D;020A0025262B2F060557586C5F;030B001406056246603C8F;0436000207282916105B6364656A;0537130E191F47483E;0622300F2C0168693F44;07021E33495C40413C;08090C04184A5E423D59;093504121A1B0308014C4D4E51524B3D5A;0A02272D321C1D232A4F507E61;0B1124535455433E66;0C0A2E2007210D341505566D;0D0B0217455D;0E3625262B2F0657586C;0F00140662463C4260;10000207282916105B6364656A3F79;1100130E191F47483E;1209350C0422300F032C01686944;1335000204031E33495C40413C6D;1418310308014A5E6B3D59;15121A1B0308014C4D4E51524B3D5A;160A02272D321C1D232A4F507E61;170B1124535455433C6F6E3E66;18362E2007210D341556;190217455D;1A25262B060557586C3F5F;1B14060562463C4260;1C09020C0407282916105B6364656A;1D3504130E03191F47483E;1E22300F032C01686944;1F02031E495C40413C;200A183108014A5E6B3D59;210B121A1B08014C4D4E51524B3D5A;223602272D321C1D232A4F507E61;231124535455433C3E66;242E2007210D34150556717C3F;25021745735D;26090C0425262B2F060557586C5F;27350414060562463C4260;280207282916105B6364656A74;29130E03191F47483E;2A0A22300F2C01686944;2B0B021E33495C40413C6F67;2C36381831034A5E6B3D59;2D00121A1B08014C4D4E51524B3D5A;2E0002272D321C1D232A4F507E613F;2F00112453545543727C3C3E66;3009000C042E2007210D34150556;313500020417455D676D;3225262B2F060557586C70675F;331406056246703C426084;340A0207282916105B6364656A;350B130E191F47486E3E;363622300F032C7544;37021E33495C40413C67;38183108014A5E6B3F3D675976;39121A1B08014C4D4E51524B3D5A;3A09020C04272D321C1D232A4F507E61;3B35041124535455433C3E66;', + ';000A002E27202C2A475462464B;010B0002070D1E5666;02002F06150548456E5D;0300061705575868695B633C;040002130323495C645F;0507212829249060;0609341001534C4D4E415152;070212300F31031F3C61423F;080418220E032B080143403D44;090C041A1D14080833014A5E6B6C4F503D;0A0A022D1B16556A59;0B0B112526321C193C653E5A;0C2E27202C2A05475462464B6D;0D02070D1E5666;0E2F061548455D;0F000617575868695B633C85;10090002371323495C645F;11000721282903243F3E60;12000403341001534C4D4E415152;1300020C0412300F31031F3C61426D;140A18220E032B080143403D44;150B1A1D140833014A5E6B6C4F503D;16022D1B16556A59;17112526321C193C6F653E5A;182E27202C2A475462464B;1902070D1E5666;1A092F06150548455D;1B061705575868695B633C3F79;1C0204130323495C645F;1D0C040721282903243E60;1E0A03341001534C4D4E415152;1F0B0227300F311F3C6142;2018220E2B080143406E3D44;211A1D140833014A5E6B6C4F503D;22022D1B16556A59;23112526321C193C653E5A;24092E27202C2A0547546246717C4B;2502070D1E56733F66;26042F06150548455D;270C04061705575868695B633C;280A02130323495C645F;290B07212829243E60;2A341001534C4D4E415152;2B0212300F311F3C6F614267;2C3818220E032B0843403D44;2D001A1D140833014A5E6B5B4F503D78;2E0900022D1B16556A59;2F00112526321C19727C3C653F3E5A;3000042E27202C2A05475462464B;3100020C04070D1E56676D66;320A2F0615054845705D67;330B061705575868695B63703C74;34021323495C645F;3507212829243E60;36033410534C4D4E41755152;370212300F311F3C614267;380918220E2B080143403D6744;391A1D140833014A5E6B6C4F503F3D76;3A02042D1B16556A59;3B0C04112526321C193C653E5A;', ';00002E20391C246869655D59;010002345354495C5A;023509002707210D062A055B6356515277;0300132B06054C4D4E453C66;04000203142F1557586473614B3F;0512161743416A3E;060C072829310319015F;07360B02032C476C3C6E60;080A04182526300F1D1E0810014F503D;09041A081F01556246403D;0A022D224A5E6B4486;0B111B0E2333483C423E;0C35092E20321C24056869655D6D59;0D02345354495C5A;0E2707210D062A5B635651523F77;0F00132B064C4D4E453C66;1000020C03142F15575864614B;11360B001203161743416A3E;120A0004072829310319015F;13000204032C476C3C6D60;14182526300F1D1E0810014F503D;151A081F01556246403D;163509022D224A5E6B44;17111B0E2333483C6F423E;182E20321C246869655D3F59;1902345354495C5A;1A0C2707210D062A055B635651527F;1B360B3713032B06054C4D4E453C66;1C0A020403142F15575864614B;1D041203161743416A3E;1E0728293119015F;1F022C476C3C60;203509182526300F1D1E08104F503D;211A081F01556246403D;22022D224A5E6B3F447891;23111B0E2333483C423E;240C2E20321C24056869717C655D59;25360B021C5354495C6E5A;260A042707210D062A055B6356515280;270413032B06054C4D4E453C66;2802142F15575864614B;2912161743416A3E;2A35090728293119015F;2B022C476C3C6F6760;2C38182526300F1D1E08104F503F3D;2D001A081F01556246403D;2E0002092D224A5E6B4476;2F360B00111B0E233348727C3C423E;300A00042E20321C24056869655D59;31000204345354495C676D5A;322707210D062A055B6356705152677774;33132B06054C4D4E45703C66;34350902142F15575864614B;3512161743416A3E;36072829310319753F5F;37022C476C3C6760;380C182526300F1D1E0810014F503D67;39360B1A081F01556246403D;3A0A02042D224A5E6B44;3B04111B0E2333483C423E;', ';00090038041A221B194C4D4E44;0135000C042D321C2C335B6361655D77;02002E11130E1E06054754433C59;03001220070D0605565A;0400272F2A454142;050B252631032357583E66;06360A0324150162463C;07072128291D34174F50644B;080208015348553F3D5F;0902300F2B080168693D60;0A09041410495C403C6F;0B35090418161F4A5E6B6C5152403E;0C1A221B19054C4D4E6D44;0D2D321C2C335B6361655D77;0E2E11130E1E064754433C6E59;0F0B351220070D0306565A;10360A0027032F2A454142;1100252631032357583E66;12000324150162463C3F;1300072128291D34174F50644B6D;1409020408015348553D5F;1535020C04300F2B080168693D60;161410495C403C;1718161F4A5E6B6C51526A3E;181A221B194C4D4E4481;190B0A2E11130E031E06054754433C59;1A360A2E11130E031E06054754433C59;1B1220070D030605565A;1C27032F2A454173423F;1D252631032357583E66;1E090424150162463C;1F350C04072128291D34174F50644B;200208015348553D5F;2102300F2B080168693D60;221410495C403C92;230B18161F4A5E6B6C51526A3E7893;24360A1A221B19054C4D4E44;252D321C2C335B6361655D7F;26372E11130E031E06054754433C3F59;271220070D030605565A;280904272F2A454142;29350C042526312357583E66;2A2415016246703C;2B072128291D34174F50644B67;2C02085348556E3D5F;2D090002300F2B080168693D60;2E360A001410495C403C;2F0018161F4A5E6B6C51526A3E;30001A221B19054C4D4E717D3F4481;31002D321C2C335B6361655D676D8074;3209042E11130E1E06054754433C6F6759;33350C042720070D0605565A;34272F2A454142;35252631235758703E6687;36241562463C;370B072128291D34174F50644B67;38360A023A015348553D675F;3902300F2B08016869753D60;3A1410495C403C3F;3B18161F4A5E6B6C727D51526A3E76;', ';0000380C041A23104A5E6B5B63;010004122D1B13241F838A;020A002E11252622321C3406053C5D44;030B00200306330553544641;040007210D312B5659;050E031448453E5A;060E1D162F2A01575868694F503C6A;0719495C556466;0809020728292C081501515242653D;09021E081701474C4D4E3F3D;0A0C04300F3C6F614B5F;0B041843403E60;0C0A1A2310054A5E6B5B636D;0D0B122D1B1303241F838A94;0E2E11252622321C34063C5D44;0F002003063353546C624641;100007210D31032B5659;11000E031448453E5A;120900271D162F2A01575868694F503C6A;130019495C55643F6D66;14020C040728292C081501515242653D;1502041E081701474C4D4E3D;160A300F3C614B5F;170B1843403E60;181A23104A456B5B6378;19122D1B1303241F9583;1A2E11252622321C033406053C5D44;1B200306330553546C6246416E;1C0907210D31032B567359;1D0E1448453F3E5A;1E0C04271D163B2A01575868694F503C6A;1F0419495C556466;200A020728292C081501515242653D;210B021E081701474C4D4E3D;22300F3C614B5F;231843403E60;241A2310054A5E425B63;25122D1B1303241F;26092E11252622321C033406053C5D44;272006330553546C6246413F;280C0407210D312B5659;29040E1448453E5A;2A0A271D162F2A01575868694F50703C6A89;2B0B19495C55646766;2C020728292C0815515242653D;2D00021E081701474C4D4E3D;2E00300F3C614B5F;2F001843403E60;3009001A2310054A5E6B5B63717D7988;310037122D1B13241F3F676D;320C042E11252622321C3406053C6F5D6744;33042006330553546C624641;340A07210D312B5659;350B0E03144845703E5A;36271D162F2A575868694F503C6A;3719495C55646766;38020728292C081501515242653D67;39021E081701474C4D4E756E3D;3A09300F3C614B5F;3B184340727D3F3E60;', diff --git a/src/culture/Taboo.php b/src/culture/Taboo.php index a0dc551..e763249 100644 --- a/src/culture/Taboo.php +++ b/src/culture/Taboo.php @@ -84,6 +84,24 @@ function getLuck(): Luck return Luck::fromIndex($this->index < 60 ? 0 : 1); } + /** + * 宜忌 + * @param string[] $data 数据 + * @param int $supIndex 主下标 + * @param int $subIndex 次下标 + * @param int $index 宜忌下标 + * @return Taboo[] 宜忌列表 + */ + private static function getTaboos(array $data, int $supIndex, int $subIndex, int $index): array + { + $l = array(); + $d = explode(',', explode(';', $data[$supIndex])[$subIndex])[$index]; + for ($i = 0, $j = strlen($d); $i < $j; $i += 2) { + $l[] = static::fromIndex(hexdec(substr($d, $i, 2))); + } + return $l; + } + /** * 日宜 * @param SixtyCycle $month 月干支 @@ -92,12 +110,7 @@ function getLuck(): Luck */ static function getDayRecommends(SixtyCycle $month, SixtyCycle $day): array { - $l = array(); - $data = explode(',', explode(';', static::$dayTaboo[$month->getEarthBranch()->getIndex()])[$day->getIndex()])[0]; - for ($i = 0, $j = strlen($data); $i < $j; $i += 2) { - $l[] = static::fromIndex(hexdec(substr($data, $i, 2))); - } - return $l; + return self::getTaboos(static::$dayTaboo, $month->getEarthBranch()->getIndex(), $day->getIndex(), 0); } /** @@ -108,12 +121,7 @@ static function getDayRecommends(SixtyCycle $month, SixtyCycle $day): array */ static function getDayAvoids(SixtyCycle $month, SixtyCycle $day): array { - $l = array(); - $data = explode(',', explode(';', static::$dayTaboo[$month->getEarthBranch()->getIndex()])[$day->getIndex()])[1]; - for ($i = 0, $j = strlen($data); $i < $j; $i += 2) { - $l[] = static::fromIndex(hexdec(substr($data, $i, 2))); - } - return $l; + return self::getTaboos(static::$dayTaboo, $month->getEarthBranch()->getIndex(), $day->getIndex(), 1); } /** @@ -124,12 +132,7 @@ static function getDayAvoids(SixtyCycle $month, SixtyCycle $day): array */ static function getHourRecommends(SixtyCycle $day, SixtyCycle $hour): array { - $l = array(); - $data = explode(',', explode(';', static::$hourTaboo[$hour->getEarthBranch()->getIndex()])[$day->getIndex()])[0]; - for ($i = 0, $j = strlen($data); $i < $j; $i += 2) { - $l[] = static::fromIndex(hexdec(substr($data, $i, 2))); - } - return $l; + return self::getTaboos(static::$hourTaboo, $hour->getEarthBranch()->getIndex(), $day->getIndex(), 0); } /** @@ -140,11 +143,6 @@ static function getHourRecommends(SixtyCycle $day, SixtyCycle $hour): array */ static function getHourAvoids(SixtyCycle $day, SixtyCycle $hour): array { - $l = array(); - $data = explode(',', explode(';', static::$hourTaboo[$hour->getEarthBranch()->getIndex()])[$day->getIndex()])[1]; - for ($i = 0, $j = strlen($data); $i < $j; $i += 2) { - $l[] = static::fromIndex(hexdec(substr($data, $i, 2))); - } - return $l; + return self::getTaboos(static::$hourTaboo, $hour->getEarthBranch()->getIndex(), $day->getIndex(), 1); } } diff --git a/src/culture/fetus/FetusDay.php b/src/culture/fetus/FetusDay.php index aaf39c7..2580d36 100644 --- a/src/culture/fetus/FetusDay.php +++ b/src/culture/fetus/FetusDay.php @@ -81,7 +81,7 @@ function getName(): string /** * 内外 * - * @return Side 侧 + * @return Side 内外 */ function getSide(): Side { diff --git a/src/eightchar/ChildLimit.php b/src/eightchar/ChildLimit.php index 51252ac..1e973c9 100644 --- a/src/eightchar/ChildLimit.php +++ b/src/eightchar/ChildLimit.php @@ -20,6 +20,7 @@ class ChildLimit * @var ChildLimitProvider|null 童限计算接口 */ static ?ChildLimitProvider $provider = null; + /** * @var EightChar 八字 */ diff --git a/src/eightchar/provider/EightCharProvider.php b/src/eightchar/provider/EightCharProvider.php new file mode 100644 index 0000000..1ab0b80 --- /dev/null +++ b/src/eightchar/provider/EightCharProvider.php @@ -0,0 +1,22 @@ +getDay() + $addDay; + $h = $birthTime->getHour() + $addHour; + $mi = $birthTime->getMinute() + $addMinute; + $s = $birthTime->getSecond() + $addSecond; + $mi += intdiv($s, 60); + $s %= 60; + $h += intdiv($mi, 60); + $mi %= 60; + $d += intdiv($h, 24); + $h %= 24; + + $sm = SolarMonth::fromYm($birthTime->getYear() + $addYear, $birthTime->getMonth())->next($addMonth); + + $dc = $sm->getDayCount(); + while ($d > $dc) { + $d -= $dc; + $sm = $sm->next(1); + $dc = $sm->getDayCount(); + } + + return new ChildLimitInfo($birthTime, SolarTime::fromYmdHms($sm->getYear(), $sm->getMonth(), $d, $h, $mi, $s), $addYear, $addMonth, $addDay, $addHour, $addMinute); + } +} diff --git a/src/eightchar/provider/impl/China95ChildLimitProvider.php b/src/eightchar/provider/impl/China95ChildLimitProvider.php index cb146a6..d69f612 100644 --- a/src/eightchar/provider/impl/China95ChildLimitProvider.php +++ b/src/eightchar/provider/impl/China95ChildLimitProvider.php @@ -4,8 +4,6 @@ use com\tyme\eightchar\ChildLimitInfo; -use com\tyme\eightchar\provider\ChildLimitProvider; -use com\tyme\solar\SolarMonth; use com\tyme\solar\SolarTerm; use com\tyme\solar\SolarTime; @@ -14,7 +12,7 @@ * @author 6tail * @package com\tyme\eightchar\provider\impl */ -class China95ChildLimitProvider implements ChildLimitProvider +class China95ChildLimitProvider extends AbstractChildLimitProvider { function getInfo(SolarTime $birthTime, SolarTerm $term): ChildLimitInfo { @@ -25,17 +23,6 @@ function getInfo(SolarTime $birthTime, SolarTerm $term): ChildLimitInfo $month = intdiv($minutes, 360); $minutes %= 360; $day = intdiv($minutes, 12); - - $sm = SolarMonth::fromYm($birthTime->getYear() + $year, $birthTime->getMonth())->next($month); - - $d = $birthTime->getDay() + $day; - $dc = $sm->getDayCount(); - while ($d > $dc) { - $d -= $dc; - $sm = $sm->next(1); - $dc = $sm->getDayCount(); - } - - return new ChildLimitInfo($birthTime, SolarTime::fromYmdHms($sm->getYear(), $sm->getMonth(), $d, $birthTime->getHour(), $birthTime->getMinute(), $birthTime->getSecond()), $year, $month, $day, 0, 0); + return $this->next($birthTime, $year, $month, $day, 0, 0, 0); } } diff --git a/src/eightchar/provider/impl/DefaultChildLimitProvider.php b/src/eightchar/provider/impl/DefaultChildLimitProvider.php index 0cb9e49..e5abe00 100644 --- a/src/eightchar/provider/impl/DefaultChildLimitProvider.php +++ b/src/eightchar/provider/impl/DefaultChildLimitProvider.php @@ -4,8 +4,6 @@ use com\tyme\eightchar\ChildLimitInfo; -use com\tyme\eightchar\provider\ChildLimitProvider; -use com\tyme\solar\SolarMonth; use com\tyme\solar\SolarTerm; use com\tyme\solar\SolarTime; @@ -14,7 +12,7 @@ * @author 6tail * @package com\tyme\eightchar\provider\impl */ -class DefaultChildLimitProvider implements ChildLimitProvider +class DefaultChildLimitProvider extends AbstractChildLimitProvider { function getInfo(SolarTime $birthTime, SolarTerm $term): ChildLimitInfo { @@ -34,24 +32,6 @@ function getInfo(SolarTime $birthTime, SolarTerm $term): ChildLimitInfo $seconds %= 30; // 1秒 = 2分,1秒/2=0.5秒 = 1分 $minute = $seconds * 2; - - $d = $birthTime->getDay() + $day; - $h = $birthTime->getHour() + $hour; - $mi = $birthTime->getMinute() + $minute; - $h += intdiv($mi, 60); - $mi %= 60; - $d += intdiv($h, 24); - $h %= 24; - - $sm = SolarMonth::fromYm($birthTime->getYear() + $year, $birthTime->getMonth())->next($month); - - $dc = $sm->getDayCount(); - while ($d > $dc) { - $d -= $dc; - $sm = $sm->next(1); - $dc = $sm->getDayCount(); - } - - return new ChildLimitInfo($birthTime, SolarTime::fromYmdHms($sm->getYear(), $sm->getMonth(), $d, $h, $mi, $birthTime->getSecond()), $year, $month, $day, $hour, $minute); + return $this->next($birthTime, $year, $month, $day, $hour, $minute, 0); } } diff --git a/src/eightchar/provider/impl/DefaultEightCharProvider.php b/src/eightchar/provider/impl/DefaultEightCharProvider.php new file mode 100644 index 0000000..56ad68d --- /dev/null +++ b/src/eightchar/provider/impl/DefaultEightCharProvider.php @@ -0,0 +1,24 @@ +getYearSixtyCycle(), $hour->getMonthSixtyCycle(), $hour->getDaySixtyCycle(), $hour->getSixtyCycle()); + } +} diff --git a/src/eightchar/provider/impl/LunarSect1ChildLimitProvider.php b/src/eightchar/provider/impl/LunarSect1ChildLimitProvider.php new file mode 100644 index 0000000..68e7247 --- /dev/null +++ b/src/eightchar/provider/impl/LunarSect1ChildLimitProvider.php @@ -0,0 +1,43 @@ +getJulianDay()->getSolarTime(); + $end = $termTime; + $start = $birthTime; + if ($birthTime->isAfter($termTime)) { + $end = $birthTime; + $start = $termTime; + } + $endTimeZhiIndex = ($end->getHour() == 23) ? 11 : $end->getLunarHour()->getIndexInDay(); + $startTimeZhiIndex = ($start->getHour() == 23) ? 11 : $start->getLunarHour()->getIndexInDay(); + // 时辰差 + $hourDiff = $endTimeZhiIndex - $startTimeZhiIndex; + // 天数差 + $dayDiff = $end->getSolarDay()->subtract($start->getSolarDay()); + if ($hourDiff < 0) { + $hourDiff += 12; + $dayDiff--; + } + $monthDiff = intdiv($hourDiff * 10, 30); + $month = $dayDiff * 4 + $monthDiff; + $day = $hourDiff * 10 - $monthDiff * 30; + $year = intdiv($month, 12); + $month = $month - $year * 12; + return $this->next($birthTime, $year, $month, $day, 0, 0, 0); + } +} diff --git a/src/eightchar/provider/impl/LunarSect2ChildLimitProvider.php b/src/eightchar/provider/impl/LunarSect2ChildLimitProvider.php new file mode 100644 index 0000000..4ec227d --- /dev/null +++ b/src/eightchar/provider/impl/LunarSect2ChildLimitProvider.php @@ -0,0 +1,30 @@ +getJulianDay()->getSolarTime()->subtract($birthTime)), 60); + $year = intdiv($minutes, 4320); + $minutes %= 4320; + $month = intdiv($minutes, 360); + $minutes %= 360; + $day = intdiv($minutes, 12); + $minutes %= 12; + $hour = $minutes * 2; + return $this->next($birthTime, $year, $month, $day, $hour, 0, 0); + } +} diff --git a/src/eightchar/provider/impl/LunarSect2EightCharProvider.php b/src/eightchar/provider/impl/LunarSect2EightCharProvider.php new file mode 100644 index 0000000..a575494 --- /dev/null +++ b/src/eightchar/provider/impl/LunarSect2EightCharProvider.php @@ -0,0 +1,24 @@ +getYearSixtyCycle(), $hour->getMonthSixtyCycle(), $hour->getLunarDay()->getSixtyCycle(), $hour->getSixtyCycle()); + } +} diff --git a/src/jd/JulianDay.php b/src/jd/JulianDay.php index 081c593..bb98da7 100644 --- a/src/jd/JulianDay.php +++ b/src/jd/JulianDay.php @@ -78,46 +78,7 @@ function next(int $n): static */ function getSolarDay(): SolarDay { - $d = (int)($this->day + 0.5); - $f = $this->day + 0.5 - $d; - - if ($d >= 2299161) { - $c = (int)(($d - 1867216.25) / 36524.25); - $d += 1 + $c - intdiv($c, 4); - } - $d += 1524; - $year = (int)(($d - 122.1) / 365.25); - $d -= (int)(365.25 * $year); - $month = (int)($d / 30.601); - $d -= (int)(30.601 * $month); - $day = $d; - if ($month > 13) { - $month -= 13; - $year -= 4715; - } else { - $month -= 1; - $year -= 4716; - } - $f *= 24; - $hour = (int)$f; - - $f -= $hour; - $f *= 60; - $minute = (int)$f; - - $f -= $minute; - $f *= 60; - $second = (int)(round($f)); - if ($second > 59) { - $minute++; - } - if ($minute > 59) { - $hour++; - } - if ($hour > 23) { - $day += 1; - } - return SolarDay::fromYmd($year, $month, $day); + return $this->getSolarTime()->getSolarDay(); } /** diff --git a/src/lunar/LunarHour.php b/src/lunar/LunarHour.php index 69c20bb..1ee9728 100644 --- a/src/lunar/LunarHour.php +++ b/src/lunar/LunarHour.php @@ -8,6 +8,8 @@ use com\tyme\culture\star\twelve\TwelveStar; use com\tyme\culture\Taboo; use com\tyme\eightchar\EightChar; +use com\tyme\eightchar\provider\EightCharProvider; +use com\tyme\eightchar\provider\impl\DefaultEightCharProvider; use com\tyme\sixtycycle\EarthBranch; use com\tyme\sixtycycle\HeavenStem; use com\tyme\sixtycycle\SixtyCycle; @@ -22,6 +24,11 @@ */ class LunarHour extends AbstractTyme { + /** + * @var EightCharProvider|null 八字计算接口 + */ + static ?EightCharProvider $provider = null; + /** * @var LunarDay 农历日 */ @@ -42,8 +49,16 @@ class LunarHour extends AbstractTyme */ protected int $second; + private static function init(): void + { + self::$provider = new DefaultEightCharProvider(); + } + protected function __construct(int $year, int $month, int $day, int $hour, int $minute, int $second) { + if (null == self::$provider) { + self::init(); + } if ($hour < 0 || $hour > 23) { throw new InvalidArgumentException(sprintf('illegal hour: %d', $hour)); } @@ -310,7 +325,7 @@ function getSolarTime(): SolarTime */ function getEightChar(): EightChar { - return new EightChar($this->getYearSixtyCycle(), $this->getMonthSixtyCycle(), $this->getDaySixtyCycle(), $this->getSixtyCycle()); + return self::$provider->getEightChar($this); } /** diff --git a/src/solar/SolarHalfYear.php b/src/solar/SolarHalfYear.php index b43b91a..572c4be 100644 --- a/src/solar/SolarHalfYear.php +++ b/src/solar/SolarHalfYear.php @@ -79,15 +79,16 @@ function __toString(): string function next(int $n): static { - if ($n == 0) { - return self::fromIndex($this->getYear(), $this->index); - } - $i = $this->index + $n; - $y = $this->getYear() + intdiv($i, 2); - $i %= 2; - if ($i < 0) { - $i += 2; - $y -= 1; + $i = $this->index; + $y = $this->getYear(); + if ($n != 0) { + $i += $n; + $y += intdiv($i, 2); + $i %= 2; + if ($i < 0) { + $i += 2; + $y -= 1; + } } return self::fromIndex($y, $i); } diff --git a/src/solar/SolarMonth.php b/src/solar/SolarMonth.php index 9045084..c27e3a4 100644 --- a/src/solar/SolarMonth.php +++ b/src/solar/SolarMonth.php @@ -133,15 +133,16 @@ function __toString(): string function next(int $n): SolarMonth { - if ($n == 0) { - return self::fromYm($this->getYear(), $this->month); - } - $m = $this->month + $n; - $y = $this->getYear() + intdiv($m, 12); - $m %= 12; - if ($m < 1) { - $m += 12; - $y--; + $m = $this->month; + $y = $this->getYear(); + if ($n != 0) { + $m += $n; + $y += intdiv($m, 12); + $m %= 12; + if ($m < 1) { + $m += 12; + $y--; + } } return self::fromYm($y, $m); } diff --git a/src/solar/SolarSeason.php b/src/solar/SolarSeason.php index 608c42d..f062c37 100644 --- a/src/solar/SolarSeason.php +++ b/src/solar/SolarSeason.php @@ -79,15 +79,16 @@ function __toString(): string function next(int $n): static { - if ($n == 0) { - return self::fromIndex($this->getYear(), $this->index); - } - $i = $this->index + $n; - $y = $this->getYear() + intdiv($i, 4); - $i %= 4; - if ($i < 0) { - $i += 4; - $y -= 1; + $i = $this->index; + $y = $this->getYear(); + if ($n != 0) { + $i += $n; + $y += intdiv($i, 4); + $i %= 4; + if ($i < 0) { + $i += 4; + $y -= 1; + } } return self::fromIndex($y, $i); } diff --git a/src/solar/SolarWeek.php b/src/solar/SolarWeek.php index 0558aaf..2d78d41 100644 --- a/src/solar/SolarWeek.php +++ b/src/solar/SolarWeek.php @@ -134,12 +134,10 @@ function __toString(): string function next(int $n): static { $startIndex = $this->start->getIndex(); - if ($n == 0) { - return static::fromYm($this->getYear(), $this->getMonth(), $this->index, $startIndex); - } - $d = $this->index + $n; + $d = $this->index; $m = $this->month; if ($n > 0) { + $d += $n; $weekCount = $m->getWeekCount($startIndex); while ($d >= $weekCount) { $d -= $weekCount; @@ -149,7 +147,8 @@ function next(int $n): static } $weekCount = $m->getWeekCount($startIndex); } - } else { + } else if ($n < 0) { + $d += $n; while ($d < 0) { if (!SolarDay::fromYmd($m->getYear(), $m->getMonth(), 1)->getWeek()->equals($this->start)) { $d -= 1;