简体   繁体   中英

Python Quantlib convert Quantlib Date to datetime

I have a list of dates defined in the Date format of quantlib. How can I convert these into datetime format. The reason I am asking is, that I would like to plot it and I received the follwoing error:

TypeError: float() argument must be a string or a number, not 'Date'

when doing the following:

plt.plot(dates,rates, linewidth=2.0) # Without date plotting works out.

dates looks like the following:

[
  Date(11,12,2012), 
  Date(12,12,2012), 
  Date(13,12,2012),
  Date(14,12,2012), 
  Date(15,12,2012), 
  Date(16,12,2012),
  Date(17,12,2012), 
  Date(18,12,2012), 
  Date(19,12,2012),
  Date(20,12,2012)
]

There's no predefined conversion, so you'll have to extract the information from the QuantLib date and use it to build a datetime instance. Eg, define something like

def ql_to_datetime(d):
    return datetime.datetime(d.year(), d.month(), d.dayOfMonth())

after which you can use ql_to_datetime(d) for a single date, or [ ql_to_datetime(d) for d in dates ] for a list. (You can also define another function taking a list, of course.)

Update: in recent versions of QuantLib-Python, a predefined conversion was added. You can now say d.to_date() to convert a date, or [d.to_date() for d in dates] for a list.

There is a faster way. Since datetime.datetime has methods fromordinal() and toordinal() to convert between datetime.datetime and an integer that represents the date. Similarly, ql.Date also has the method serialNumber() to convert ql.Date to integer and its constructor accepts the integer as well. However, datetime.datetime uses 0001-01-01 as 1 with increments in days while ql.Date uses 1899-12-31 as 0. Hence, to convert between the two, we can use the following function:

def ql_to_datetime_new(d):
    return datetime.datetime.fromordinal(d.serialNumber() + 693594)

where 693594 is equal to datetime.datetime(1899,12,31).toordinal() - 1. To test the speed, I also use the function from Luigi's answer:

def ql_to_datetime(d):
    return datetime.datetime(d.year(), d.month(), d.dayOfMonth())

Then, test the speed as follows:

d = ql.Date(31, 12, 2000)
%timeit ql_to_datetime(d)
%timeit ql_to_datetime_new(d)

On my computer, the results are

796 ns ± 18.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
436 ns ± 0.938 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Hence, the one that I proposed is faster.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM