光明日报记者 齐芳
未来生活会是什么样?中国科学院科技战略咨询研究院研究员冷伏海领导的科研团队,与华为公司战略研究院曹华俊等合作,建立了“面向2030年人与科技发展愿景”联合研究组,围绕人的生活、工作、健康、信息和安全5个维度,对2030年的生活图景进行了研究。相关研究结果以论文的形式发表在日前出版的《中国科学院院刊》上。
近些年来,世界主要国家、国际组织和大型高科技企业都广泛开展了面向未来的前瞻预见活动,大家都希望通过前瞻和预见,制定研发战略和计划,从而保持或塑造竞争优势。冷伏海说:“未来10—15年,是世界经济新旧动能转换及全球科技革命与产业变革的关键时期,科技发展将呈现新的态势和特征。科技进步正以空前的力量再一次改变人类生产和生活的方式:一方面,冲击着所有的产业形态并改变着全球的产业结构,推动了全球经济增长的方向;另一方面,深刻改变着人自身对衣食住行等诸多方面的需求及其满足形式,以人为本的科技进步或将成为时代的主旋律。”
冷伏海介绍,此次研究没有采取传统的专家法、趋势分析法等方法,“因为这需要投入巨大的人力、物力和时间成本”,他说,“我们的研究主要采用战略扫描、案例分析、案头研究、比较综合等方法,以发达国家对人与社会环境发展愿景与前瞻场景为参照,通过系统分析形成面向未来愿景与场景全景报告。”
其中,很多对未来的预测令人震撼。例如,研究认为,未来人类将在物理世界与数字世界的混合世界中生存。报告中说:“未来人类将进入混合世界(blendedworld),即突破物理人的生命极限,形成在物理世界和数字世界的双重公民身份,乃至形成数字国度等。为解决物理人与虚拟人之间的矛盾,人类将利用信息通信技术(ICT)将虚拟人作为未来自然人学习、能力的延伸,而不是成为虚拟人的傀儡。”
那么,在他们的描述中,2030年生活究竟是什么样呢?
生活
人类与机器共存,营造便捷、舒适的生活环境。
记者观察:
人类的生活一直在向更便利、更轻松的方向发展,不过这也给能源带来了更大压力。未来,我们能找到平衡二者的方法吗?
家居生活关键词:
低碳绿色和智能便利
智能家居。家用电器不再是简单的消费品,制造商借助传感器及时了解机器运转状态、排除故障部件、远程安装升级,进一步分析消费者的潜在需求 。
智能家居与应用程序(APP)相连,既实现人体作息规律与自然协调,又实现随时随地自主控制家居电器,从而提高人的生活舒适度。具体场景如,根据日出日落自动升降的新型百叶窗,人被阳光自然唤醒。家庭安装的智能系统根据人的活动路线、身体状况随时调整房间和用水温度。借助可穿戴技术实时监测室内居住者的心跳、血压等情况,运用机器人分析人的排泄物和体液情况,并将这些数据与医院健康管理系统相关联,从而预知疾病风险、保障人体健康。
人类与机器人等智能装备共同生活。可穿戴式智能装备消除了残疾人与正常人之间的隔阂;服务机器人承揽了从育儿到清扫的所有家务;竞技类机器人可以与人类一起打网球、篮球等;借助多语种翻译机,人们可以与世界上的任何一个人进行无障碍沟通,进而充分理解对方的文化。
消费购物。网上购物体验更加便利、贴心,消费者可网上个性化定制,借助 3D 系统模拟与实物大小一致的心仪产品,经过虚拟技术预先体验之后再正式下达订单。
居民可在家中选择“智慧农场”推出的定制服务,并通过远程系统实时看到瓜果蔬菜的种植情况、农药喷洒情况等。家用机器人可根据家人口味和现有食材自动做饭,并提前检测农药残余。
虚拟空间里的虚拟替身可以代替人独立完成购物、银行事务等简单的日常业务,极大增加私人闲暇时间。家居装修通过 3D 增强现实房间,允许顾客按自己的意愿设计生活区,然后进入空间的虚拟模型,以更好地获得其设计的直观印象。
能源生产与使用关键词:
清洁高效
公用设施能源使用。新型数字技术允许公用设施和客户之间双向通信,融合技术将降低可再生能源的储存成本;新材料将显著提高能源使用效率,提高光伏电池和核燃料电池的安全性;智能化电网可以支持配电和各种不同的发电技术。
每个公司或家庭都可通过自身的太阳能发电系统实现电力自给自足,并将富余的电力卖给电力公司。白天用电高峰的写字楼与夜晚用电高峰的娱乐中心可协调错峰用电,提高效率。
家庭能源使用。每个家庭居住空间都成为一个“能源+”的系统,可以根据居住者的需求管理热能和电;电动汽车是“能源+”的一部分,通过可控的双向充电,在家庭电力不足时可将电动汽车在行驶中产生的富余电力用于家庭用电,家庭能源系统也可以为汽车充电。
物流运输及交通关键词:
智能快捷
交通基础设施。交通基础设施将变得更加智能化,新材料和嵌入式传感器在汽车、火车、飞机和渡船等交通工具上汇聚,并利用大数据为人们提供更加安全、便利、快捷的出行。
例如,道路系统将包含动态系统,可以在行驶过程中为电动汽车充电。自动驾驶系统与全方位、无死角的道路影像预警系统相结合,及时发现诸如“行人突然进入”等危险情况并做出反应,将道路交通事故率降到最低。自主车辆和机器智能将改变大宗运输和物流的形式。自主运输技术可以提高在城市内和城市之间输送乘客和产品的效率。
个人出行。半自动或全自动商用飞机、公共汽车、出租车可为人们提供更安全的出行方式,同时减少拥堵和污染。开放共享调度数据不仅有助于人们计划行程、了解交通拥挤和延误情况,而且交通自主性正在从交通系统(如码头、轻轨)向个人行程方面扩展。
娱乐关键词:
高度逼真和五感再现
未来将出现基于脑机接口的神经游戏产品、基于生物识别分析方法用于改变机能和心理情绪状态的产品,实现高度逼真、五感(视觉、听觉、嗅觉、味觉、触觉)再现的娱乐体验。新型用户互动的大型游戏平台将持续监测用户的肌体能力和心理状态,评估用户当前活动的认知情况、生理数据等信息。基于所获得的数据,将对用户进行非侵入式刺激以实现娱乐体验。
工作
“工作”的内涵将被重新定义,人与工作的关系将改变。
记者观察:
信息技术的飞速发展已经让工作的形式、社会分工等有了很大变化。人们在享受便利的同时,也不免有些担忧:人工智能会取代人类吗?
高性能网络和海量数据
技术改变着个人与工作之间的关系,网络市场和协作工具使工作机会渠道增加,自由职业者的数量将增加。伴随新技术、网络市场和协作工具的推动,人们可以通过居家办公、卫星办公室(即分散办公的分部、分公司)等方式提高工作效率,减少出行时间。
机器人应用及人机交互
机器人产业的发展将解决老龄化社会劳动力减少的问题。语音指令将极大替代文字输入指令,从而使人们尤其是老年人更加便捷地使用智能设备。机器人将成为辅助人类生产和物流的主要工具,更多的机器人将与人类一起工作,使人类免于执行危险的工作。
先进功能材料广泛运用
多功能纳米材料的开发,使得人在极端环境中穿着简单的衣物开展工作变为可能。硬度大于钢铁但轻巧的制造材料和建筑材料,使超级隧道与建筑、超快速车辆和超强设备有望实现。常温超导材料和柔性材料将使磁悬浮列车和可折叠手机、电脑进入实用化阶段,智能材料使汽车可以自我检测并修复损伤。
远程、自动、网络化办公
居家办公、网络办公等方式减少了人们的出行,以服务低碳社会。人们可以远程操作机器人和自动化装置,完成办公事务,绿色印刷系统也将极大减少办公资源消耗。工作将通过类似“滴滴呼叫”的方式进行分配、筛选、成交、支付等,精准匹配碎片化工作需求和拥有大量闲暇时间的劳动人口。
绿色农业和水资源管理
通过绿色种植、新型农业技术实现粮食和农畜产品完全自给。普及高层建筑形式的垂直农场,计算机自动调节与管理农作物的日照量、温度等。在城市中心及建筑物周边栽培运用生物质能的水生植物,由智能系统统一调配水资源。
健康
人类预期寿命延长,先进的医疗体系可最大限度地提高老年人健康生活的独立性。
记者观察:
摆脱疾病困扰,延长健康生活时间是人类一直追求的目标。人们寄望于医疗技术等的发展,能让大家更有质量地生活。
新型医疗技术高度发达以解决疑难杂症
得益于医疗技术的发展,老年人也能够享受更高质量的生活。随着医用机器人进入实用化阶段,清洁血管、辅助肌肉运动、癌细胞靶向治疗等新技术使部分疑难杂症的治疗成为可能。
随着脑认知功能的完全揭示,大脑神经细胞修复技术得以开发,使得阿尔茨海默病、帕金森病等的治疗成为可能。人工血液的开发使得献血的必要性逐渐消失,同时随着干细胞器官再生技术实现商业化,可逐渐替代衰老和生病的人体器官。
通过使用无线药物管理器、电子包装和数字药物等工具来改进依从性监测,也可以与基于手机等智能穿戴设备相结合来提供更好的实时健康管理。
新型预防和治疗体系可有效防治疾病与传染病
未来的新型疾病防控体系应更加完善,并创设传染病“安全地带”。通过人工智能技术搭建计算机模型,准确预测传染病的传播轨迹和暴发的高风险地区,指导政府的传染病防控工作。
通过迅速准确的基因检测技术对多种疾病进行诊断及治疗,并快速、低成本地开发定制型的疫苗和制剂,惠及普通民众。利用毒性基因组学等生物技术,探究环境激素等化学物质所含的毒性与环境疾病之间的关系。
电子医疗与健康管理
借助可穿戴设备采集的数据并结合相关软件进行分析,帮助用户详细了解健康状况。运用传感器远程监控患者的健康状况,进行诊断甚至治疗、护理。
政府建立跨学科卫生中心,设立数字化专线。患者通过自动诊断系统先分析自己的测试结果,并且可以在手机和家庭监测设备上进行智能症状检查,然后再联系健康中心。高性能网络可支持不同健康任务的实施开展,如支持患者与全科医生的视频对话,以及通过数字个人助理帮助患者跟踪控制自身健康。
失能和老年人群辅助及看护
针对该类人群设计出一系列的自动化设备,如自动卫生设备、自动洁齿设备等。
借助自动监测和治疗系统,为慢性病患者定时提供在家测量和简单常规治疗等上门服务。通过智能门禁,医院判断存在相应情况时立即通知,提供上门帮助和抢救。智能娱乐和看护类机器人或自动装置可与老人对话、嬉戏,减少寂寞,还能协助保姆、护工从事重体力的看护工作,同时记录看护对象的各项生理数据,为医生修改治疗方案提供参考 。
信息
人类可以泛在、无缝、智能地获取和处理信息,并利用数据来支撑敏捷、明智的决策。
记者观察:
信息就是资源。目前我们获取信息的速度已经足够快,但准确性和信息交互过程中的安全性却无法保障,带来了很多问题。未来,我们是否能够快速、准确、安全地获取信息?
万物相连、普适计算的信息获取与处理
大量设备连接到互联网,包括移动和可穿戴设备、家用电器、医疗设备、工业探测器、监控摄像头、汽车、服装等,这些设备产生和共享大量数据并具有极高的分析利用价值。
新型传感器将所有物体与空间都通过网络连接起来,人们能够在任何时间、任何地点以任何方式进行信息获取与处理。通过生物信息与内置芯片,人们可以在购买物品时快捷结算,并获取定制型信息服务。实时分析周边的信息,为用户提供恰当的服务,让普适计算的服务惠及范围更广。
物联网、大数据背景下的信息利用与保护
物联网、数据分析和人工智能这三大技术的结合将会在全世界创造一个巨大的智能网络,在不需要人力过多干预的情况下实现巨量的商业交易。
保险服务被重新定义,传感器能对个人行为进行详细而持续地跟踪,被保险人将要求实现个性化定制的保险服务,或者被保险人通过自我评估而与保险公司共同商定应有的保险利率。
隐私保护成为新型服务并拥有广阔市场。随着物联网、大数据等新技术的应用,人们在大众面前愈加“透明”,于是人们将越发关注隐私保护问题,希望拥有“下网”空间,使个人的生活、出行信息远离各类传感器。
信息扩散与社交
运用 3D 远程交流系统和情感交流机器人,使远隔千里的家人能够随时互动交流,并且模拟对话时的表情神态和肢体动作,通过五感再现的方式使对方能更加真实地传递感情。
社交技术给人们带来能够塑造个人微型文化圈的力量,以技术为基础的网络世界将对传统的权利结构产生影响甚至带来挑战。
企业可以通过社交渠道的新技术直接接触到消费者,消费者也可以利用社交平台突破营销干扰,使企业对其产品和行为负责。
知识学习
通过可穿戴设备把相关信息传递给人类感官。隐形眼镜和永久植入的嵌入传感器和计算器给人们带来穿墙的听力、天然的夜视,以及可以嵌入虚拟和增强现实系统中的能力;智力增强药物将会扩展人类认知能力,改变知识学习方式。
虚实交融的泛在学习成为学校教育常态。每所学校都是虚拟学校的组成部分,虚拟学校与实体学校无缝融合,满足人人、时时、处处可学的需求。创建基于神经认知机制规律并利用该机制获取新知识、学习和记忆的教育系统。借助于个体倾向性和大脑可塑性数据、神经计算机界面、虚拟和增强现实元素,混合智能为人们提供新型教学场所和教育方式。
安全
人、机、物融合的安全系统,以及快速感知、响应和应对的社会安全生态。
记者观察:
安全,既包括人身和环境的安全,也包括网络安全、生物安全等方面。如何实现全方位的安全?
对犯罪与恐怖主义有效监控及预防
建设城市公共安全视频监控系统,实现打击犯罪、治安防范、社会管理、服务民生等功能。对城市公共区域内人员的活动情况进行记录。发展身份识别和比对技术,数据存储、专项提取、综合分析技术,对罪犯和嫌疑人群进行实时追踪,提高犯罪预防效果和事后破案率,强化震慑效果。
网络安全防护
通过信息安全技术和舆情监测技术的开发,主动搜索和处理钓鱼网站、身份识别、恶意窃听和窃密、假冒热点、电信、网络攻击、勒索软件等安全缺陷热点问题,使网络不法行为及恐怖主义得到防治,使虚拟空间的安全性大幅提升。
生物安全防护
通过信息监测技术和紧急生物防护与杀灭技术的开发,主动检测和及时应对外来生物入侵、新型人畜传染病、疫病暴发等生物安全问题,加强检测及防护网络建设与应对机制设计、防护工具及恢复机制等方面的研究,积极面对未来可能大面积出现的生物安全及其社会影响问题。
(课题组成员还包括李宏、王建芳、惠仲阳、张秋菊、陈晓怡、葛春雷、刘栋、叶京、贾晓琪、李超、艾超)
《光明日报》( 2021年03月25日16版)
来源: 光明网-《光明日报》
最近做到一个项目, 需要阴历与阳历的相互转换, 网上找了很多资料, 发现很多都是不准的, 但是给了我参考价值
算法借用百度百科的 :
阳历太阳历又称为阳历,是以地球绕太阳公转的运动周期为基础而制定的历法。
太阳历的历年近似等于回归年,一年12个月,这个“月”,实际上与朔望月无关。
阳历的月份、日期都与太阳在黄道上的位置较好地符合,根据阳历的日期,在一年中可以明显看出四季寒暖变化的情况;但在每个月份中,看不出月亮的朔、望、两弦。
如今世界通行的公历就是一种阳历,平年365天,闰年366天,每四年一闰,每满百年少闰一次,到第四百年再闰,即每四百年中有97个闰年。公历的历年平均长度与回归年只有26秒之差,要累积3300年才差一日。
阴历希吉来历系太阴历,其计算方法是: 以太阴圆缺一周为一月,历时29日12小时44分2.8秒,太阴圆缺十二周为一年,历时354日8小时48分33.6秒。每一年的12个月中,6个单数月份(即1、3、5、7、9、11月)为“大建”,每月为30天; 6个双数月份(2、4、6、8、10、12月)为“小建”,每月为29天;在逢闰之年,将12月改大月为30天。该历以30年为一周期,每一周期里的第2、5、7、10、13、16、18、21、24、26、29年,共11年为闰年, 不设置闰月,而在12月末置一闰日,闰年为355日,另19年为平年,每年354日。故平均每年为354日8小时48分。按该历全年实际天数计算,比回归年约少10日21小时1分,积2.7回归年相差一月,积32.6回归年相差一年。该历对昼夜的计算,以日落为一天之始,到次日日落为一日,通常称为夜行前,即黑夜在前,白昼在后,构成一天。希吉来历每年9月(莱麦丹)为伊斯兰教斋戒之月, 对这个月的起讫除了计算之外,还要由观察新月是否出现来决定。 即在8月29日这天进行观测,如见新月,第二日即为9月1日,黎明前开始斋戒,8月仍为小建; 如不见新月,第三日则为9月1日,8月即变为“大建”。到了9月29日傍晚,也需要看月,如见新月,第二天就是10月1日,即为开斋节日,使9月变成“小建”;如未见新月,斋戒必须再延一天,9月即为“大建”。 12月(祖勒·希哲)上旬为朝觐日期,12月10日为宰牲节日。该历的星期,使用七曜(日、月、火、水、木、金、土)记日的周日法。每周逢金曜为“主麻日”,穆斯林在这一天举行“聚礼”。
思路要想计算给定的时间对于的农历是哪一天,我们需要找一个参考时间,然后以该参考时间计算以后的时间。首先计算当前时间与参考时间相差的天数,然后通过求出农历每年的天数,计算当前时间对应的是哪一年的第几天,最后计算出属于那个月的哪一个日期。
计算生肖属相目前的做法是 阴历年份 - 1900 + 36 然后除以 12 取余数, 得出生肖属相的序号。
private function yearShengXiao($lunarYear){ // TODO 至于为什么这样弄, 我也没搞清楚 return self::SHENG_XIAO[($lunarYear - self::MIN_YEAR + 36) % 12]; // 年的属相}年的干支算法
网上搜到的做法是用公元年来计算, 但是不对, 然后我换成阴历年居然就跟百度的日历能对上了, 这个我也没弄清楚, 但是能算出来了, 公式: 年数先减三,除10余数是天干,基数改用12除,余数便是地支年 (如果余数为 0 ,则取最大序号)
private function yearGanZhi($lunarYear){ // 年数先减三,除10余数是天干,基数改用12除,余数便是地支年 (如果余数为 0 ,则取最大序号) $yJiShu = $lunarYear - 3; $yTianGan = ($yJiShu % 10 == 0) ? 10 : $yJiShu % 10; $yDiZhi = ($yJiShu % 12 == 0) ? 10 : $yJiShu % 12; $yGanZhi = self::TIAN_GAN[$yTianGan - 1] . self::DI_ZHI[$yDiZhi - 1]; // // 由于是从 0 开始,这里再减一 return $yGanZhi;}月的干支算法
网上搜索了, 没找到好的实现方式, 麻烦知道的在这里说一下,
日的干支算法网上搜到的:
G = 4C + [C / 4] + 5y + [y / 4] + [3 * (M + 1) / 5] + d - 3Z = 8C + [C / 4] + 5y + [y / 4] + [3 * (M + 1) / 5] + d + 7 + i其中C 是世纪数减一,y 是年份后两位,M 是月份,d 是日数。1月和2月按上一年的13月和14月来算。奇数月i=0,偶数月i=6。G 除以10的余数是天干,Z 除以12的余数是地支。
但是不对, 麻烦有懂也告知下
PHP 的实现完整代码<?php/** * 阳历和新历的转换 */class SolarLunar { // 最小年 const MIN_YEAR = 1900; // 最大年 const MAX_YEAR = 2100; // 开始的日期 const START_DATE_STR = \"1900-01-30\"; const CHINESE_NUMBER = [\"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"七\", \"八\", \"九\", \"十\", \"十一\", \"十二\"]; const CHINESE_NUMBER_SPECIAL = [\"正\", \"二\", \"三\", \"四\", \"五\", \"六\", \"七\", \"八\", \"九\", \"十\", \"冬\", \"腊\"]; const TIAN_GAN = [\"甲\", \"乙\", \"丙\", \"丁\", \"戊\", \"己\", \"庚\", \"辛\", \"壬\", \"癸\"]; const DI_ZHI = [\"子\", \"丑\", \"寅\", \"卯\", \"辰\", \"巳\", \"午\", \"未\", \"申\", \"酉\", \"戌\", \"亥\"]; const SHENG_XIAO = [\"鼠\", \"牛\", \"虎\", \"兔\", \"龙\", \"蛇\", \"马\", \"羊\", \"猴\", \"鸡\", \"狗\", \"猪\"]; // 阴历年份的数据 const LUNAR_INFO = [ 0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909 0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919 0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929 0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939 0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949 0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959 0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969 0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979 0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989 0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999 0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009 0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019 0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029 0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039 0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049 0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059 0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069 0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079 0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089 0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099 0x0d520]; /** * 阴历转阳历 * @param string $date * @param bool $leapMonthFlag * @return string */ public function lunarToSolar($date = \"\", $leapMonthFlag = false) { try { $dateTime = new \DateTime($date); } catch (\Exception $exception) { return \"\"; } $lunarYear = $dateTime->format(\"Y\"); $lunarMonth = $dateTime->format(\"n\"); $lunarDay = $dateTime->format(\"j\"); // 检查是否合法 if (!$this->checkLunarDate($lunarYear, $lunarMonth, $lunarDay, $leapMonthFlag)) { return \"\"; } $offset = 0; for ($i = self::MIN_YEAR; $i < $lunarYear; $i++) { $yearDaysCount = $this->getYearDays($i); // 求阴历某年天数 $offset += $yearDaysCount; } //计算该年闰几月 $leapMonth = $this->getLeapMonth($lunarYear); if ($leapMonthFlag && $leapMonth != $lunarMonth) { // 您输入的闰月标志有误 return \"\"; } if ($leapMonth == 0 || ($lunarMonth < $leapMonth) || ($lunarMonth == $leapMonth && !$leapMonthFlag)) { for ($i = 1; $i < $lunarMonth; $i++) { $tempMonthDaysCount = $this->getMonthDays($lunarYear, $i); $offset += $tempMonthDaysCount; } // 检查日期是否大于最大天 if ($lunarDay > $this->getMonthDays($lunarYear, $lunarMonth)) { // 不合法的农历日期 return \"\"; } $offset += intval($lunarDay); // 加上当月的天数 } else { //当年有闰月,且月份晚于或等于闰月 for ($i = 1; $i < $lunarMonth; $i++) { $tempMonthDaysCount = $this->getMonthDays($lunarYear, $i); $offset += $tempMonthDaysCount; } if ($lunarMonth > $leapMonth) { $temp = $this->getLeapMonthDays($lunarYear); // 计算闰月天数 $offset += $temp; // 加上闰月天数 if ($lunarDay > $this->getMonthDays($lunarYear, $lunarMonth)) { // 不合法的农历日期 return \"\"; } $offset += intval($lunarDay); } else { // 如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数 // 计算月为闰月 $temp = $this->getMonthDays($lunarYear, $lunarMonth); // 计算非闰月天数 $offset += $temp; if ($lunarDay > $this->getLeapMonthDays($lunarYear)) { // 不合法的农历日期 return \"\"; } $offset += intval($lunarDay); } } try { $newDateTime = new \DateTime(self::START_DATE_STR); } catch (\Exception $exception) { return \"\"; } $sumH = 24 * $offset; $newDateTime->add(new \DateInterval('PT' . $sumH . 'H')); return $newDateTime->format(\"Y-m-d\"); } /** * 把阳历转换为中文的阴历 * @param string $date * @return string */ public function solarToChineseLunar($date) { $dateTime = new \DateTime($date); list($lunarYear, $lunarMonth, $lunarDay, $leapMonth, $leapMonthFlag) = $this->calculateLunar($dateTime); $result = \"\"; if($leapMonthFlag && $lunarMonth == $leapMonth){ $result .= \"闰\"; } $solarYear = (int)$dateTime->format(\"Y\"); $solarMoth = (int)$dateTime->format(\"n\"); $solarDay = (int)$dateTime->format(\"j\"); $result .= self::CHINESE_NUMBER_SPECIAL[$lunarMonth-1] . \"月\"; $result .= $this->chineseDayString($lunarDay) . \"日\"; // 年的天干地支 $yGanZhi = $this->yearGanZhi($lunarYear); // 生肖属相 $yShengXiao = $this->yearShengXiao($lunarYear); $result .= \",\" . $yGanZhi . \"年 [\" . $yShengXiao . '年]'; // 月的天干地支 $mTianGanDiZhi = $this->mothGanZhi($solarYear, $solarMoth, $solarDay); $result .= \",\" . $mTianGanDiZhi . '月'; // 日的天干地支 $dTianGanDiZhi = $this->dayGanZhi($solarYear, $solarMoth, $solarDay); $result .= \",\" . $dTianGanDiZhi . '日'; return $result; } /** * 阳历转换为简单的中文阴历 * @param string $date * @return string */ public function solarToSimpleLunar($date) { $dateTime = new \DateTime($date); list($lunarYear, $lunarMonth, $lunarDay, $leapMonth, $leapMonthFlag) = $this->calculateLunar($dateTime); $result = $lunarYear . \"年\"; if($leapMonthFlag && $lunarMonth == $leapMonth) { $result .= \"闰\"; } if($lunarMonth < 10){ $result .= \"0\" . $lunarMonth . \"月\"; } else { $result .= $lunarMonth . \"月\"; } if($lunarDay < 10){ $result .= \"0\" . $lunarDay . \"日\"; } else { $result .= $lunarDay . \"日\"; } return $result; } /** * 阳历转为正常的阴历 * @param string $date * @param bool $isLeapMonth 是否是闰月 * @return string */ public function solarToLunar($date, &$isLeapMonth = false) { $dateTime = new \DateTime($date); list($lunarYear, $lunarMonth, $lunarDay, $leapMonth, $leapMonthFlag) = $this->calculateLunar($dateTime); $result = $lunarYear . \"-\"; if($lunarMonth < 10){ $result .= \"0\" . $lunarMonth . \"-\"; } else { $result .= $lunarMonth . \"-\"; } if($lunarDay < 10){ $result .= \"0\" . $lunarDay; } else { $result .= $lunarDay; } $isLeapMonth = false; if($leapMonthFlag && $lunarMonth == $leapMonth) { $isLeapMonth = true; } return $result; } /** * 计算当前日期的阴历 * @param \DateTime $dateTime * @return array */ private function calculateLunar($dateTime) { $i = 0; $temp = 0; $leapMonthFlag = false; $isLeapYear = false; $startDate = new \DateTime(self::START_DATE_STR); $offset = $this->daysBwteen($dateTime, $startDate); for($i = self::MIN_YEAR; $i < self::MAX_YEAR; $i++){ $temp = $this->getYearDays($i); //求当年农历年天数 if($offset - $temp < 1){ break; } else { $offset -= $temp; } } $lunarYear = $i; $leapMonth = $this->getLeapMonth($lunarYear); //计算该年闰哪个月 //设定当年是否有闰月 if($leapMonth > 0 ){ $isLeapYear = true; } else { $isLeapYear = false; } for($i = 1; $i <= 12; $i++){ if($i == $leapMonth + 1 && $isLeapYear){ $temp = $this->getLeapMonthDays($lunarYear); $isLeapYear = false; $leapMonthFlag = true; $i--; } else { $temp = $this->getMonthDays($lunarYear, $i); } $offset -= $temp; if($offset <= 0){ break; } } $offset += $temp; $lunarMonth = $i; $lunarDay = $offset; return [$lunarYear, $lunarMonth, $lunarDay, $leapMonth, $leapMonthFlag]; } /** * 检查阴历是否合法 * @param int $lunarYear * @param int $lunarMonth * @param int $lunarDay * @param bool $leapMonthFlag * @return bool * @throws Exception */ private function checkLunarDate($lunarYear, $lunarMonth, $lunarDay, $leapMonthFlag = false) { if ($lunarYear < self::MIN_YEAR || $lunarYear > self::MAX_YEAR) { // 非法农历年份 return false; } if ($lunarMonth < 1 || $lunarMonth > 12) { // 非法农历月份 return false; } if ($lunarDay < 1 || $lunarDay > 30) { // 中国的月最多30天 // 非法农历天数 return false; } $leap = $this->getLeapMonth($lunarYear); // 计算该年应该闰哪个月 if ($leapMonthFlag == true && $lunarMonth != $leap) { // 非法闰月 return false; } return true; } /** * 计算该月总天数 * @param int $year * @param int $month * @return int */ private function getMonthDays($year, $month) { if ($month > 31 || $month < 0) { // error month return 0; } // 0X0FFFF[0000 {1111 1111 1111} 1111]中间12位代表12个月,1为大月,0为小月 $bit = 1 << (16 - $month); if (((self::LUNAR_INFO[$year - 1900] & 0x0FFFF) & $bit) == 0) { return 29; } return 30; } /** * 计算阴历年的总天数 * @param int $year * @return int */ private function getYearDays($year) { $sum = 29 * 12; for ($i = 0x8000; $i >= 0x8; $i >>= 1) { if ((self::LUNAR_INFO[$year - 1900] & 0xfff0 & $i) != 0) { $sum++; } } return $sum + $this->getLeapMonthDays($year); } /** * 计算阴历年闰月多少天 * @param int $year * @return int */ private function getLeapMonthDays($year) { if ($this->getLeapMonth($year) != 0) { if ((self::LUNAR_INFO[$year - 1900] & 0xf0000) == 0) { return 29; } return 30; } return 0; } /** * 计算阴历年闰哪个月 1-12 , 没闰传回 0 * @param int $year * @return int */ private function getLeapMonth($year) { return (int)(self::LUNAR_INFO[$year - 1900] & 0xf); } /** * 计算差的天数 * @param \DateTime $date * @param \DateTime $startDate * @return int */ private function daysBwteen($date, $startDate) { $subValue = floatval($date->getTimestamp() - $startDate->getTimestamp()) / 86400.0 + 0.5; return intval($subValue); } /** * 计算年天干地支 * @param $lunarYear * @return string */ private function yearGanZhi($lunarYear) { // 年数先减三,除10余数是天干,基数改用12除,余数便是地支年 (如果余数为 0 ,则取最大序号) $yJiShu = $lunarYear - 3; $yTianGan = ($yJiShu % 10 == 0) ? 10 : $yJiShu % 10; $yDiZhi = ($yJiShu % 12 == 0) ? 10 : $yJiShu % 12; $yGanZhi = self::TIAN_GAN[$yTianGan - 1] . self::DI_ZHI[$yDiZhi - 1]; // // 由于是从 0 开始,这里再减一 return $yGanZhi; } /** * 计算年的生肖属相 * @param $lunarYear * @return mixed */ private function yearShengXiao($lunarYear) { // TODO 至于为什么这样弄, 我也没搞清楚 return self::SHENG_XIAO[($lunarYear - self::MIN_YEAR + 36) % 12]; // 年的属相 } // TODO 尚未实现 /** * 计算日的天干地支 * @param $solarYear * @param $solarMoth * @param $solarDay * @return string */ private function dayGanZhi($solarYear, $solarMoth, $solarDay) { return \"\"; } // TODO 尚未实现 /** * 计算月的天干地支 * @param $solarYear * @param $solarMoth * @param $solarDay * @return string */ private function mothGanZhi($solarYear, $solarMoth, $solarDay) { return \"\"; } /** * 把天转换为中文字符 * @param int $day * @return mixed|string */ private function chineseDayString($day) { $chineseTen = [\"初\", \"十\", \"廿\", \"三\"]; $n = 0; if($day % 10 == 0){ $n = 9; } else { $n = $day % 10 - 1; } if($day > 30){ return \"\"; } if($day == 20){ return \"二十\"; } else if($day == 10){ return \"初十\"; } else { return $chineseTen[$day / 10] . self::CHINESE_NUMBER[$n]; } }}$solarLunar = new SolarLunar();$solarDate = \"2010-01-05\";$new_date = $solarLunar->solarToChineseLunar($solarDate);var_dump($solarDate . \" 转为阴历: \" . $new_date);$new_date = $solarLunar->solarToSimpleLunar($solarDate);var_dump($solarDate . \" 转为阴历, 中文: \" . $new_date);$new_date = $solarLunar->solarToLunar($solarDate, $isLeapMonth);var_dump(\"是否是闰月: \" . ($isLeapMonth ? \"是\" : \"否\"));var_dump($solarDate . \" 转为阴历: \" . $new_date);$lunarDate = \"2099-11-25\";$new_date = $solarLunar->lunarToSolar($lunarDate, false);var_dump($lunarDate . \" 转新历为: \" . $new_date);
输出:
string(67) \"2010-01-05 转为阴历: 冬月廿一日,己丑年 [牛年],月,日\"string(50) \"2010-01-05 转为阴历, 中文: 2009年11月21日\"string(20) \"是否是闰月: 否\"string(35) \"2010-01-05 转为阴历: 2009-11-21\"string(35) \"2099-11-25 转新历为: 2100-01-05\"
如果想要学习交流PHP的朋友,可以关注小编,私信【学习交流】手机用户可以直接私信,电脑端尚未开放此功能,需要下载app,我已经设置了自动回复,具体后续会自动回复各位。