addDays :: (Int,Int,Int) -> Int -> (Int,Int,Int)
addDays (dd,mm,yy) daystoadd =
let yearType = if((yy `mod` 4 ==0) && ((yy `mod` 100 /=0)||(yy `mod` 400 ==0)))
then [31,29,31,30,31,30,31,31,30,31,30,31]
else [31,28,31,30,31,30,31,31,30,31,30,31]
sumYear = (sum yearType)
daysGone =sum ( (take (mm-1) ) yearType ) + dd
totalDays = daysGone + daystoadd
yearsOverflow = totalDays `div` sumYear
totalDays1 = totalDays `mod` sumYear
year = yy+yearsOverflow
monthsGone =last ( takeWhile (\x -> sum x <=totalDays1) ((inits(yearType) ) ) )
daysofMonth = if (totalDays1 - (sum monthsGone) == 0)
then ( yearType!!(mm-1) )
else if (totalDays1 <= (yearType!!(mm-1)) )
then totalDays1
else (totalDays1 - (sum monthsGone) )
noofMonths = if (monthsGone/= [])
then if ( ((length monthsGone) )>12)
then ((length monthsGone)+1-12 )
else if( (last monthsGone) == daysofMonth )
then ( (length monthsGone) ) --then ( (length monthsGone)+2 )
else ( (length monthsGone)+1 )
else (length monthsGone) +1
in (daysofMonth,noofMonths, year)
我已编写此功能以添加日期的天数。但是,如果我想从2000年5月1日起增加400天,那么每当它超过31日时,就会使用相同月份的闰年。如何再次使用非闰年?
我面临的另一个问题是月份有30天,月份会在下个月的月末发生变化。
有什么建议吗?
Dan Robertson解释道 我做了这个import Data.List
isLeapYear :: Int -> Bool
isLeapYear x = ((x `mod` 4 ==0) && ((x `mod` 100 /=0)||(x `mod` 400 ==0)))
yearLength :: Int -> Int
yearLength n = if (isLeapYear n) then 366 else 365
monthLength :: Int -> Int -> [Int]
monthLength mm yy =
let months = if isLeapYear yy
then [31,29,31,30,31,30,31,31,30,31,30,31]
else [31,28,31,30,31,30,31,31,30,31,30,31]
in months
leftInMonth :: (Int,Int,Int) -> Int
leftInMonth (dd,mm,yy) = ( (monthLength mm yy) !! (mm-1) ) - dd + 1
daysSinceYearBegan :: (Int,Int,Int) -> Int
daysSinceYearBegan (dd,mm,yy) =if(mm==1)
then dd
else
dd + sum( take (mm-1) (monthLength mm yy) )
leftInYear :: (Int,Int,Int) -> Int
leftInYear (dd,mm,yy) = yearLength (yy) - (daysSinceYearBegan (dd,mm,yy) ) +1
addDays :: (Int,Int,Int) -> Int -> (Int,Int,Int)
addDays (dd,mm,yy) days =
if ( days >= leftInYear (dd,mm,yy))
then addDays (1,1,(yy+1)) (days- (leftInYear (dd,mm,yy)) )
else if ( days >= leftInMonth (dd,mm,yy) )
then if((mm)<=12 )
then addDays (dd,mm+1,yy) (days- (leftInMonth (dd,mm,yy) ) )
else addDays (1,1,yy+1) (days- (leftInMonth (dd,mm,yy) ) )
else ( (dd + days),mm,yy)
答案 0 :(得分:2)
这是如何解决问题的草图。我们将坚持公历(所以像闰年这样的事情以及月份是固定的)。
我们需要一个日期的数据类型。
data Date = Date {year :: Int, month :: Int, day :: Int }
您可以在月份和日期使用较小的类型,但我认为没有充分理由限制年限。您还可以使用具有1月,2月等变体的月份类型。我们将从1到12编号。
一年中有多少天?
leapYear n = n `mod` 4 == 0 && (n `mod` 100 /= 0 || n `mod` 400 == 0)
yearLength n = if leapYear n then 366 else 365
一个月有多少天?
monthLength year month = months !! month where
months = if leapYear year then months2 else months1
months1 = [31,28,31,30,31,30,31,31,30,31,30,31]
months2 = [31,29,31,30,31,30,31,31,30,31,30,31]
现在我们如何添加一些日期? 首先,我们计算出要继续前进多少年。然后多少个月。然后多少天。所以我们想知道一个月或一年剩下多少天。
leftInMonth (Date year month day) = monthLength year month - day + 1
daysSinceYearBegan (Date year month day) = previousMonths + day - 1 where
previousMonths = sum [monthLength m | m <- [1..month - 1]]
leftInYear date = yearLength (year date) - daysSinceYearBegan date
现在添加天数:
addDays date 0 = date
addDays (Date year 1 1) days
| days < 0 = undefined
| days >= yearLength year = addDays (Date (year+1) 1 1) (days - yearLength year)
addDays d@(Date year month day) days
| days < 0 = undefined
| days >= leftInYear d = addDays (Date (year+1) month day) (days - leftInYear d)
| days >= leftInMonth year month = addDays (if month == 12 then Date (year+1) 1 1) else Date year (month+1) 1) (days - leftInMonth year month)
| otherwise = Date year month (day + days)
我不确定它是否完美,但应该给你一些更合理的工作