Python Forum

Full Version: Error when converting MATLAB's datenum to Python's datetime
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I have to convert a MATLAB's datenum to Python's datetime. The following code is as below:

import datetime
matlab_datenum = 63650571169.50261
python_datetime = datetime.date.fromordinal(int(matlab_datenum)) + datetime.timedelta(days=matlab_datenum%1) -  datetime.timedelta(days = 366)
print (matlab_datenum)
63650571169.50261 is a datenum that represents a date plus a time for example 2010-11-04 00:03:50.209589

The above code generates this error:

OverflowError: Python int too large to convert to C long
 
The above code, is it correct ? how can i obtain a date plus a time ?

Thank you for your help,
Formula that you are using is based on assumption that matlab datenum is representing days from Jan 1, 0 with fractional part representing part of day.

It seems that your datenum is probably number of seconds from Jan 1, 0 (while fractional part is mysterious). If its really seconds from some date, you can use datetime.datetime.fromtimestamp(), it uses seconds from Jan 1, 1970, so you would need to subract your "matlab datenum" for Jan 1, 1970 to get seconds from Jan 1, 1970.
Thank you for your reply,
In fact, the datenum is number of milliseconds



matlab_datenum = 6.365057116950260162e+10
python_datetime = datetime.datetime.fromtimestamp(matlab_datenum / 1e3)
print (python_datetime)
The result is : 1972-01-07 16:42:51.169503

But, i think the result is wrong because the date must be from 2010-11-04 to 2011-06-11.

Do you have any idea how to correct the result ?
In [1]: matlab_datenum =  63650171169.50261

In [2]: matlab_datenum/1000/86400  # days
Out[2]: 736.6917959433172
If its really miliseconds, then its counting them from date in October 2008, seems quite odd. As i said, you would need to use some "offset".

In [3]: import datetime

In [4]: some_matlab_date = matlab_datenum - 1000000000 # million seconds earlier?

In [5]: some_python_date = ( datetime.datetime(2010, 11, 4, 0, 3, 50)   # your base date
                             + datetime.timedelta(seconds = (some_matlab_date - matlab_datenum)/1000) )

In [6]: some_python_date
Out[6]: datetime.datetime(2010, 10, 23, 10, 17, 10)
You just take your 2010/11/4 as a base date and add difference between matlab representation of that date and another one.

EDIT: You can use that formula to compute "start of matlab calender" by setting some_matlab_date = 0 and after that you could use
 some_python_date = python_datetime_of_start_of_matlab_calendar + datetime.timedelta(seconds = some_matlab_date/1000)
Thank you for your reply,
I met some difficulties to understand your proposition.
The result is 2010-10-23 10:17:10 and does not belongs to [2010-11-04 00:00:00, 2011-06-11 00:00:00].

You proposed the following code:

matlab_datenum = 6.365057116950260162e+10
some_matlab_date = matlab_datenum - 1000000000 # million seconds earlier?
some_python_date = ( datetime.datetime(2010, 11, 4, 0, 3, int(50.209589)) # your base date
+ datetime.timedelta(seconds = (some_matlab_date - matlab_datenum)/1000) )
print (some_python_date)

But it provides the same value "2010-10-23 10:17:10" of "some_python_date" for any value of matlab_datenum!!

is it correct the proposiotion code ? or i missunderstand ?

Thank you very much for your help
I guess that there was some misunderstooding. matlab_datenum was your original matlab datenum, some_matlab_date was testing matlab datenum to show that it "works", as i had no other matlab date i created it. I rewrote that expression without using any auxiliary variables:
datetime.datetime(2010, 11, 4, 0, 3, 50) + datetime.timedelta(seconds = (matlab_date_to_convert - 63650171169.50261)/1000)
If you replace matlab_date_to_convert with your matlab datenum that you want  to convert to python date, this expression should give python date corresponding to your matlab datenum.