首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >识别电子表格中的日期类型::ParseExcel

识别电子表格中的日期类型::ParseExcel
EN

Stack Overflow用户
提问于 2014-12-17 00:18:42
回答 1查看 504关注 0票数 0

我们正在从基于module的模块迁移到Spreadsheet::ParseExcel (或类似模块)。由于我们有数以百计的程序使用我们的模块,我们希望我们提供一个下降的替换,即返回的数据是相同的。

问题是日期--使用Excel,我们得到一个Win32::OLE::Variant对象,类型为VT_DATE。作为一种解决方法,我们可以通过检查$cell->type() eq 'Date'并返回对象来手动构建该对象。

问题是类型没有可靠地设置,所以我们不能总是这样做.

Date类型在两处设置。这是FmtDefault.pm中使用的逻辑

代码语言:javascript
复制
if (   ( ( $iFmtIdx >= 0x0E ) && ( $iFmtIdx <= 0x16 ) )
    || ( ( $iFmtIdx >= 0x2D ) && ( $iFmtIdx <= 0x2F ) ) )
{
    return "Date";
}

如果检查失败,我们得到Numeric,那么它将在ParseExcel.pm中执行备份检查

代码语言:javascript
复制
if ( $FmtStr =~ m{^[dmy][-\\/dmy]*$}i ) {
    $rhKey{Type} = "Date";
}

但是,一些通用格式字符串无法工作,例如:

代码语言:javascript
复制
[$-C09]dddd\\,\\ d\\ mmmm\\ yyyy;@ i.e. Sunday, 24 January 1982
d/m/yyyy;@ i.e. 24/1/1982

我在openoffice.org上检查了Excel规范,还阅读了指南(如代码 ),下面的规则似乎与日期格式字符串匹配:

带有d、m或y字符的字符串,它们不是介于"“或[]之间,除非是\,而且后面没有- or *,否则不加\。

,这看起来非常复杂,而且容易出错。有更好的方法吗?

似乎Spreadsheet::ParseExcel::Utility::ExcelFmt()标记了$format_mode下的日期格式,所以也许可以修改这个逻辑以返回标志?但是,如果可能的话,我更希望在不改变Spreadsheet::ParseExcel模块的情况下做好准备。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-17 00:49:09

你知道什么列应该是日期吗?

在我的用法中,我会这样做,并将它们转换为:

代码语言:javascript
复制
$val = $cell->unformatted();
# if it was properly set as a Date cell, the value will be a number of days since 1900 or 1904
# that we can convert to a date, regardless of the format they were shown.
if ( $val =~ /^[0-9]{5}(?:\.[0-9]+)?\z/ ) {
    $date = Spreadsheet::ParseExcel::Utility::ExcelFmt( 'YYYY-MM-DD', $val, $wb->{'Flg1904'} );
}
else {
    $val = $cell->value();
    $val =~ s/^'//;
    # try parsing it with Date::Manip, which handles all common formats (see its ParseDateString doc)
    use Date::Manip ();
    Date::Manip::Date_Init("TZ=GMT","DateFormat=US");
    $date = Date::Manip::UnixDate( $val, '%Y-%m-%d' );
}

更新:听起来最好是修改ExcelFmt,如下(未经测试):

代码语言:javascript
复制
--- Utility.pm.orig 2014-12-17 07:16:06.609942082 -0800
+++ Utility.pm  2014-12-17 07:18:14.453965764 -0800
@@ -69,7 +69,7 @@
 #
 sub ExcelFmt {

-    my ( $format_str, $number, $is_1904, $number_type, $want_subformats ) = @_;
+    my ( $format_str, $number, $is_1904, $number_type, $want_subformats, $want_format_mode ) = @_;

     # Return text strings without further formatting.
     return $number unless $number =~ $qrNUMBER;
@@ -956,8 +956,14 @@
     $result =~ s/^\$\-/\-\$/;
     $result =~ s/^\$ \-/\-\$ /;

-    # Return color and locale strings if required.
-    if ($want_subformats) {
+    # Return format mode and/or color and locale strings if required.
+    if ( $want_subformats && $want_format_mode ) {
+        return ( $result, $color, $locale, $format_mode );
+    }
+    elsif ($want_format_mode) {
+        return ( $result, $format_mode );
+    }
+    elsif ($want_subformats) {
         return ( $result, $color, $locale );
     }
     else {

一定要将它提交给保持器,以便包含在以后的版本中。

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

https://stackoverflow.com/questions/27516355

复制
相关文章

相似问题

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