Set Time and Locale in Ubuntu Linux

服务器的时间是一个不起眼但非常重要的因素。当它是正确的时候,一切平安无事,但是当它 出现问题时,就会造成很多不便,甚至会导致一些依赖时间的应用出现数据上的问题。

本文整理一些关于查看和设置时间的命令,以及本地化locale显示设置的问题。

时间

正确而方便的时间格式,能方便查看文件的修改时间,日志记录的时间等。所谓方便的时间格式, 一方面是时区最好与用户本地时区一致,另一方面是时间格式要符合用户国家和地区的习惯。

正确的时间并不是一个看起来那么简单的问题。达成一般精度的时间是比较容易的,而要达成 非常精确的时间,则需要有效的设计与调校。

时区

Linux的时区信息存放于 /etc/timezone之中,可以直接修改该值,也可以使用系统提供的命令, 比如新版本的Ubuntu上可以通过 timedatectl来修改, 下面的命令将时区改为中国时间.

sudo timedatectl set-timezone Asia/Shanghai

时钟

时钟涉及到时间的准确性. 除了传统的date命令可以显示时间外,timedatectl命令可以显示 更丰富的时间信息

$ date
Thu Jan 12 19:32:02 CST 2017
$ timedatectl
    Local time: Thu 2017-01-12 19:29:31 CST
Universal time: Thu 2017-01-12 11:29:31 UTC
        RTC time: Thu 2017-01-12 11:29:31
    Time zone: Asia/Shanghai (CST, +0800)
Network time on: yes
NTP synchronized: yes
RTC in local TZ: no

NTP

通过NTP能从网络上获取更精准的时间,比如误差在几十毫秒级别。有一些分布式系统对时间 误差很敏感,可以通过运行本地子网的ntpd来最小化这些集群内的服务器时间误差。

本地化显示locale

locale是本地化的意思,也就是可以根据用户的本地语言习惯来查看一些系统信息,比如日期、 货币、界面语言等。

默认的locale存在于/etc/default/locale, 当前会话的locale则可通过运行命令locale查看.

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

LC_MESSAGES 设置消息和界面显示的语言

LC_CTYPE 设置字符集

LC_COLLATE 设置排序字符集

LC_TIME 设置日期和时间的显示语言和格式

LC_NUMERIC 设置数字的显示格式

LC_PAPER: paper size

LC_NAME: personal name format

LC_ADDRESS: address format

LC_TELEPHONE: telephone number format

LC_MEASUREMENT: measurement units

LC_ALL 统一设置所有LC开头的环境变量,它会覆盖其他的LC环境变量

LANG 是最后的默认语言,即既没有设置LC_ALL, 也没有设置具体的LC时会采用LANG的值

LANGUAGE 环境变量则只针对GUI的显示, 对于GUI它的效果是覆盖LC及LANG设置。在LANGUAGE 设置中可以按优先顺序定义多个语言及字符集, 以冒号分割.

locale异常

locale: Cannot set LC_ALL to default locale: No such file or directory

通过ssh访问远程Linux服务器时,默认会把本地机器的LC_环境变量带到远程会话中,有时候 会遇到这种情况,并不是因为LC_ALL的设置不正确,而是因为LC_环境变量所使用的locale值有 一些在该系统中并不存在。

在Ubuntu中,比较简单的做法是安装locales-all的软件包,这样无论从哪里访问该系统时, 都能正确地显示本地化内容。

另外一种省事的办法是在用户的profile中定义LC_ALL, 使得LC_ALL与该系统默认的保持一致。 这样做的缺点是远程用户不再能够以他的本地化语言习惯来查看信息。

还有一种针对ssh的解决办法,是将ssh_config的 "SendEnv LANG LC_*" 注释掉.