PB中关于公历转农历的算法,网上有很多,思路也大致一样,在这里我就不再进行说明了。

本文主要是想跟所有PB爱好者,分享农历转公历的方法。

转换思路为:根据传入的农历日期,找到第一个小于传入日期的基准日期(基准日期梅10年1天,基准日期对应的农历日期为正月初一),通过计算,得出传入日期与基准日期之间相差的天数ll_sumday,然后通过RelativeDate ( 基准日期, ll_sumday ),即可求出传入的农历日期对应的公历日期。

本文将给出一个用户自定义对象,该用户对象中包含两个public函数,第一个是:

********************************************************************

函数名称: of_day_to_lunar

传递参数: date ad_date;    - 传入公历日期

string as_lunar  - 返回农历日期

integer ai_type  - 类型,1取完整信息, 2取日信息, 3取农历写法的月日

返回参数: STRING

********************************************************************

功能描述: 计算农历:传入公历计算农历

********************************************************************

第二个是:

********************************************************************

函数名称: of_lunar_to_day

传递参数: string as_lunar  - 传入农历日期,

写法为: 20110101  表示2011年正月初一

20090506R 表示2009年闰五月初六

返回参数: date   - 返回公历日期

********************************************************************

功能描述: 计算公历:传入农历计算公历

********************************************************************

需要说明的是第二个函数“农历转公历”,由于农历日期的写法不是一种规范化的写法,因此我将该函数设定为只能接受格式化了的参数。如果你想要传入形如:五月廿八 这样的农历写法的日期,那么,请自己写一个将农历写法的日期格式化为of_lunar_to_day函数所能接受的参数的函数吧。

nvo_lunar代码明细:(自定义一个不可见的对象nvo_lunar,然后对该对象进行Edit Source,将以下内容复制替换即可)

forward global type nvo_lunar from nonvisualobject end type end forward global type nvo_lunar from nonvisualobject autoinstantiate end type type variables //农历年1900 到 2051年 每年的信息数据: string is_lunarinfostr[152] = { & '04bd8','04ae0','0a570','054d5','0d260','0d950','16554','056a0','09ad0','055d2', & '04ae0','0a5b6','0a4d0','0d250','1d255','0b540','0d6a0','0ada2','095b0','14977', & '04970','0a4b0','0b4b5','06a50','06d40','1ab54','02b60','09570','052f2','04970', & '06566','0d4a0','0ea50','06e95','05ad0','02b60','186e3','092e0','1c8d7','0c950', & '0d4a0','1d8a6','0b550','056a0','1a5b4','025d0','092d0','0d2b2','0a950','0b557', & '06ca0','0b550','15355','04da0','0a5d0','14573','052d0','0a9a8','0e950','06aa0', & '0aea6','0ab50','04b60','0aae4','0a570','05260','0f263','0d950','05b57','056a0', & '096d0','04dd5','04ad0','0a4d0','0d4d4','0d250','0d558','0b540','0b5a0','195a6', & '095b0','049b0','0a974','0a4b0','0b27a','06a50','06d40','0af46','0ab60','09570', & '04af5','04970','064b0','074a3','0ea50','06b58','055c0','0ab60','096d5','092e0', & '0c960','0d954','0d4a0','0da50','07552','056a0','0abb7','025d0','092d0','0cab5', & '0a950','0b4a0','0baa4','0ad50','055d9','04ba0','0a5b0','15176','052b0','0a930', & '07954','06aa0','0ad50','05b52','04b60','0a6e6','0a4e0','0d260','0ea65','0d530', & '05aa0','076a3','096d0','04bd7','04ad0','0a4d0','1d0b6','0d250','0d520','0dd45', & '0b5a0','056d0','055b2','049b0','0a577','0a4b0','0aa50','1b255','06d20','0ada0', & '14b63','09370'} /* 如 2001 0x0d954 01101100101010100 1、2、4、5、8、10、12月大3、6、7、9、11月小,4月为闰月,闰月小 */ end variables forward prototypes public function string of_day_to_lunar (date ad_date, ref string as_lunar, integer ai_type) public function date of_lunar_to_day (ref string as_lunar) private function string of_get_jq (date ad_date) private function integer of_get_monthdays_byyear (string as_str, ref long al_mdays[14], string as_end_lunar) end prototypes public function string of_day_to_lunar (date ad_date, ref string as_lunar, integer ai_type);/* ******************************************************************** 函数名称: of_day_to_lunar 传递参数: date ad_date; - 传入公历日期 string as_lunar - 返回农历日期 integer ai_type - 类型,1取完整信息, 2取日信息, 3取农历写法的月日 返回参数: STRING ******************************************************************** 功能描述: 计算农历:传入公历计算农历 ******************************************************************** 备注: ******************************************************************** */ if ad_date <= date('1900-1-1') or ad_date > date('2051-12-31') or isnull(ad_date) then as_lunar = '19000101' return '' end if string ls_ret, ls_lunar_mmdd //干 string Gan[10] = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"} //支 string Zhi[12] = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"} //生肖 string Animals[12] = {"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"} string nStr1[11] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"} string nStr2[5] = {"初", "十", "廿", "卅", " "} string ls_daysto[17] = {'1900-01-30', '1910-02-09','1920-02-19','1930-01-29','1940-02-07','1950-02-16','1960-01-27','1970-02-05','1980-02-15','1990-01-26','2000-02-04','2010-02-13','2020-01-24','2030-02-02','2040-02-11', '2050-01-22', '2101-02-05'} long ll_now, ll_nowstart long ll_year,ll_mon,ll_day long ll_lyear,ll_lmon,ll_lday long ll_lunarmd[14] //年,月,日 ll_year = year(ad_date) ll_mon = month(ad_date) ll_day = day(ad_date) double ld_num long ll_leap,ll_sumday,ll_leapdays long ll_info,k,i long ll_temp,ll_offset string ls_bin,ls_code long ll_month_prior //当月的前一个月 ll_leap = 0 ll_temp = 0 //取得最近的一个基准点,10年一个,可提高效率 k = int((ll_year - 1900) / 10) + 1 if ll_mon > 2 then k ++ for i = k to 17 if ad_date <= date(ls_daysto[i]) then ll_now = i -1 ll_nowstart = long(left(ls_daysto[i - 1],4)) ll_offset = daysafter(date(ls_daysto[i - 1]), ad_date) exit end if next //计算农历 for i = ll_nowstart to 2051 //求当年农历年的天数 //农历全年天数 //ll_lunarmd[14]说明,1-12为农历年每个月的天数,13为闰月的天数(无闰月则为0),14为闰月月份(无闰月则为0) ll_sumday = of_get_monthdays_byyear( is_lunarinfostr[i - 1900 + 1], ll_lunarmd, '') ll_offset = ll_offset - ll_sumday if ll_offset < 1 then exit next ll_offset = ll_offset + ll_sumday //农历年 ll_lyear = i long ll_leapmonth long ll_pritmp,ll_thistmp //取得闰月月份 ll_leapmonth = ll_lunarmd[14] for i = 1 to 13 if ll_leapmonth = 0 or ll_leapmonth = 12 then //没有闰月或闰12月,按顺序增加 ll_temp = ll_lunarmd[i] ll_pritmp = i else//否则,加到有闰月的月份后,需要把闰月天数加进来 if i <= ll_leapmonth then ll_temp = ll_lunarmd[i] ll_pritmp = i elseif i = ll_leapmonth + 1 then ll_temp = ll_lunarmd[13] ll_pritmp = ll_leapmonth else ll_temp = ll_lunarmd[i - 1] ll_pritmp = i - 1 end if end if ll_offset = ll_offset - ll_temp ll_lmon = ll_pritmp if ll_offset <= 0 then exit ll_month_prior = ll_pritmp next ll_offset = ll_offset + ll_temp //农历月 //农历日 ll_lday = ll_offset long ll_days as_lunar = fill('0', 2 - len(string(ll_lyear))) + string(ll_lyear) + fill('0', 2 - len(string(ll_lmon))) + string(ll_lmon) + fill('0', 2 - len(string(ll_lday))) + string(ll_lday) //转换成农历的写法: string ls_str,ls_mstr,ls_ystr,ls_astr if ai_type = 1 then //农历年的干、支 ls_ystr = gan[mod(mod(ll_lyear - 1864, 60), 10) + 1] + zhi[mod(mod(ll_lyear - 1864, 60), 12) + 1] //生肖 ls_astr = Animals[mod(ll_lyear - 1900, 12) + 1] end if long ll_mtmp //日期 choose case ll_lday case 10 ls_str = '初十' case 20 ls_str = '二十' case 30 ls_str = '三十' case else if int(ll_lday / 10) + 1>=1 and int(ll_lday / 10) + 1<=5 then ls_str = nstr2[int(ll_lday / 10) + 1] end if if mod(ll_lday,10)>11 or mod(ll_lday,10)<=0 then else ls_str += nstr1[mod(ll_lday,10)] end if end choose //月份 choose case ll_lmon case 1 ls_mstr = '正' case 11 ls_mstr = '十一' case 12 ls_mstr = '十二' case else if ll_lmon>11 or ll_lmon<=0 then else ls_mstr = nstr1[ll_lmon] end if end choose if ll_leapmonth = ll_lmon and ll_lmon = ll_month_prior then ls_mstr = '闰' + ls_mstr if ai_type = 1 then ls_ret = ls_ystr + "年(" + ls_astr + ") " + ls_mstr + "月" + ls_str //计算农历上的节气,从1900.1.6 02:05:00 (小寒)开始 string ls_jq ls_jq = of_get_jq(ad_date) if ls_jq <> '' then ls_ret = ls_ret + " 节气:" + ls_jq elseif ai_type = 3 then //返回月日 return ls_mstr + "月" + ls_str else if ls_str = '初一' then ls_ret = ls_mstr + "月" else ls_ret = ls_str end if end if return ls_ret end function public function date of_lunar_to_day (ref string as_lunar);/* ******************************************************************** 函数名称: of_lunar_to_day 传递参数: string as_lunar - 传入农历日期,写法为: 20110101表示2011年正月初一 20090506R表示2009年闰五月初六 返回参数: date - 返回公历日期 ******************************************************************** 功能描述: 计算公历:传入农历计算公历 ******************************************************************** 备注: ******************************************************************** */ if len(as_lunar) <> 8 and len(as_lunar) <> 9 then return 1900-01-01 end if long ll_year,ll_mon,ll_day boolean lb_leapmonth long i, k, ll_sumday ll_year = integer(left(as_lunar, 4)) ll_mon = integer(mid(as_lunar, 5,2)) ll_day = integer(mid(as_lunar, 7, 2)) lb_leapmonth = upper(mid(as_lunar, 9, 1)) = 'R' //是否是闰月 if ll_year < 1900 or ll_year > 2050 then return 1900-01-01 if ll_mon < 1 or ll_mon > 12 then return 1900-01-01 if ll_day < 1 or ll_day > 31 then return 1900-01-01 string ls_daysto[17] = {'1900-01-30', '1910-02-09','1920-02-19','1930-01-29','1940-02-07','1950-02-16','1960-01-27','1970-02-05','1980-02-15','1990-01-26','2000-02-04','2010-02-13','2020-01-24','2030-02-02','2040-02-11', '2050-01-22', '2101-02-05'} long ll_lunarmd[14] //取得最近的一个基准点,10年一个,可提高效率 k = int((ll_year - 1900) / 10) + 1 //计算农历天数 for i = integer(left(ls_daysto[k],4)) to ll_year - 1 //求当年农历年的天数 //农历全年天数 //ll_lunarmd[14]说明,1-12为农历年每个月的天数,13为闰月的天数(无闰月则为0),14为闰月月份(无闰月则为0) ll_sumday += of_get_monthdays_byyear( is_lunarinfostr[i - 1900 + 1], ll_lunarmd, '') next i = of_get_monthdays_byyear( is_lunarinfostr[ll_year - 1900 + 1], ll_lunarmd, as_lunar) if i = 0 then return 1900-01-01 ll_sumday += i return RelativeDate ( date(ls_daysto[k]), ll_sumday ) end function private function string of_get_jq (date ad_date);//24节气 string SolarTerm[24] = {"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", & "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"} //************************************************************************* // 该函数已经加密 //************************************************************************** return '' end function private function integer of_get_monthdays_byyear (string as_str, ref long al_mdays[14], string as_end_lunar);//取得指定农历年的天数 string ls_hextobin[15] = {'0001','0010','0011','0100','0101','0110','0111','1000','1001','1010','1011','1100','1101','1110','1111'} string ls_bin long ll_leapdays long ll_leapm long ll_yeardays long ll_mon, ll_day //结束日期信息 if as_end_lunar <> '' then ll_mon = integer(mid(as_end_lunar, 5, 2)) ll_day = integer(mid(as_end_lunar, 7, 2)) else ll_mon = 12 end if as_str = upper(as_str) if left(as_str,1) = '1' then ll_leapdays = 30 else ll_leapdays = 29 end if choose case right(as_Str,1) case '1','2','3','4','5','6','7','8','9' ll_leapm = integer(right(as_Str,1)) case 'A' ll_leapm = 10 case 'B' ll_leapm = 11 case 'C' ll_leapm = 12 case else ll_leapm = 0 end choose if upper(mid(as_end_lunar, 9, 1)) = 'R' then //传入的日期是闰月的,但实际上该日期不是闰月,则表示日期有问题,返回0 if ll_mon <> ll_leapm then return 0 if ll_day > ll_leapdays then return 0 //日期有误 ll_mon ++ end if if ll_leapm = 0 then ll_leapdays = 0 long i for i = 2 to 4 choose case mid(as_str,i,1) case '1','2','3','4','5','6','7','8','9' ls_bin += ls_hextobin[integer(mid(as_str,i,1))] case 'A' ls_bin += ls_hextobin[10] case 'B' ls_bin += ls_hextobin[11] case 'C' ls_bin += ls_hextobin[12] case 'D' ls_bin += ls_hextobin[13] case 'E' ls_bin += ls_hextobin[14] case 'F' ls_bin += ls_hextobin[15] case else ls_bin += '0000' end choose next for i = 1 to ll_mon choose case mid(ls_bin,i,1) case '1' al_mdays[i] = 30 case '0' al_mdays[i] = 29 case else end choose if as_end_lunar <> '' and ll_mon = i then exit ll_yeardays += al_mdays[i] next al_mdays[13] = ll_leapdays al_mdays[14] = ll_leapm if ll_day > 0 then //有截止日期的 if ll_day > al_mdays[integer(mid(as_end_lunar, 5, 2))] then return 0 //日期有误 if integer(mid(as_end_lunar, 5, 2)) > ll_leapm then ll_yeardays += ll_leapdays ll_yeardays += ll_day else ll_yeardays += ll_leapdays end if return ll_yeardays end function on nvo_lunar.create call super::create TriggerEvent( this, "constructor" ) end on on nvo_lunar.destroy TriggerEvent( this, "destructor" ) call super::destroy end on

根据

  • gui41021
  • (鬼鬼)

的思路,可以使用另外一种方法来实现农历转阳历,该方法需要使用到网上随处可见的一个动态链接库:calendar.dll 。需要其中的一个函数:

function long MyGetLunarDate(long iYear, long iMonth, long iDay, ref long iLunarYear, ref long iLunarMonth, ref long iLunarDay) library "calendar.dll"

该方法的思路是:首先记录传入的农历日期的年份、月份和天数,然后取到第一个可以用date类型表示并且小于传入的农历日期的日期new_date,然后通过函数MyGetLunarDate来获取new_date对应的农历日期(很显然的,此时获取的农历日期一定小于传入的农历日期),接着使用RelativeDate(new_date,n),将new_date往后增加,直到new_date对应的农历日期为传入的日期。

具体的代码如下:

/* ******************************************************************** 函数名称: of_lunar_to_day 传递参数: string as_lunar - 传入农历日期,写法为: 2011-01-01表示2011年正月初一 2009-05-06R表示2009年闰五月初六 返回参数: date - 返回公历日期 ******************************************************************** 功能描述: 计算公历:传入农历计算公历 ******************************************************************** 备注: ******************************************************************** */ long ll_oldyear,ll_oldmonth,ll_oldday long ll_newyear,ll_newmonth,ll_newday date new_date, first_date //第一次吻合的日期 boolean i =false //ls_lunar = '2009-05-06'// 求这天的阳历 boolean lb_leap = false //是否是闰月 int li lb_leap = upper(mid(as_lunar, 11, 1)) = 'R' as_lunar = left(as_lunar, 10) ll_oldyear = integer(left(as_lunar, 4)) ll_oldmonth = integer(mid(as_lunar, 6, 2)) ll_oldday = integer(mid(as_lunar, 9, 2)) if ll_oldyear < 1900 or ll_oldyear > 2050 then return 1900-01-01 if ll_oldmonth < 1 or ll_oldmonth > 12 then return 1900-01-01 if ll_oldday < 1 or ll_oldday > 31 then return 1900-01-01 if not isdate(as_lunar) then //如果农历无法用公历表示,则往前走,找到第一个可以用农历表示的日期 li = ll_oldday do while true li -- if li = 0 then return 1900-01-01 if isdate(left(as_lunar, 8) + string(li)) then new_date = date(left(as_lunar, 8) + string(li)) exit end if loop else new_date = date(as_lunar) end if do while i = false //一般是2-4次左右,最长可能循环6次 mygetlunardate(year(new_date),month(new_date),day(new_date),ll_newyear,ll_newmonth,ll_newday) // calendar.dll中阳历转阴历的函数 if ll_newyear = ll_oldyear and ll_newmonth = ll_oldmonth and ll_newday = ll_oldday then if lb_leap then lb_leap = false first_date = new_date new_date = RelativeDate(new_date,29) //下个月,起码是29天后了 else i = true end if else //取得的农历日期大于传入的日期,说明传入的日期有误,直接返回 if string(ll_newyear) + string(ll_newmonth, '00') > string(ll_oldyear) + string(ll_oldmonth, '00') then return 1900-01-01//没有发现 if ll_newmonth <> ll_oldmonth then if ll_newday < 29 then new_date = RelativeDate(new_date,29 - ll_newday) //取得的农历日期还是上一个月的29号前的,直接跳到29号 else new_date = RelativeDate(new_date,1) //取得的农历日期是上一个月的29号后的,跳到下一天(因为下一天可能是30号也可能是1号) end if else //取得的农历日期已经是这个月的,直接跳到传入的农历日期那一天 new_date = RelativeDate(new_date,ll_oldday - ll_newday) end if end if loop return new_date

PB中公历与农历(阳历与阴历)的互相转换——主要是农历转公历(阴历转阳历)相关推荐

  1. linux 软件集成工具箱,在PB中动态修改SQL语句

    在PB中动态修改SQL语句 分享到: 江苏省南通电信局网管中心 黄莹 ---- PowerBuilder是图形界面的Client/Server应用程序开发环境,可以很容易开发出功能强大的应用程序,在当 ...

  2. PB中函数测试遇到的问题

    在PB中写了一个函数,需要连接两个数据库 tr_1,tr_2,测试时报错(无法连接到第二个数据库),再确定该函数代码没有其它问题后,选中该函数,右键Regenerate后,测试成功. 转载于:http ...

  3. 在PB中存图片入数据库及显示图片

    在PB中存图片入数据库及显示图片 摘自:http://www.xicc.cn/User0/109/Show.asp?/_articleid/549.html 1.选择图片 string ls_path ...

  4. 在pb中实现声音文件的播放

    一个商业软件不仅要功能强大,而且界面也要美观,如果加入适量声音会增强软件的人机交互性,让软件给人更为深刻的印象.pb作为客户/服务器的客户端开发工具,在数据库管理上有强大的功能,但pb中本身没有播放声 ...

  5. pb 修改数据窗口种指定字段位置_在PB中控制 数据窗口 列修改属性.doc

    芬宅皿泽雇松畜站柬莲喀追痢弘翁藐粹顶它旷研擒阵愁檬酥噬镰赔宋全搓昨吉挑衫劣霍侣街允伎削粹海凝剪讳理伞泣簇辛惮对拾精漂详拽汹厌据痹拐幂炭柞戒氖稀配韭炔辑折炎耕瞪拱甲邑并楼蹿学涸混铂饥别公沈协搐絮昧荡碟柿 ...

  6. PB 中获取时间的方法

    PB 中获取时间的方法 1.获取当前日期和时间 sle_2.text= string(today(),'yyyy-mm-dd')+ " " + string(now(),'hh:m ...

  7. 在PB中如何打开一个非執行文件

    大家知道在PB中,有一个RUN()函数,可以运行一个指定的执行文件,如.EXE,.COM,.BAT等.但如果我们想打开一个非执行文件, 如.TXT,.DOC,.XLS等,就不能用RUN()函数了.如果 ...

  8. [PB] PB中读写文件通用的两个函数

    PB中读写文件通用的两个函数 1.文件读取 : //函数名:f_readfile //功能:读取文件//参数:// io_file:ref blob 大对象类型,存储读出的文件内容:// is_fil ...

  9. PB中的timer事件

    前言   在软件开发中,我们经常会用到实时获取服务器时间的功能,在这个功能中我们会用到timer控件,来看一下在PB中的timer是如何使用的吧. 实现步骤   1.窗体布局   2.窗体的open事 ...

最新文章

  1. 【Android 逆向】代码调试器开发 ( ptrace 函数 | 读寄存器 | 写寄存器 )
  2. 【ARM】Programmers Model
  3. SAP License:SAP记账码
  4. 小小芯片上的上千万个晶体管是怎么装上去的
  5. 米奇emoji_一些常用的 Emoji 符号(可直接复制)
  6. 12-13 库存信息管理系统
  7. (转)jquery对表单元素的取值和赋值
  8. 一元三次方程求解matlab_为什么一元n次代数方程必有n个根?
  9. [WARNING] Corrupted STDOUT by directly writing to native stream in forked JVM 1
  10. php java扩展模块_php扩展模块装安装
  11. 从零基础到斩获BAT算法岗offer,围观复旦大佬的秋招之路
  12. python学习笔记分享(四十)网络爬虫(7)反爬虫问题,解决中文乱码,登陆和验证码处理
  13. python修改桌面壁纸_python设置windows桌面壁纸
  14. java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource解决方法
  15. Keil5 平台 S3C2440裸机程序开发-----定时器中断
  16. 牛津英语字典pdf下载_从1到18岁,这款牛津认证的免费APP是学英语最好的装备
  17. .gitignore文件作用
  18. c语言栈的实现以及操作
  19. 智能家居进入人工智能时代 开启智慧家庭生活
  20. iTop-4412_开发板Linux编程之TFTP服务器学习笔记

热门文章

  1. python根据品种散点图鸢尾花_[Python机器学习]鸢尾花分类 机器学习应用
  2. ACdream之kmp
  3. 京东云与AI:助力企业公众抗击疫情 多项免费产品服务紧急驰援
  4. LINUX 系统:部署达梦企业管理工具-DEM
  5. android kotlin 高阶函数,Kotlin-高阶函数
  6. 计算机学年教学总结怎么写,计算机教学年终工作总结-
  7. LSQ:LEARNED STEP SIZE QUANTIZATION论文学习
  8. mysql int需要指定长度吗_mysql中为int设置长度除了表明数据长度外还有什么其他的好处?...
  9. 悟空crm前端php,悟空CRM(基于Jfinal+vue+ElementUI)核心代码讲解
  10. 基于C++和OpenCv的SIFT_图像局部特征检测算法代码的实现