0

I am making a calendar program. The 'expand repeating events' code is giving me no end of trouble. I am expanding events by using mktime() to get a 'pure' time value, then adding the repeat delta (in this case, 604800 seconds or 7 days) to it. localtime() is then used to get a calendar struct back out.

This happens:

Original event: September 10

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 10, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 283, tm_isdst = 0, 
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

First repetition: September 17

{tm_sec = 0, tm_min = 0, tm_hour = 17, tm_mday = 17, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 290, tm_isdst = 1, 
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

Second repetition: September 24

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 24, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 297, tm_isdst = 0,
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

Third repetition: September 31?!

{tm_sec = 0, tm_min = 0, tm_hour = 16, tm_mday = 31, tm_mon = 9,
 tm_year = 2012, tm_wday = 4, tm_yday = 304, tm_isdst = 0,
 tm_gmtoff = -25200, tm_zone = 0x608ff0 "PDT"}

Does anyone have any idea what's going on here? Will I have to fill in for localtime() myself?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
SoItBegins
  • 414
  • 1
  • 6
  • 22
  • 3
    Remember that `tm_year` is the number of years since 1900. So if you want year 2012 (this year) it should be 112. – Some programmer dude Dec 01 '12 at 21:36
  • "...It is **not** a compiler error..." (NB: I did not downvote this time - it's a mistake easy to make, I'm sure I'd have done this too...) –  Dec 01 '12 at 21:38

2 Answers2

6

From the documentation: the members of the struct tm structure are 0-based (as usually in C).

int    tm_mon   month of year [0,11]

So actually the month numbered 9 is the 10th month, which is October, and it has 31 days.

caf
  • 233,326
  • 40
  • 323
  • 462
  • Even in the year 3912, which is what `tm_year == 2012` represents. BTW, month numbers are zero-based so they can be used as indices into an array of month names; `tm_mday` is one-based because it's not used as in index (we don't have names for days of the month, "Ides" notwithstanding). – Keith Thompson Dec 01 '12 at 21:42
2

As H2CO3 pointed out, tm_mon is 0-based, so the date was actually October 31st, which makes sense.

I wanted to mention that simply adding 604800 seconds to advance 7 days is probably not what a user would want from a calendar program. 604800 is exactly seven days, but if the user wants a recurring event at 10:00 AM every seven days, adding 604800 seconds will not always result in a time at 10:00 AM because this ignores special considerations like Daylight Saving Time and leap seconds.

What you can do instead is add 7 to tm_mday. Don't worry about exceeding the number of days in the month because mktime() will correct it.

Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193