----------------------------------------------------------------------
--然后就可以用我写的这个函数来取农历日期了
CREATE FUNCTION fn_GetLunar(@solarDay DATETIME)    
RETURNS datetime  
  
AS    
BEGIN    
  DECLARE @solData int    
  DECLARE @offset int    
  DECLARE @iLunar int    
  DECLARE @i INT     
  DECLARE @j INT     
  DECLARE @yDays int    
  DECLARE @mDays int    
  DECLARE @mLeap int    
  DECLARE @mLeapNum int    
  DECLARE @bLeap smallint    
  DECLARE @temp int    
    
  DECLARE @YEAR INT     
  DECLARE @MONTH INT    
  DECLARE @DAY INT    
      
  DECLARE @OUTPUTDATE DATETIME    
  
  --保证传进来的日期是不带时间    
  SET @solarDay=cast(@solarDay AS char(10))    
  SET @offset=CAST(@solarDay-'1900-01-30' AS INT)  
  
    
  --确定农历年开始    
  SET @i=1900    
  --SET @offset=@solData    
  WHILE @i<2050 AND @offset>0    
  BEGIN    
    SET @yDays=348    
    SET @mLeapNum=0    
    SELECT @iLunar=dataInt FROM SolarData WHERE yearId=@i    
    
    --传回农历年的总天数    
    SET @j=32768    
    WHILE @j>8    
    BEGIN    
      IF @iLunar & @j >0    
        SET @yDays=@yDays+1    
      SET @j=@j/2    
    END    
    
    --传回农历年闰哪个月 1-12 , 没闰传回 0    
    SET @mLeap = @iLunar & 15    
    
    --传回农历年闰月的天数 ,加在年的总天数上    
    IF @mLeap > 0    
    BEGIN    
      IF @iLunar & 65536 > 0    
        SET @mLeapNum=30    
      ELSE     
        SET @mLeapNum=29    
    
      SET @yDays=@yDays+@mLeapNum    
    END    
        
    SET @offset=@offset-@yDays    
    SET @i=@i+1    
  END    
      
  IF @offset <= 0    
  BEGIN    
    SET @offset=@offset+@yDays    
    SET @i=@i-1    
  END    
  --确定农历年结束      
  SET @YEAR=@i    
  
  --确定农历月开始    
  SET @i = 1    
  SELECT @iLunar=dataInt FROM SolarData WHERE yearId=@YEAR  
  
  --判断那个月是润月    
  SET @mLeap = @iLunar & 15    
  SET @bLeap = 0   
  
  WHILE @i < 13 AND @offset > 0    
  BEGIN    
    --判断润月    
    SET @mDays=0    
    IF (@mLeap > 0 AND @i = (@mLeap+1) AND @bLeap=0)    
    BEGIN--是润月    
      SET @i=@i-1    
      SET @bLeap=1    
      --传回农历年闰月的天数    
      IF @iLunar & 65536 > 0    
        SET @mDays = 30    
      ELSE     
        SET @mDays = 29    
    END    
    ELSE    
    --不是润月    
    BEGIN    
      SET @j=1    
      SET @temp = 65536     
      WHILE @j<=@i    
      BEGIN    
        SET @temp=@temp/2    
        SET @j=@j+1    
      END    
    
      IF @iLunar & @temp > 0    
        SET @mDays = 30    
      ELSE    
        SET @mDays = 29    
    END    
      
    --解除闰月  
    IF @bLeap=1 AND @i= (@mLeap+1)  
      SET @bLeap=0  
  
    SET @offset=@offset-@mDays    
    SET @i=@i+1    
  END    
    
  IF @offset <= 0    
  BEGIN    
    SET @offset=@offset+@mDays    
    SET @i=@i-1    
  END    
  
  --确定农历月结束      
  SET @MONTH=@i  
    
  --确定农历日结束      
  SET @DAY=@offset    
    
  SET @OUTPUTDATE=CAST((CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) AS DATETIME)    
  RETURN @OUTPUTDATE  
END   ----------------------------------------------------------------------
--调用方法
select dbo.fn_GetLunar(getdate())

解决方案 »

  1.   

    Gooooooooooooooooooooooooooooooooood!
    高!
    收藏!
      

  2.   

    做这个纯属一时兴起,实际中也没有什么用处!只是作为程序员,写点这个,提高一下自己的SQL熟练纯度!
      

  3.   

    你搞这个作什么哟
    老板给了你多少money
      

  4.   

    to : hmzgz81(哩翱) 这个表是农历年的数据,每一年一个,都是天文学家推算出来的,具体要问天文学家!CREATE TABLE SolarData
    (
        yearId int not null,       -- 年份
        data char(7) not null,     -- 十六进制数据,在计算中没有用到,因为SQL不能处理
        dataInt int not null       -- 十进制数据,把十六进制数据转换来,根据这个计算
    )
      

  5.   

    To xmlandnet() :我没事偷着乐,所以搞这个!可以吗?也没有人给我钱!
      

  6.   

    Server: Msg 242, Level 16, State 3, Procedure fn_GetLunar, Line 25
    The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
      

  7.   

    修改上面的错误:因时间格式的错误
      SET @solarDay=cast(@solarDay AS char(10))    
    该为 SET @solarDay=convert(char(10),@solarDay,120)    
      

  8.   

    data char(7) not null,--这个好象没用。
        dataInt int not null--跟上面DATA是一样的数值。
      

  9.   

    to J老师
       确实没有用到,因为SQL中处理十六进制数据好像不行!CREATE TABLE SolarData
    (
        yearId int not null,       -- 年份
        data char(7) not null,     -- 十六进制数据,在计算中没有用到,因为SQL不能处理
        dataInt int not null       -- 十进制数据,把十六进制数据转换来,根据这个计算
    )
      

  10.   

    declare @a table (a varbinary(10))
    insert @a select 0x0205