Reading Daylight Saving Time in Linux using C/C++

Hi folks,
I would like to read the start date and end date of the Daylight Saving Time for the given timezone in the given year. What's the function in C/C++ to read the start of the Daylight Saving date and end of Daylight saving date?

I'm using Linux 2.6.xx Kernel.

For Example, in Pacific Time (US & Canada) the Daylight Start date for the year 2009 is Mar 9,2009 and it ended on Nov 1, 2009. I need a C/C++ function to read these dates.

Thanks in Advance,
Surya

I am not sure if C/C++ libraries has anything to do with the Linux kernel being used. You may need to check C/C++ documentation for the implementation.

There are no standardized APIs for accessing the data you want from the relevant zoneinfo files. However if you do an Internet search for "ttisstdcnt" and "detzone" you will find plenty of examples of how it is done.

I stayed out of this one for a while. Anytime you make assumptions about timezone or date you get in trouble - of all applications, calendrics and time get mishandled the most, IMO.

The std C runtime plus the environment is the final arbiter on what the system thinks about time and date.

This code is a rather stupid (with no error checking) brute force solution. It has assumptions: 32 bit system, years from 1970-2037, 2 ds time changes per year, and we are N of the equator. That way "start ds" is the first change we will hit if we begin Jan 01. Use at your own risk.

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>

#define FULL_FMT "%m-%d-%Y"
#define DT_LEN 80
#define TZ_LEN 28
#define DAY 86400

typedef
struct
{
  char start[DT_LEN];
  char tz1[TZ_LEN];  
  char end[DT_LEN];
  char tz2[TZ_LEN];
  
} dsavings_t;

char *sec2dt(char *dest, time_t sec, const char *fmt, char *cmp, dsavings_t *ds)
{
	struct tm *p=localtime(&sec);
	*dest=0x0;

	strftime(dest, DT_LEN, fmt, p);
	if(cmp!=NULL && strcmp(cmp, dest))
	{
		strcpy(   (*ds->tz1)?   ds->tz2: ds->tz1, cmp);
		strftime( (*ds->start)? ds->end: ds->start, DT_LEN, FULL_FMT, p);
		strcpy(cmp, dest);
	}
	return dest;
}

int tzshift(dsavings_t *ds, const int year)
{
	  struct tm w={0,0,0,0,0,0,0,0,0};
	  int i=0;
	  char tmp[DT_LEN]={0x0};
	  char tz[DT_LEN]={0x0};
	  time_t lt=0;
	  memset(ds, 0x0, sizeof(dsavings_t));	 	  
    sprintf(tmp,"01-01-%4d-23:00", year);
	  strptime(tmp, "%d-%m-%Y-%H:%M", &w);
	  lt=mktime(&w);
	  sec2dt(tz, lt, "%Z", NULL, NULL);
	  /*lt+=DAY; */
	  for(i=0; *(sec2dt(tmp, lt, "%Z", tz, ds)) && i<366; i++, lt+=DAY);	    
	  return (*ds->start && *ds->end)? 1 : 0;
}

int main(int argc, char **argv)
{
	  int yr=0;
	  dsavings_t ds={ {0x0}, {0x0} };
	  int retval=0;
	  for(yr=1970; yr < 2038; yr++)
	  {
	  		retval=tzshift(&ds, yr);
	  		printf("%d: %s (%s)  %s (%s)\n", yr, 
	  		       (retval) ? ds.start : "None",
	  		       (retval) ? ds.tz1 : "",
	  		       (retval) ? ds.end : "None",
	  		       (retval) ? ds.tz2 : "");
	  }
	  return 0;
}

Thanks a lot, folks.