关于python处理作Excel文件的一些问题,包括时间处理 (转)

关于python 处理作Excel文件的一些问题,包括时间处理(原创)

根据limodou的《使用xlrd模块时对Excel的日期处理》可以处理年月日, 但时分秒没法处理。下面是他的原文:
=======================================================

最近在我正在开发的一个数据维护工具中我经常使用 xlrd 来读取Excel文件,在转换 过 程中一直也没有遇到什么问题,只不过需要注意,它返回的字符串都是 Unicode 编码。不过今天在使用时发现对于日期类型,在Excel文件中看到的可能是 "2005-7-8" 这样格式,但直接使用 xlrd 来读的话却会变成 38541。很奇怪。仔细查看 Excel 后再经过试验,我明白了 Excel 保存日期其实是使用一个长整数,只不过显示时可以为标准的日期格式。本来我想将日期在 Excel 中直接转为日期格式的字符串,但没整出来,而且我更希望有一种方法可以正确地进行转换 。于是我想 xlrd 有没有这样的处理呢?使用 NewEdit 的 代码提示功能,查了查 xlrd 模块的属**,没找到。不过看到它有cell_type(i, j)的方法可以返回一个单元格的数据格式。于是我使用这个方法打出日期所在的单元格的格式为:3。然后又比较了 xlrd 中定义的一些常量,最后锁定在了 XL_CELL_DATE上,它的值就是 3。这样到目前为止我已经知道了如何判断一个单元格是否是日期类型,下面就是如何转换 了。

我查阅了datetime 模式,在它的date 类中查到一个函数叫:

fromordinal(oridnal)

它的作用是将从公元1年1月1日开始的天数转换 为 年月日的形式。于是我试了一下:

>>> import datetime
>>> datetime.date .fromordinal(38541)
datetime.date (106, 7, 10)

好象不对呀。于是我反向转转试试:

>>> datetime.date .toordinal(datetime.date (2005, 7, 8))
732135

怎么这么大的数。后来我想到可能fromordinal与Excel使用的起始日期可 能是不同的。做个减法看一看是哪天。

>>> datetime.date .fromordinal(732135 - 38541 + 1)
datetime.date (1899, 12, 31)

原来如此,是 1899/12/31 日,这回我明白了。其实象用过的 Informix 中的日期与 Excel 的方法是一样的,都是从 1899/12/31 开始计算的。那么做个转换 函 数吧:

__s_date = datetime.date (1899, 12, 31).toordinal() - 1
def getdate(date ):
    if isinstance(date , float ):
        date = int(date )
    d = datetime.date .fromordinal(__s_date + date )
    return d.strftime("%Y-%m-%d")

上述函数就是用来将一个从 1899/12/31 开始计算的天数转成年月日的格式,并且是字符串的形式。其中如果传入的是一个浮点数,先取整再进行转换

Trackback: http://tb.donews.net/TrackBack.aspx?PostId=459100

=======================================================

现在要处理时分秒怎么办呢??使用下面的方法:
import datetime
from matplotlib.dates import num2date

def ReDate(date ):
    __startDt = datetime.date (1899, 12, 31).toordinal() - 1
    if type(date )==float :
        return num2date(__startDt+date ).strftime("%Y-%m-%d %H:%M:%S")

s = 39469.912437
print ReDate(s)

大家来看一下
from matplotlib.dates import num2date他的一些代码:
def _from_ordinalf(x, tz=None):
    """
    convert Gregorian float of the date , preserving hours, minutes,
    seconds and microseconds. return value is a datetime
    """
    if tz is None: tz = _get_rc_timezone()
    ix = int(x)
    dt = datetime.datetime.fromordinal(ix)
    remainder = float (x) - ix
    hour, remainder = divmod(24*remainder, 1)
    minute, remainder = divmod(60*remainder, 1)
    second, remainder = divmod(60*remainder, 1)
    microsecond = int(1e6*remainder)
    if microsecond<10: microsecond=0 # compensate for rounding errors
    dt = datetime.datetime(
        dt.year, dt.month, dt.day, int(hour), int(minute), int(second),
        microsecond, tzinfo=UTC).astimezone(tz)

    if microsecond>999990: # compensate for rounding errors
        dt += datetime.timedelta(microseconds=1e6-microsecond)
    return dt

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值