首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在csv中编辑日期时间以调整时区

在csv中编辑日期时间以调整时区
EN

Stack Overflow用户
提问于 2016-09-14 21:07:27
回答 2查看 1.7K关注 0票数 0

我们通常会在GMT的某些列中获得包含日期时间值的csv文件。

我们正在寻找一种将日期时间值从GMT更改为我们选择的时区的方法--所需的目标时区可能因csv而异。这一调整也需要考虑到DST。

csv的日期时间格式:

代码语言:javascript
复制
YYYY/MM/DD HH:MM:SS

样本数据:

代码语言:javascript
复制
col1,col2,col3,col4
aaa,bbb,2016/01/15 22:01:16,ccc
ddd,eee,,fff
hhh,iii,2014/09/19 00:53:37,jjj
kkk,lll,2015/11/15 22:01:16,mmm
nnn,ooo,2015/10/12 19:54:59,ppp

例如,如果我们希望将上述样本数据从格林尼治时间调整到太平洋时间(GMT -8标准),我们希望得到的结果是一个csv,其值如下:

代码语言:javascript
复制
col1,col2,col3,col4
aaa,bbb,2016/01/15 14:01:16,ccc
ddd,eee,,fff
hhh,iii,2014/09/18 17:53:37,jjj
kkk,lll,2015/11/15 14:01:16,mmm
nnn,ooo,2015/10/12 12:54:59,ppp

注re :对于上面的5行示例数据,DST仅对第3行和第5行的日期是活动的。调整可能因线而异,但在目标时区当量(太平洋)方面是一致的。

日期时间格式本身可以保持原样--我们只需调整时区的日期时间值,最终将等效的日期时间存储在东部、太平洋(或任何其他时区)而不是格林尼治标准时间。

如果可能的话,我们希望利用Ubuntu中本机提供的编辑工具,比如awk,因为我们已经有了使用它的清理例程。如果不可能使用awk或类似的解决方案,将考虑其他解决方案。

其他说明:

  • 有些csv在多列中有日期时间,其中只有,列的某些需要从GMT调整到另一个时区。理想的解决方案是在我们指定的一个或多个列中调整日期时间,但跳过不需要调整的列。
  • 具有datetimes的csv列也可能在某些行上包含空白值。
  • 在每个csv的基础上,我们希望将日期时间从GMT更改为单个目标时区,对所有行进行相同的tz调整。

任何洞察力都是值得赞赏的--谢谢!

编辑:

在研究这个问题的过程中,我发现这样一种说法:

代码语言:javascript
复制
echo "1/15/2016  10:01:16 GMT" | awk -v q='"' '{cmd="TZ=America/Los_Angeles date -d"q$0 q" +"q"%F %H:%M:%S %Z"q; cmd|getline x; close(cmd);print x}'

...is在某种程度上是概念的证明,但我不得不自己在字符串中添加"GMT“,并且输出日期格式略有不同。

我希望找到一个解决方案,我可以应用到csv可能有数千行。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-14 22:41:33

使用GNU awk作为时间函数:

代码语言:javascript
复制
$ cat tst.awk
function dt2utcSecs(dateTime,   cmd,line,ret) {
    cmd = "TZ=UTC gawk -v dt='" dateTime "' 'BEGIN{print mktime(dt)}'"
    ret = ( (cmd | getline line) > 0 ? line : -1 )
    close(cmd)
    return ret
}
BEGIN{
    FS=OFS=","
    split(cols,f)
}
{
    for (i in f) {
        dateTime = gensub(/[\/:]/," ","g",$(f[i]))
        utcSecs = dt2utcSecs(dateTime)
        if (utcSecs >= 0) {
            $(f[i]) = strftime("%Y/%m/%d %T",utcSecs)
        }
    }
    print
}

$ TZ='US/Pacific' gawk -v cols=3 -f tst.awk file
col1,col2,col3,col4
aaa,bbb,2016/01/15 14:01:16,ccc
ddd,eee,,fff
hhh,iii,2014/09/18 17:53:37,jjj
kkk,lll,2015/11/15 14:01:16,mmm
nnn,ooo,2015/10/12 12:54:59,ppp

只需设置cols=3,5,9对这些字段进行转换即可。有关有效时区的列表,请参见/usr/share/zoneinfo。

请注意,@webb's answer应该比上面的更有效,因为上面的调用shell可以在每个输入dateTime字段中调用gawk一次,而@webbs只调用gawk两次。

票数 1
EN

Stack Overflow用户

发布于 2016-09-15 03:38:25

以下是一种有趣的方式:

首先,将日期字符串转换为数值,utc时间戳,然后将数字时间戳转换为本地日期字符串:

代码语言:javascript
复制
TZ=UTC awk -F, '
  BEGIN{OFS=","}
  { if(NR>1&&$3){
      gsub("[/:]"," ",$3);
      $3=mktime($3" GMT")};
    print $0
  }' infile.csv | awk  -F, '
  BEGIN{OFS=","}
  { if(NR>1&&$3){
      $3=strftime("%Y/%m/%d %H:%M:%S %Z", $3, 0)};
    print $0
  }' > outfile.csv

产出:

代码语言:javascript
复制
col1,col2,col3,col4
aaa,bbb,2016/01/15 14:01:16 PST,ccc
ddd,eee,,fff
hhh,iii,2014/09/18 17:53:37 PDT,jjj
kkk,lll,2015/11/15 14:01:16 PST,mmm
nnn,ooo,2015/10/12 12:54:59 PDT,ppp

注意1:您可以通过删除第二个%Z中的awk从输出中移除时区,但是如果这样做,只会损害您未来的自我。

注2:这可能有用,也可能不起作用,这取决于您的awk版本。如果您的系统有gawk,请尝试用它代替awk。如果不是,那么安装gawk应该很容易。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39499654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档