During my tests I noticed what i think is an issue in some of the date routines related to offset or possibly daylight savings time. I tried to implement a newlisp version of days_in_month.
(Note: I'm in Austin, TX CDT which means my GMT offset is -0500 ==> 300 offset)
(Also note that if I use (date-value) without any options I don't need to specify an offset to get the correct datetime)
Code: Select all
newLISP v.9.3.5 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.
> (date (date-value 2008 1 1) 300 "%Y %m %d")
"2007 12 31"
> (date (date-value) 0 "%Y %m %d"))
"2008 03 30"
Code: Select all
> (date (date-value) 300 "%z")
"-0500"
> (date (date-value 2008 3 1 0 0 0) 300 "%d")
"29"
> (date (date-value 2008 3 1 0 0 1) 300 "%d")
"29"
> (date (date-value 2008 3 1 1 0 0 ) 300 "%d")
"01"
Upon further investigation I found this
Code: Select all
> (date (date-value 2008 4 1) 300 "%Y %m %d")
"2008 04 01"
Code: Select all
> (date (date-value 2008 3 8) 300 "%Y %m %d")
"2008 03 07"
> (date (date-value 2008 3 9) 300 "%Y %m %d")
"2008 03 08"
> (date (date-value 2008 3 10) 300 "%Y %m %d")
"2008 03 10"
> (date (date-value 2008 3 9 1 0 0) 300 "%Y %m %d")
"2008 03 09"
> (date (date-value 2008 3 8 1 0 0) 300 "%Y %m %d")
"2008 03 08"
My hackish workaround is to take the time at 3am.
But I'm hoping there's a better way.
So finally ... here's a newlisp days-in-month
Code: Select all
(define (days-in-month y m)
(set 'tmp (date (date-value) 0 "%z"))
(set 'offset (+ (* (int (1 2 tmp)) 60) (int (3 2 tmp))))
(if (= "+" (0 1 tmp)) (set 'offset (* -1 offset)))
(int (date (date-value y (+ m 1) 0 3 0 0) offset "%d"))
)
> (days-in-month 2008 2)
29
> (days-in-month 2007 2)
28
> (days-in-month 2008 3)
31
> (days-in-month 2008 4)
30