c - setlocale()无法正常工作

时间:2015-10-14 05:28:51

标签: c locale

以下程序使用setlocale()从环境变量和打印时间中获取区域设置。

locale_test.c

// locale test

#include <stdio.h>
#include <locale.h>
#include <time.h>

// locale test
void locale_test() {
    // use environment variable to get locale setting,
    setlocale(LC_ALL, "");

    char buf[26];
    time_t now = time(NULL);
    ctime_r(&now, buf);
    printf("time: %s", buf);

    char *time_locale = setlocale(LC_TIME, NULL);
    printf("current LC_TIME locale: %s\n", time_locale);
}

int main(int argc, char *argv[]) {
    locale_test();
    return 0;
}

执行:

  • LC_ALL=fr_FR LC_TIME=fr_FR ./a.out,输出为:

      

    时间:2015年10月14日星期三13:16:35
      当前LC_TIME语言环境:C

  • LC_ALL=en_US LC_TIME=en_US ./a.out,输出为:

      

    时间:2015年10月14日星期三13:17:12   当前LC_TIME语言环境:C

问题是:

  • 由于语言环境不同,2执行的结果预计会有不同的格式,但它们是一样的,为什么?
  • 当尝试获取当前LC_TIME时,它只打印C,但不打印环境变量中指定的值。

更新 - 解决方案:

根据评论&amp;回答,做出以下修改:

  • locale -a
  • 的结果中使用正确的区域设置名称
  • 使用strftime()生成时间字符串,而不是ctime()

新计划:

// locale test

#include <stdio.h>
#include <locale.h>
#include <time.h>

// locale test
void locale_test() {
    // use environment variable to get locale setting,
    if(setlocale(LC_ALL, "") == NULL) {
        printf("error while setlocale()\n");
    }

    // get current LC_TIME
    char *time_locale = setlocale(LC_TIME, NULL);
    if(time_locale == NULL) {
        printf("error while setlocale()\n");
    } else {
        printf("LC_TIME: %s\n", time_locale);
    }

    // print time in locale,
    size_t buf_size = 50;
    char buf[buf_size];
    // char *format = "%F %T %z";
    char *format = "%A, %d %B %Y, %H:%M:%S %Z";

    time_t now = time(NULL);
    struct tm tm_now;
    localtime_r(&now, &tm_now);

    strftime(buf, buf_size, format, &tm_now);
    printf("time: %s\n", buf);
}

int main(int argc, char *argv[]) {
    locale_test();
    return 0;
}

然后执行:

  • LC_ALL=en_US.utf8 LC_TIME=en_US.utf8 ./a.out,输出为:

      

    LC_TIME:en_US.utf8
      时间:2015年10月14日,星期三,中部标准时间16:36:36

  • LC_ALL=zh_CN.utf8 LC_TIME=zh_CN.utf8 ./a.out,输出为:

      

    LC_TIME:zh_CN.utf8
      时间:星期三,14十月2015,16:38:10 CST

  • LC_ALL=en_US.utf8 LC_TIME=en_US.utf8 ./a.out,输出为:

      

    LC_TIME:ja_JP.utf8
      时间:水曜日,14 10月2015年,16:40:05 CST

这就像预期的那样工作。

1 个答案:

答案 0 :(得分:4)

您必须检查def create params[:attendee_id].each do |user_id| Invitation.create(:attended_event_id => params[:attended_event_id], :attendee_id => user_id) end . . . end 的返回值,因为如果区域设置字符串无效,未安装所需的区域设置或其他原因,它将失败。

setlocale

您可以查看if (setlocale(LC_ALL, "") == NULL) { puts("Unable to set locale"); } 可用的区域设置。也许您确实安装了法语区域设置,但必须使用locale -a进行设置。

然后,fr_FR.utf8输出不依赖于语言环境; standard指定其确切格式,并且始终为英文。对于本地化输出,请改为使用ctime