How do I find the current system timezone?

后端 未结 12 444
攒了一身酷
攒了一身酷 2020-11-30 06:22

On Linux, I need to find the currently configured timezone as an Olson location. I want my (C or C++) code to be portable to as many Linux systems as possible.

For e

12条回答
  •  醉梦人生
    2020-11-30 07:11

    I see two major linux cases:

    1. Ubuntu. There should be a /etc/timezone file. This file should only contain the timezone and nothing else.
    2. Red Hat. There should be a /etc/sysconfig/clock that contains something like: ZONE="America/Chicago"

    In addition, Solaris should have an /etc/TIMEZONE file that contains a line like: TZ=US/Mountain

    So based on the above, here is some straight C that I believe answers the OP's question. I have tested it on Ubuntu, CentOS (Red Hat), and Solaris (bonus).

    #include 
    #include 
    #include 
    
    char *findDefaultTZ(char *tz, size_t tzSize);
    char *getValue(char *filename, char *tag, char *value, size_t valueSize);
    
    int main(int argc, char **argv)
    {
      char tz[128];
    
      if (findDefaultTZ(tz, sizeof(tz)))
        printf("Default timezone is %s.\n", tz);
      else
        printf("Unable to determine default timezone.\n");
      return 0;
    }
    
    
    char *findDefaultTZ(char *tz, size_t tzSize)
    {
      char *ret = NULL;
      /* If there is an /etc/timezone file, then we expect it to contain
       * nothing except the timezone. */
      FILE *fd = fopen("/etc/timezone", "r"); /* Ubuntu. */
      if (fd)
      {
        char buffer[128];
        /* There should only be one line, in this case. */
        while (fgets(buffer, sizeof(buffer), fd))
        {
          char *lasts = buffer;
          /* We don't want a line feed on the end. */
          char *tag = strtok_r(lasts, " \t\n", &lasts);
          /* Idiot check. */
          if (tag && strlen(tag) > 0 && tag[0] != '#')
          {
            strncpy(tz, tag, tzSize);
            ret = tz;
          }
        }
        fclose(fd);
      }
      else if (getValue("/etc/sysconfig/clock", "ZONE", tz, tzSize)) /* Redhat.    */
        ret = tz;
      else if (getValue("/etc/TIMEZONE", "TZ", tz, tzSize))     /* Solaris. */
        ret = tz;
      return ret;
    }
    
    /* Look for tag=someValue within filename.  When found, return someValue
     * in the provided value parameter up to valueSize in length.  If someValue
     * is enclosed in quotes, remove them. */
    char *getValue(char *filename, char *tag, char *value, size_t valueSize)
    {
      char buffer[128], *lasts;
      int foundTag = 0;
    
      FILE *fd = fopen(filename, "r");
      if (fd)
      {
        /* Process the file, line by line. */
        while (fgets(buffer, sizeof(buffer), fd))
        {
          lasts = buffer;
          /* Look for lines with tag=value. */
          char *token = strtok_r(lasts, "=", &lasts);
          /* Is this the tag we are looking for? */
          if (token && !strcmp(token, tag))
          {
            /* Parse out the value. */
            char *zone = strtok_r(lasts, " \t\n", &lasts);
            /* If everything looks good, copy it to our return var. */
            if (zone && strlen(zone) > 0)
            {
              int i = 0;
              int j = 0;
              char quote = 0x00;
              /* Rather than just simple copy, remove quotes while we copy. */
              for (i = 0; i < strlen(zone) && i < valueSize - 1; i++)
              {
                /* Start quote. */
                if (quote == 0x00 && zone[i] == '"')
                  quote = zone[i];
                /* End quote. */
                else if (quote != 0x00 && quote == zone[i])
                  quote = 0x00;
                /* Copy bytes. */
                else
                {
                  value[j] = zone[i];
                  j++;
                }
              }
              value[j] = 0x00;
              foundTag = 1;
            }
            break;
          }
        }
        fclose(fd);
      }
      if (foundTag)
        return value;
      return NULL;
    }
    

提交回复
热议问题