⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genutils.c

📁 C编写的格式转换程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * genutils.c * * Generic utility routines * * Written by Chad Trabant * ORFEUS/EC-Project MEREDIAN * IRIS Data Management Center * * modified: 2007.228 ***************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "libmseed.h"static hptime_t ms_time2hptime_int (int year, int day, int hour,				    int min, int sec, int usec);/*************************************************************************** * ms_recsrcname: * * Generate a source name string for a specified raw data record in * the format: 'NET_STA_LOC_CHAN' or, if the quality flag is true: * 'NET_STA_LOC_CHAN_QUAL'.  The passed srcname must have enough room * for the resulting string. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *ms_recsrcname (char *record, char *srcname, flag quality){  struct fsdh_s *fsdh;  char network[6];  char station[6];  char location[6];  char channel[6];    if ( ! record )    return NULL;    fsdh = (struct fsdh_s *) record;    ms_strncpclean (network, fsdh->network, 2);  ms_strncpclean (station, fsdh->station, 5);  ms_strncpclean (location, fsdh->location, 2);  ms_strncpclean (channel, fsdh->channel, 3);    /* Build the source name string including the quality indicator*/  if ( quality )    sprintf (srcname, "%s_%s_%s_%s_%c",             network, station, location, channel, fsdh->dataquality);    /* Build the source name string without the quality indicator*/  else    sprintf (srcname, "%s_%s_%s_%s", network, station, location, channel);    return srcname;} /* End of ms_recsrcname() *//*************************************************************************** * ms_strncpclean: * * Copy up to 'length' characters from 'source' to 'dest' while * removing all spaces.  The result is left justified and always null * terminated.  The destination string must have enough room needed * for the non-space characters within 'length' and the null * terminator, a maximum of 'length + 1'. *  * Returns the number of characters (not including the null terminator) in * the destination string. ***************************************************************************/intms_strncpclean (char *dest, const char *source, int length){  int sidx, didx;    if ( ! dest )    return 0;    if ( ! source )    {      *dest = '\0';      return 0;    }  for ( sidx=0, didx=0; sidx < length ; sidx++ )    {      if ( *(source+sidx) == '\0' )	{	  break;	}      if ( *(source+sidx) != ' ' )	{	  *(dest+didx) = *(source+sidx);	  didx++;	}    }  *(dest+didx) = '\0';    return didx;}  /* End of ms_strncpclean() *//*************************************************************************** * ms_strncpopen: * * Copy 'length' characters from 'source' to 'dest', padding the right * side with spaces and leave open-ended.  The result is left * justified and *never* null terminated (the open-ended part).  The * destination string must have enough room for 'length' characters. *  * Returns the number of characters copied from the source string. ***************************************************************************/intms_strncpopen (char *dest, const char *source, int length){  int didx;  int dcnt = 0;  int term = 0;    if ( ! dest )    return 0;    if ( ! source )    {      for ( didx=0; didx < length ; didx++ )	{	  *(dest+didx) = ' ';	}            return 0;    }    for ( didx=0; didx < length ; didx++ )    {      if ( !term )	if ( *(source+didx) == '\0' )	  term = 1;            if ( !term )	{	  *(dest+didx) = *(source+didx);	  dcnt++;	}      else	{	  *(dest+didx) = ' ';	}    }    return dcnt;}  /* End of ms_strncpopen() *//*************************************************************************** * ms_doy2md: * * Compute the month and day-of-month from a year and day-of-year. * * Year is expected to be in the range 1900-2100, jday is expected to * be in the range 1-366, month will be in the range 1-12 and mday * will be in the range 1-31. * * Returns 0 on success and -1 on error. ***************************************************************************/intms_doy2md(int year, int jday, int *month, int *mday){  int idx;  int leap;  int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};    /* Sanity check for the supplied year */  if ( year < 1900 || year > 2100 )    {      ms_log (2, "ms_doy2md(): year (%d) is out of range\n", year);      return -1;    }    /* Test for leap year */  leap = ( ((year%4 == 0) && (year%100 != 0)) || (year%400 == 0) ) ? 1 : 0;  /* Add a day to February if leap year */  if ( leap )    days[1]++;  if (jday > 365+leap || jday <= 0)    {      ms_log (2, "ms_doy2md(): day-of-year (%d) is out of range\n", jday);      return -1;    }      for ( idx=0; idx < 12; idx++ )    {      jday -= days[idx];      if ( jday <= 0 )	{	  *month = idx + 1;	  *mday = days[idx] + jday;	  break;	}    }  return 0;}  /* End of ms_doy2md() *//*************************************************************************** * ms_md2doy: * * Compute the day-of-year from a year, month and day-of-month. * * Year is expected to be in the range 1900-2100, month is expected to * be in the range 1-12, mday is expected to be in the range 1-31 and * jday will be in the range 1-366. * * Returns 0 on success and -1 on error. ***************************************************************************/intms_md2doy(int year, int month, int mday, int *jday){  int idx;  int leap;  int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};    /* Sanity check for the supplied parameters */  if ( year < 1900 || year > 2100 )    {      ms_log (2, "ms_md2doy(): year (%d) is out of range\n", year);      return -1;    }  if ( month < 1 || month > 12 )    {      ms_log (2, "ms_md2doy(): month (%d) is out of range\n", month);      return -1;    }  if ( mday < 1 || mday > 31 )    {      ms_log (2, "ms_md2doy(): day-of-month (%d) is out of range\n", mday);      return -1;    }    /* Test for leap year */  leap = ( ((year%4 == 0) && (year%100 != 0)) || (year%400 == 0) ) ? 1 : 0;    /* Add a day to February if leap year */  if ( leap )    days[1]++;    /* Check that the day-of-month jives with specified month */  if ( mday > days[month-1] )    {      ms_log (2, "ms_md2doy(): day-of-month (%d) is out of range for month %d\n",	       mday, month);      return -1;    }  *jday = 0;  month--;    for ( idx=0; idx < 12; idx++ )    {      if ( idx == month )	{	  *jday += mday;	  break;	}            *jday += days[idx];    }    return 0;}  /* End of ms_md2doy() *//*************************************************************************** * ms_btime2hptime: * * Convert a binary SEED time structure to a high precision epoch time * (1/HPTMODULUS second ticks from the epoch).  The algorithm used is * a specific version of a generalized function in GNU glibc. * * Returns a high precision epoch time on success and HPTERROR on * error. ***************************************************************************/hptime_tms_btime2hptime (BTime *btime){  hptime_t hptime;  int shortyear;  int a4, a100, a400;  int intervening_leap_days;  int days;    if ( ! btime )    return HPTERROR;    shortyear = btime->year - 1900;  a4 = (shortyear >> 2) + 475 - ! (shortyear & 3);  a100 = a4 / 25 - (a4 % 25 < 0);  a400 = a100 >> 2;  intervening_leap_days = (a4 - 492) - (a100 - 19) + (a400 - 4);    days = (365 * (shortyear - 70) + intervening_leap_days + (btime->day - 1));    hptime = (hptime_t ) (60 * (60 * (24 * days + btime->hour) + btime->min) + btime->sec) * HPTMODULUS    + (btime->fract * (HPTMODULUS / 10000));      return hptime;}  /* End of ms_btime2hptime() *//*************************************************************************** * ms_btime2isotimestr: * * Build a time string in ISO recommended format from a BTime struct. * * The provided isostimestr must have enough room for the resulting time * string of 25 characters, i.e. '2001-07-29T12:38:00.0000' + NULL. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *ms_btime2isotimestr (BTime *btime, char *isotimestr){    int month = 0;  int mday = 0;  int ret;  if ( ! isotimestr )    return NULL;  if ( ms_doy2md (btime->year, btime->day, &month, &mday) )    {      ms_log (2, "ms_btime2isotimestr(): Error converting year %d day %d\n",	      btime->year, btime->day);      return NULL;    }    ret = snprintf (isotimestr, 25, "%4d-%02d-%02dT%02d:%02d:%02d.%04d",		  btime->year, month, mday,		  btime->hour, btime->min, btime->sec, btime->fract);    if ( ret != 24 )    return NULL;  else    return isotimestr;}  /* End of ms_btime2isotimestr() *//*************************************************************************** * ms_btime2mdtimestr: * * Build a time string in month-day format from a BTime struct. *  * The provided isostimestr must have enough room for the resulting time * string of 25 characters, i.e. '2001-07-29 12:38:00.0000' + NULL. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *ms_btime2mdtimestr (BTime *btime, char *mdtimestr){   int month = 0;  int mday = 0;  int ret;    if ( ! mdtimestr )    return NULL;    if ( ms_doy2md (btime->year, btime->day, &month, &mday) )    {      ms_log (2, "ms_btime2mdtimestr(): Error converting year %d day %d\n",              btime->year, btime->day);      return NULL;    }    ret = snprintf (mdtimestr, 25, "%4d-%02d-%02d %02d:%02d:%02d.%04d",                  btime->year, month, mday,                  btime->hour, btime->min, btime->sec, btime->fract);  if ( ret != 24 )    return NULL;  else    return mdtimestr;}  /* End of ms_btime2mdtimestr() *//*************************************************************************** * ms_btime2seedtimestr: * * Build a SEED time string from a BTime struct. * * The provided seedtimestr must have enough room for the resulting time * string of 23 characters, i.e. '2001,195,12:38:00.0000' + NULL. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *ms_btime2seedtimestr (BTime *btime, char *seedtimestr){  int ret;    if ( ! seedtimestr )    return NULL;    ret = snprintf (seedtimestr, 23, "%4d,%03d,%02d:%02d:%02d.%04d",		  btime->year, btime->day,		  btime->hour, btime->min, btime->sec, btime->fract);    if ( ret != 22 )    return NULL;  else    return seedtimestr;}  /* End of ms_btime2seedtimestr() *//*************************************************************************** * ms_hptime2btime: * * Convert a high precision epoch time to a SEED binary time * structure.  The microseconds beyond the 1/10000 second range are * truncated and *not* rounded, this is intentional and necessary. * * Returns 0 on success and -1 on error. ***************************************************************************/intms_hptime2btime (hptime_t hptime, BTime *btime){  struct tm *tm;  int isec;  int ifract;  int bfract;  time_t tsec;    if ( btime == NULL )    return -1;    /* Reduce to Unix/POSIX epoch time and fractional seconds */  isec = MS_HPTIME2EPOCH(hptime);  ifract = hptime - ((hptime_t)isec * HPTMODULUS);    /* BTime only has 1/10000 second precision */  bfract = ifract / (HPTMODULUS / 10000);    /* Adjust for negative epoch times, round back when needed */  if ( hptime < 0 && ifract != 0 )    {      /* Isolate microseconds between 1e-4 and 1e-6 precision and adjust bfract if not zero */      if ( ifract - bfract * (HPTMODULUS / 10000) )	bfract -= 1;            isec -= 1;      bfract = 10000 - (-bfract);    }  tsec = (time_t) isec;  if ( ! (tm = gmtime ( &tsec )) )    return -1;    btime->year   = tm->tm_year + 1900;  btime->day    = tm->tm_yday + 1;  btime->hour   = tm->tm_hour;  btime->min    = tm->tm_min;  btime->sec    = tm->tm_sec;  btime->unused = 0;  btime->fract  = (uint16_t) bfract;    return 0;}  /* End of ms_hptime2btime() *//*************************************************************************** * ms_hptime2isotimestr: * * Build a time string in ISO recommended format from a high precision * epoch time. * * The provided isostimestr must have enough room for the resulting time * string of 27 characters, i.e. '2001-07-29T12:38:00.000000' + NULL. * * The 'subseconds' flag controls whenther the sub second portion of the * time is included or not. * * Returns a pointer to the resulting string or NULL on error. ***************************************************************************/char *ms_hptime2isotimestr (hptime_t hptime, char *isotimestr, flag subseconds){  struct tm *tm;  int isec;  int ifract;  int ret;  time_t tsec;  if ( isotimestr == NULL )    return NULL;  /* Reduce to Unix/POSIX epoch time and fractional seconds */  isec = MS_HPTIME2EPOCH(hptime);  ifract = (hptime_t) hptime - (isec * HPTMODULUS);    /* Adjust for negative epoch times */  if ( hptime < 0 && ifract != 0 )    {      isec -= 1;      ifract = HPTMODULUS - (-ifract);    }  tsec = (time_t) isec;  if ( ! (tm = gmtime ( &tsec )) )    return NULL;    if ( subseconds )    /* Assuming ifract has at least microsecond precision */    ret = snprintf (isotimestr, 27, "%4d-%02d-%02dT%02d:%02d:%02d.%06d",                    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,                    tm->tm_hour, tm->tm_min, tm->tm_sec, ifract);  else    ret = snprintf (isotimestr, 20, "%4d-%02d-%02dT%02d:%02d:%02d",                    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,                    tm->tm_hour, tm->tm_min, tm->tm_sec);  if ( ret != 26 && ret != 19 )    return NULL;  else    return isotimestr;}  /* End of ms_hptime2isotimestr() *//***************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -