2012-03-23 125 views
3

似乎每个星期左右都会有人发布有关将日期转换(损坏?)为美式格式的问题。像其他许多人一样,我试图提供帮助,但问题难以捉摸。我现在想知道我是否发现了原因。.NumberFormat有时会用日期和时间返回错误的值

我正在研究一个应用程序,我需要从Excel工作表中提取数据,并将其输出为格式为符合Excel用户可以看到的值的字符串。所以如果值是“1”格式化显示为“1.00”那么我想字符串为“1.00”。

我通过测试单元格值为数字,日期或时间来实现此效果。如果是,我找回了数字格式,并用它来格式的单元格值,因此:

With .Cells(Row, Column) 
    Output string = Format(.Value, .NumberFormat) 
End With 

在大多数情况下,这给了我正是我所需要的输出。但是,有时候,当源格式化为英国日期或时间时,我会得到美国的日期和时间。

经过对Excel 2003和Excel 2007的大量实验后,我发现原因。 (我无权访问Excel 2010,但是根据我推断它存在的问题也有同样的问题。)这个问题部分旨在向全世界揭示这个问题,因为我可以在互联网上发现任何东西以表明其他人已经注意到它。 (毫无疑问,有人会回复他们搜索“xyz”并立即得到答案)。然而,这个问题的主要目的是寻求获得所有情况下我需要的结果的建议。

通常我输入日期,例如“23mar12”。 Excel将此识别为日期并将其格式化为“23-Mar-12”。我可以选择Format Cells并输入或选择自定义格式或选择其中一种日期格式,以便我可以使用任何格式,我可以想象包括几天和几个月的非英文名称。

但是,在一种情况下,我选择的格式不是记录的格式:定制格式“dd/mm/yyyy”记录为日期格式“* 14/03/2001”。直到更进一步,这显然不是问题。

我创建了一列日期和时间,并用不同的自定义格式或标准格式格式化。我写了一个宏来为这些日期和时间中的每一个提取NumberFormat,并将它作为字符串写入相邻列。我还使用数字格式格式化了该值,并将该字符串写入第三列。

在许多情况下,选择并用Excel记录的格式不通过的NumberFormat返回的格式:

Excel format   NumberFormat 
Date: * 14/03/2001  m/d/yyyy 
Date: * 14 March 2001 [$-F800]dddd, mmmm dd, yyyy 
Date: 14/03/2001  dd/mm/yyyy;@ 
Date: 14/03/01   dd/mm/yy;@ 
Date: 14/3/01   d/m/yy;@ 
Date: 14.3.01   d.m.yy;@ 
Date: 2001-03-14  yyyy-mm-dd;@ 
Date: 14 March 2001 (1) [$-809]dd mmmm yyyy;@ 
Date: 14 March 2001 (2) [$-809]d mmmm yyyy;@ 
Custom: hh:mm:ss  h:mm:ss 
Time: * 13:30:55  [$-F400]h:mm:ss AM/PM 
Time: 13:30:55 (1)  hh:mm:ss;@ 
Time: 13:30:55 (2)  h:mm:ss;@ 
Time: 01:30:55 PM  [$-409]hh:mm:ss AM/PM;@ 
Time: 1:30:55 PM  [$-409]h:mm:ss AM/PM;@ 

的值(1)和(2)在Excel格式柱通过我加入到表明有两种明显相同的格式。从NumberFormat列可以看出,在每种情况下,第二个版本都抑制了前导零。

大部分更改都没有重要影响。 “[$ -F800]”等等显然是虚拟值,没有任何效果。显然,您可以用Microsoft国家/地区代码替换“F800”,以便将日期和月份的名称翻译为该国家的语言。

但是,Microsoft标记为星号的三种标准格式发生了不可接受的变化。日期从小端变为中端;时间从24小时变为12小时,并且“2001年3月14日”中增加了一周中的某一天。

对星号的日期,引用注释:“除了在类型列表(数字选项卡,格式单元格对话框)中带有星号()的项目,您应用的日期格式不会切换日期顺序。操作系统”对时间的星号,引用的注释:“除了有在类型列表中的星号()项目(编号选项卡,设置单元格格式对话框),你申请不切换时间的订单时间格式与操作系统。”

如果我要,我可以警告我的用户是标准的日期和时间格式可能无法得到所需的结果。然而,如果他们想要流行的格式“dd/mm/yyyy”,他们不能拥有它。例如,“dd-mm-yyyy”是可以的,但自定义格式“dd/mm/yyyy”变成日期格式“* 14/03/2001”变为“m/d/yyyy”。

回到我开点:在这个陌生的一个特定的日期格式,许多人之所以宣称自己的日期的处理有时被转换成美国的格式,这是为什么这个问题是如此难以捉摸?我遇到了一组微软程序员其他地方遇到的这种类型的问题,他们不知道另一个小组正在做什么。这就是为什么一些功能总是有效,而其他功能有时却不行?一些微软程序员知道在哪里寻找正确的格式,其他人不知道?

更重要的是,对我来说,任何人都可以提出:

  • 我如何获得真实的日期或时间格式?
  • 确定用户选择的日期或时间显示格式的其他方法?

顺便说一句:我记得大约三十年前,我被告知美国军方不使用月/日/年格式;只有美国平民使用这种格式。谁能告诉我这是真的吗?

BTW 2:类似的问题与Excel的颜色。 Excel将其颜色标为“ggbbrr”,而其他人则将其标为“rrggbb”。 .Net Excel inter-op的程序员没有被告知,并且在使用它来控制屏幕之前没有反转Excel颜色编号。

+0

关于你的(1)和(2)个位,'D'示出了单个数字或两位数天,其中如'dd'预先考虑一个零到单个数字天。同样,'h'的单位小时数小于10,'hh'的前数为零。所以格式不一样,如果相应的日期或小时是两位数字,它们只会返回相同的结果。 – Pete 2014-12-17 22:29:19

+0

上面我说:“Excel格式列中的值(1)和(2)是我添加的,表示有两个明显相同的格式。从NumberFormat列可以看出,在每种情况下,第二个版本都抑制领先的零“。这与你的评论有什么不同? – 2014-12-17 22:33:27

+0

@Pete我忘了在上面的评论中包含你的名字。 – 2014-12-18 09:12:53

回答

1

我主要遇到了格式和日期的问题打开已经保存有不同的区域设置的文本文件时。处理这种两个有用的单元格属性是:

  • .Text,因为它显示
  • .Value2返回未格式化的单元格的值或日期序列号返回单元格的值。

正如您所说,标准日期和数字格式取决于Windows区域设置,这可能不是所期望的行为,因为相同的工作簿可能在不同区域显示不同。 MS引入了数字格式的区域代码前缀(大约是Excel 2000?),如果需要,它将强制执行一致的显示,但它们需要明确选择。

如果您确实希望在用户输入日期或数字时看到日期或数字,可以提取查看工作表单元格格式的.xlsx文件的内容以及共享字符串xml定义,其中列出了已保存的数字格式工作簿。我并不认为有必要这样做,因为底层价值是作为序列号存储在内部的,这种情况不会改变。

+0

我意识到Text属性,但没有意义。它为我构建的每个示例生成正确的显示值。谢谢。但是,请注意,我没有导入文本文件,也没有找到用户输入的值。对于Excel来说要考虑到区域设置是好的。要Excel忽略区域设置和用户的要求是错误的,这是.NumberFormat属性正在做什么。我仍然怀疑这是造成许多报道问题的原因。然而,你已经解决了我的问题,再次感谢你。 – 2012-03-23 17:37:07

+0

我很高兴.Text属性解决了您的问题。我现在更清楚地看到你对'.NumberFormat'的观点 - 它不会对日期格式的区域设置做出响应,这对我来说确实看起来像一个错误。我遇到过类似于“评估”的东西,它总是以美国格式处理日期,并且过去让我感到悲伤。 – 2012-03-24 09:38:09

0

BTW 1:它已经近30年,因为我是在军事... 我曾经在直升机上工作过,并且我被教导在飞机日志中使用这种格式:4月3日。所以,这就是我仍然写日期的方式。通过这种方式,2012年4月3日之前不会有人怀疑 - 是4月3日还是3月4日?

+0

感谢您确认我的记忆没有错误。 – 2012-04-04 08:40:43

0

我砍了这个:我用已知的格式重写原始数据。它依赖于与DateSerial和TimeSerial的:

'Google spreadsheet stores dates in USA format (MM/DD/YYYY). We're in Australia, using DD/MM/YYYY, so we need to swap them. 
        ' 
         With dc 'the cell who contains a date in USA format. 
          d = .Value  'capture value in USA format 
          t = TimeValue(d) 
          .NumberFormat = "dd/mm/yyyy" 'set to OZ format, so Excel knows the values were swapped in its internal math. 
          .Value = DateSerial(Year(d), Month(d), Day(d)) 'DateSerial takes y,d,m. We swap Month and Day components, to get OZ format dates 
          .Value = .Value + TimeSerial(Hour(t), Minute(t), Second(t)) 
          dc.Font.Bold = True       ' We bold the cells that are swapped, for debugging 
         End With 
        End If 
+0

感谢您的答复,但我不认为这与我的问题有关。我不熟悉Google电子表格,但如果它以美国格式存储日期,我会感到惊讶。 Excel将日期存储为自1899年12月31日以来的天数。我的问题和其他问题是Excel在将该数字转换为字符串时有时会使用错误的格式。我发现,当日期输入为dd/mm/yyyy Excel正确识别并显示它时,但如果您要求NumberFormat,则会给出mm/dd/yyyy。 Excel知道正确的格式,但给外人提供了错误的格式。 – 2012-05-28 10:36:36

+0

顺便说一句,如果你的代码是Excel VBA,它不会改变它的值,但是'.NumberFormat =“dd/mm/yyyy”'会改变它在美国fromat中显示的外观。 – 2012-05-28 10:37:09

+0

是的,我的代码是用于获取模糊数据并强制Excel将其视为数据值dd/mm/yyyy。对不起,如果它与你的问题无关。 – joshoff 2013-08-09 17:35:47