Closed Mikachu2333 closed 1 month ago
szenius/set-timezone
设置时区datatime2
文档(v1.5.7, 2021-03-21)sec. 10.3 Saving Dates 末尾的例子,列举了获取日期和时间各个部分的命令。看起来默认就是 two digits 的(除了获取 day of week 的 \DTMfetchdow
),所以可以不用 \DTMtwodigits
。\documentclass{article}
\usepackage[calc]{datetime2}
\begin{document}
\obeylines % treat line end as \par
\DTMsavenow{now}
Year: \DTMfetchyear{now}.
Month: \DTMfetchmonth{now}.
Day: \DTMfetchday{now}.
DOW: \DTMfetchdow{now}.
Hour: \DTMfetchhour{now}.
Minute: \DTMfetchminute{now}.
Second: \DTMfetchsecond{now}.
Time Zone Hour: \DTMfetchTZhour{now}.
Time Zone Minute: \DTMfetchTZminute{now}.
\end{document}
得到
Year: 2024.
Month: 05.
Day: 17.
DOW: 4.
Hour: 03.
Minute: 16.
Second: 09.
Time Zone Hour: +08.
Time Zone Minute: 00.
用 XeLaTeX 编译后,日志文件输出一切正常,无问题发生
「一切正常,无问题发生」可能带来误导,建议更明确地指出「现在的结果和想要的结果之间的差别」。比如,结合你的问题描述,我猜测差别是没能获取秒、时区是硬写的 GTM+9 GTM+8 和时间不匹配。可以直接地描述出来「哪些实现了、哪些还没实现」,避免让他人猜。
我猜测差别是没能获取秒、时区是硬写的 GTM+9 和时间不匹配
的确如此,感谢指正,下次提问时会注意拆分问题并明确描述。
另,已更正上面的问题使之对后来者更清晰易懂。
此外,我倾向于您给出的第二个解决方案,即通过latex本身获取详细时间与日期并格式化为东八区时间而非通过设置github actions的时区来迁就,以免在其他设备编译时因为忘记设置而错误地获取时间。
结合上面的上面的问题及参考资料,我发现了一种比较完善的解决方案(但是从实现原理上来讲还是很生硬,例如因为没读明白doc导致format的时候只能自己硬生生每项获取再硬写),如下所示。
注,必须使用latexmk(xe)编译
main.tex
\documentclass{article}
\usepackage{texosquery}%xelatex取秒数及时区
\usepackage[calc]{datetime2}
\newcommand{\CurrentCustomTime}{
\DTMsavenow{Compiled_time}%保存编译时间
\DTMfetchyear{Compiled_time}.%
\DTMfetchmonth{Compiled_time}.%
\DTMfetchday{Compiled_time}\quad%
\DTMfetchhour{Compiled_time}:%
\DTMfetchminute{Compiled_time}:%
\DTMfetchsecond{Compiled_time}%
\quad%
GMT+08:00
}
\begin{document}
\CurrentCustomTime
\end{document}
latexmkrc
本项的设置可保证无论在何种时区下编译均可正确转换为东八区时间,因此此时可以在main文档里硬写GMT+08:00
$ENV{'TZ'}='Asia/Shanghai';
效果
2024.05.17 09:43:10 GMT+08:00
此外,我倾向于您给出的第二个解决方案,即通过latex本身获取详细时间与日期并格式化为东八区时间而非通过设置github actions的时区来迁就,以免在其他设备编译时因为忘记设置而错误地获取时间。
我的本意是同时使用那两条,是「且」的关系。
\usepackage{texosquery}%xelatex取秒数及时区
我感觉不用加载 texosquery
。XeTeX 直接提供了 primitive \creationdate
,datetime2
会按不同引擎使用相应的 primitive,无需通过 texosquery
执行 java 再获取一遍。
建议在 \CurrentCustomTime
里用 \DTMfetchTZhour
和 \DTMfetchTZminute
来获取时区信息,而不是手动写死 GMT+08:00
。手动写死会比较难发现(latexmkrc 设置失效的)错误。
- 所以可以不用
\DTMtwodigits
我感觉不用加载
texosquery
。XeTeX 直接提供了 primitive\creationdate
,datetime2
会按不同引擎使用相应的 primitive,无需通过texosquery
执行 java 再获取一遍。
经过测试,在本地的ubuntu编译时,时间显示是一位的,例如2024.5.13 14:5:00
并且,无法在不使用 texosquery
的前提下获得gmt时区和秒数,无论如何修改系统都是gmt00:00,秒数始终是00
但是,github action就显示为正常,很奇怪,明明传参都一样……
我的本意是同时使用那两条,是「且」的关系。
一开始我也想同时使用来着,想了想决定还是不改系统时间了。 毕竟如果程序未成功转换东八区时间,但因为系统时间为正常东八区时间而掩盖了这种潜在问题就不好了
再次测试,更奇怪的问题出现了,本地编译ubuntu获取秒数失败,时区也失败,无论是否使用了texosquery……
本地运行命令: latexmk --shell-escape -synctex=1 -interaction=nonstopmode -halt-on-error -file-line-error -xelatex main.tex
自动build:https://github.com/Mikachu2333/sdsmu_welcome_tex/actions/runs/9123346871/workflow
找到原因了,我是大傻子。
texosquery 要求jre8,我系统里没有jre……
此外,根据实测,必须安装并使用texosquery否则xelatex无法获取秒数和时区
我感觉不用加载
texosquery
。XeTeX 直接提供了 primitive\creationdate
,datetime2
会按不同引擎使用相应的 primitive,无需通过texosquery
执行 java 再获取一遍。并且,无法在不使用
texosquery
的前提下获得gmt时区和秒数,无论如何修改系统都是gmt00:00,秒数始终是00
嗯,这是 datetime2
v1.5.7 (2021-03-21) 的缺陷,它还不支持从 xetex 的 \creationdate
获得时间戳(从 XeTeX 0.999991, texlive 2019 起提供)。我之前错以为已经支持,例子也没有用 xelatex 编译。
datetime2
的作者已经知道这个问题,只是还没有更新包
XeLaTeX now provides
\creationdate
. The next version ofdatetime2
will add support for this. In the meantime, if you are using a new version of XeLaTeX, add the following line before you loaddatetime2
:\providecommand{\pdfcreationdate}{\creationdate}
我还尝试了直接使用 datetime2
「切换」时区。过程要麻烦许多,也暴露出一点 datetime2
内部实现的不一致,见 \DTMtwodigits{\DTMfetchsecond{tmp@cest}
的部分。
想这么做是因为我不确定 latexmkrc 通过 Perl $ENV{key} = 'val'
设置的环境变量是不是生效、xelatex 等 latex 程序是否认 TZ
环境变量。只是猜测和担心,我没试。
% !TeX program = xelatex
\documentclass{article}
\usepackage{iftex}
% workaround for datetime2 <= 1.5.7 running in XeTeX
% see https://www.dickimaw-books.com/faq.php?id=273
\ifXeTeX
\providecommand{\pdfcreationdate}{\creationdate}
\fi
\usepackage[calc]{datetime2}
% \myDTMtoTZ{<name1>}{<name2>}{<time zone hour>}{<time zone minute>}
% based on https://tex.stackexchange.com/a/634977
\NewDocumentCommand{\myDTMtoTZ}{ mmmm }{%
% convert <name1> to UTC+0
\DTMtozulu{#1}{tmp@zulu}%
% add requested timezone offset to zulu time
\DTMsaveaszulutime{tmp@cest}%
{\DTMfetchyear{tmp@zulu}}{\DTMfetchmonth{tmp@zulu}}{\DTMfetchday{tmp@zulu}}%
{\DTMfetchhour{tmp@zulu}}{\DTMfetchminute{tmp@zulu}}%
{\DTMfetchsecond{tmp@zulu}}{\numexpr-#3\relax}{#4}%
% save new datetime to <name2>, in requested timezone
\DTMsavetimestamp{#2}{\expanded{%
\DTMfetchyear{tmp@cest}-\DTMfetchmonth{tmp@cest}-\DTMfetchday{tmp@cest}%
T%
% second (sec) field of a datetime created by \DTMsaveaszulutime is not
% guaranteed to be two digits
\DTMfetchhour{tmp@cest}:\DTMfetchminute{tmp@cest}:\DTMtwodigits{\DTMfetchsecond{tmp@cest}}%
\space
#3:#4}}%
}
% shortcut
\NewDocumentCommand{\myDTMuseinTZ}{ mm }{%
\leavevmode\llap{\makebox[4em][l]{UTC\ifnum#2=0\else#2\fi}: }%
\myDTMtoTZ{#1}{tmp@now}{#2}{0}%
\DTMuse{tmp@now}\par
}
\begin{document}
\ttfamily
\DTMsavenow{now}
\leavevmode\llap{now: }%
\DTMuse{now}
\medskip
\myDTMuseinTZ{now}{00}
\myDTMuseinTZ{now}{+08}
\myDTMuseinTZ{now}{-10}
\myDTMuseinTZ{now}{+14}
\end{document}
得到
now: 2024-05-17 19:21:22+08:00
UTC : 2024-05-17 11:21:22Z
UTC+08 : 2024-05-17 19:21:22+08:00
UTC-10 : 2024-05-17 01:21:22-10:00
UTC+14 : 2024-05-18 01:21:22+14:00
想这么做是因为我不确定 latexmkrc 通过 Perl
$ENV{key} = 'val'
设置的环境变量是不是生效、xelatex 等 latex 程序是否认TZ
环境变量。只是猜测和担心,我没试。
经过测试,完美支持。
我还尝试了直接使用
datetime2
「切换」时区。过程要麻烦许多,也暴露出一点datetime2
内部实现的不一致,见\DTMtwodigits{\DTMfetchsecond{tmp@cest}
的部分。
看了半天没看懂(捂脸)自己的latex水平还是太低了,当前阶段(在datetime2
没发新版之前)还是用着rc文件比较简单易行一点
此外,我也试图尝试过您的思路,碍于知识不足中途放弃,在努力的过程中我也是感觉datetime2似乎没有给出一些类似 rust 中 format!()
之类的成熟的格式化与运算接口(与tex语言本身也不是擅长与这方面也有关系看起来,不过没有转换时区的成熟的包装好的接口有些令人意外),导致用户在自定义输出格式与转换时区时分外艰难
所以 issue 已经解决、可以关闭了?
(不用说「您」的)
所以 issue 已经解决、可以关闭了?
是的
(不用说「您」的)
必要的礼貌,毕竟是有求于人(
顺便一提,datetime2
提供了设置输出样式的方式,见文档 sec. 5 "Styles"。但我感觉如果只需要输出一次,用 \DTMfetch<field>{<name>}
手动拼接就行了。
在努力的过程中我也是感觉datetime2似乎没有给出一些类似 rust 中
format!()
之类的成熟的格式化与运算接口
可以试试用 tex 调用 python 的包,比较新的有 pythonimmediate
,支持所有引擎、只要一次编译。pythontex
则需要两次编译,把 python 输出写入了辅助文件。https://ctan.org/topic/callback 列举了类似的宏包。
检查清单
操作系统
Win10 22h2 + Ubuntu 22.04.4 LTS (x64)
TeX 发行版
Tex Live 2024
描述问题
我尝试干什么
我知道什么
\DTMsetcurrentzone{08}{00}
但其只是粗暴地将获取到的时间由2024.5.16 22:00(current time) 00:00(time zone)
变成了2024.5.16 22:00 08:00
而并没有进行换算其他
最小工作示例(MWE)
用 XeLaTeX 编译后,无任何错误发生,文档成功编译(我的代码没有问题,只是缺少了相关的功能)
链接
No response
其他信息
原始pdf: http://mirrors.ibiblio.org/CTAN/macros/latex/contrib/datetime2/datetime2.pdf (关于xelatex的时区与秒数提醒在第6页下方)
其他资料: https://www.latexstudio.net/archives/7627.html https://zhuanlan.zhihu.com/p/667106521
附件
No response