Matlab公元0年起始日天数转Python1970纪元秒数出错排查
问题描述
有一个Matlab浮点数,代表自公元0年1月1日起经过的天数,示例值为739183.392799916,在Matlab中执行datestr(739183.392799916 ,'dd/mm/yyyy-HH:MM:SS.FFF')得到结果24/10/2023-09:25:37.913。
需要在Python中将其转换为以1970年1月1日为纪元的秒数(与time.time()标准一致),但编写的转换函数得到的结果为25/10/2024 11:25:37.913,与Matlab结果相差1年1天2小时,需排查问题。
转换函数代码:
def matlab_time_to_python_float(matlab_time: float) -> float: # Matlab standard is days since 1er Janvier 0000 heure 00:00:00 # Python standard is seconds since 1er Janvier 1970 00:00:00 from datetime import datetime, date matlab_ref = date(1, 1, 1) python_ref = datetime.utcfromtimestamp(0).date() delta = python_ref - matlab_ref python_day = matlab_time - delta.days seconds_in_a_day = 24*3600 python_time = python_day*seconds_in_a_day return python_time
时间格式化函数代码:
def python_float_to_str(python_time_float: float) -> str: # Use localtime, not gmtime. With gmtime, we get UTC time without timezone/summer/winter import time local = time.localtime(python_time_float) millisecondes = int(round((python_time_float - int(python_time_float)),3) * 1000) return time.strftime('%d/%m/%Y ', local) + f"{local.tm_hour:02d}:{local.tm_min:02d}:{local.tm_sec:02d}.{millisecondes:03d}"
调用代码:
as_str = ( python_float_to_str( matlab_time_to_python_float( 739183.392799916 ) ) ) print(as_str)
问题排查与修正
错误原因
- 日期起点不匹配:Matlab的时间起点是公元0年1月1日,但Python的
datetime.date(1,1,1)对应的是公元1年1月1日,两者相差一整个公元0年(Matlab将公元0年视为闰年,共366天)。同时,Python的datetime模块对公元1年到1582年的日期采用儒略历计算,与Matlab的datenum日期计算规则存在差异,直接通过date对象计算差值会导致天数偏差。 - 时区处理不一致:Matlab的
datestr默认输出UTC时间,而Python的time.localtime()会将时间转换为本地时区,导致小时数偏差(示例中差2小时,说明本地时区为UTC+2)。
修正方案
直接使用Matlab官方定义的从公元0年1月1日到Unix纪元(1970年1月1日)的天数差:Matlab中datenum('1970-01-01')返回719529,因此从公元0年1月1日到1970年1月1日的天数为719529 - 1 = 719528天。同时,使用UTC时间格式化,与Matlab结果时区保持一致。
修正后的代码
转换函数
def matlab_time_to_python_float(matlab_time: float) -> float: # Matlab: 天数从公元0年1月1日开始 # Unix纪元: 秒数从1970年1月1日UTC开始 # Matlab中datenum('1970-01-01') = 719529,因此差值为719529 - 1 = 719528天 days_since_unix_epoch = matlab_time - 719528 seconds_in_day = 24 * 3600 return days_since_unix_epoch * seconds_in_day
格式化函数(匹配Matlab的UTC输出)
def python_float_to_str(python_time_float: float) -> str: import time # 使用gmtime获取UTC时间,与Matlab的datestr默认输出时区一致 utc_time = time.gmtime(python_time_float) # 计算毫秒数,保留三位小数 milliseconds = int(round((python_time_float - int(python_time_float)) * 1000, 0)) # 按指定格式拼接字符串 return time.strftime('%d/%m/%Y-%H:%M:%S', utc_time) + f".{milliseconds:03d}"
调用测试
as_str = python_float_to_str(matlab_time_to_python_float(739183.392799916)) print(as_str)
测试结果
执行上述代码后,输出结果为24/10/2023-09:25:37.913,与Matlab的结果完全一致。
内容的提问来源于stack exchange,提问作者jpo38
相关产品推荐
相关产品推荐

