6

Emacs 比系统时间差两个小时。我试图用谷歌搜索这个问题,但没有运气。我需要配置什么来纠正这个问题?我怀疑这是从 GMT 到我住的地方的差异(我在 GMT+2 区域,也就是说,如果我从系统时间 2 中减去,我会在 Emacs 中得到时间)。所以......也许是一些语言环境设置?

我只是因为这个搞砸了一个 git 存储库:通过magit使用 Emacs 时间进行的提交,并将它们放在其他人的提交之前:(

在此处输入图像描述

在这里,我添加了一个显示差异的屏幕截图。的输出date是正确的时间,但模式线边缘的时间是错误的。

编辑0:

看来 Stefan 是对的,Git 中的时间与 Emacs 中的时间没有关联(下面的屏幕截图来自 Cygwin 终端)。

这个问题与 Git 和 Emacs 一样重要——不知何故,他们正在使用一些在我的 PC 上不同步的系统 API——这是我需要设置的东西以使它们对齐。问题是他们都使用的设置是什么?

在此处输入图像描述

编辑1:

这是 Emacs 用来检索时间的代码,afaik:

/* Emulate gettimeofday (Ulrich Leodolter, 1/11/95).  */
int
gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz)
{
  struct _timeb tb;
  _ftime (&tb);

  tv->tv_sec = tb.time;
  tv->tv_usec = tb.millitm * 1000L;
  /* Implementation note: _ftime sometimes doesn't update the dstflag
     according to the new timezone when the system timezone is
     changed.  We could fix that by using GetSystemTime and
     GetTimeZoneInformation, but that doesn't seem necessary, since
     Emacs always calls gettimeofday with the 2nd argument NULL (see
     current_emacs_time).  */
  if (tz)
    {
      tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich  */
      tz->tz_dsttime = tb.dstflag;  /* type of dst correction  */
    }
  return 0;
}

看起来它tz出错了。我不知道是什么_ftime- 但它似乎没有在 Emacs 的来源中定义,这一定来自其他地方......

更多研究:

从 MSI 安装的 SBCL 给出了这个:

(defconstant *day-names*
    '("Monday" "Tuesday" "Wednesday"
      "Thursday" "Friday" "Saturday" "Sunday"))
(multiple-value-bind
    (second minute hour date month year day-of-week dst-p tz)
    (get-decoded-time)
    (format t "It is now ~2,'0d:~2,'0d:~2,'0d of ~a, ~d/~2,'0d/~d (GMT~@d)"
          hour minute second (nth day-of-week *day-names*)
          month date year (- tz)))

输出:(实际时间是12:56)

It is now 10:56:55 of Tuesday, 6/04/2013 (GMT+0)

来自 ActivePerl 的 Perl(从 Cygwin 安装):

$now = localtime;
print $now;

输出:(实际时间是12:52)

Tue Jun  4 12:52:17 2013

CPython,从 MSI 安装。

import datetime
str(datetime.datetime.now())

输出:(实际时间是13:03)

2013-06-04 11:03:49.248000

从 MSI 安装的 JavaScript、Node.js:

Date();

输出:(实际时间是12:09)

Tue Jun 04 2013 10:09:05 GMT+0000 (IST)

重击(Cygwin):

$ date

输出:(实际时间是13:10)

04 Jun, 2013 13:10:37

C#:

using System;

namespace TestTime
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime d = DateTime.Now;
            Console.WriteLine("Today: {0}", d);
            Console.ReadLine();
        }
    }
}

输出:(实际时间是13:13)

Today: 04-Jun-13 13:13:37

编辑2:

今天我们的系统管理员给了我一个虚拟机来移动我的东西。有趣的是,这次我通过 Cygwin 获取了 Git,现在 Git 显示了正确的时间。然而,Emacs 仍然显示错误的时间。Python,(不是与 Cygwin 捆绑的)如果从 Cygwin 启动则显示正确的时间,如果从 Emacs 启动则显示错误的时间!SBCL 无论如何启动都会显示错误的时间。

这可能是一些网络设置吗?也许与 Windows 如何同步系统时间有关?

4

2 回答 2

1

Windows 程序从您通过控制面板设置的系统获取时区信息。时间本身也可以手动设置,但更常见的做法是让 Windows 通过Windows 时间服务(基于 NTP;有关用法,请参阅WinXP 支持文章)与时间服务器同步。AFAIK Windows 时间服务与时区无关,是该问题中唯一与网络相关的事物。

理论上,Cygwin 程序的行为方式应该与在任何其他 *NIX 上的行为方式相同。他们从/etc/localtime文件TZ环境变量中获取时区信息。在我的情况下(Debian),/etc/localtime是 的副本/usr/share/zoneinfo/Europe/Prague,但它也可能是指向该位置的符号链接。TZ可以包含相对于的路径/usr/share/zoneinfo并优先于/etc/localtime.

实践是另一回事。根据Cygwin mailing list 上的一个线程,Microsoft C 运行时 (mscrt*.dll) 的时区处理非常过时,它用于非 Cygwin 程序。这与您得到的结果一致。相关技术信息在2005 年 8 月的一个线程2010 年 5 月的一个相关线程中。

已经在 SO 上发布了针对 Python 的解决方法,C++ 完全相同,它对 MSCRT 问题的解释比之前链接的线程更简短。

也许 Emacs 与这个问题有一些特殊的关系。2009 年 2 月关于 GNU Emacs 开发人员邮件列表的消息报告 Emacs 22.3 显示正确的时间,而 Emacs 23 则没有。根据回复的建议,作者将报告发布到 Cygwin 邮件列表,但没有得到回复。2012 年 12 月,通过记录问题及其解决方法(请参阅 参考资料)解决了该问题/usr/share/doc/Cygwin/emacs.README我没有 Cygwin,也无法在其 CVS 中找到此文件,因此请使用那里的信息编辑我的答案。

就我个人而言,我认为在您的设置(和导出)TZ 环境变量~/.profile是一个好主意。Cygwin 显然已经破坏了时区处理,因此覆盖所有相关内容应该是最安全的做法,因为它只为黑魔法留下了一点空间。也许tzset会起作用,也许不会,您必须将时区设置为恒定值。

尝试在 Cygwin.com 上搜索“时区”以获取更多资源。

于 2013-11-05T23:58:09.960 回答
1

因为这是我在搜索“emacs time wrong windows”时得到的唯一相关搜索结果,所以我会记下我做了什么。

我在两个不同的时区使用 emacs,所以我编写了一个脚本来从 ipinfo.io 更新我的 emacs 位置并输出以下内容:

(setenv "TZ" "Asia/Shanghai")
(set-time-zone-rule "Asia/Shanghai")

这在 Linux 和 macOS 上运行良好,但是,它在 Windows 10 上不起作用。Windows 上的功能set-time-zone-rule在某种程度上被破坏了。跑步

(current-time-zone)

(28800 "CST")在 Ubuntu 和(0 "Asi")Windows 上提供。所以我在 Windows 上显示了错误的时间。

但是,以下确实有效:

(set-time-zone-rule nil)

(current-time-zone)给出(28800 "China Standard Time"),这有效。

我还发现,如果我将 TZ 环境变量设置为“亚洲/上海”,那么 emacs 将没有正确的时间。如果我取消设置 TZ,时间是正确的。无论如何,set-time-zone-nilnil工作,因为在这种情况下,emacs 将从系统中获取时间。

我的猜测是 OP 可能已经设置了 TZ 环境变量,这搞砸了 emacs 和 git。

希望这会有用。

于 2020-11-18T11:48:47.813 回答