因为写一些程序或脚本经常要涉及GPS的时间转换,比如下载各种产品遍历的时候可能需要用年积日,但是如果日期有跨年的话年积日也不方便,可能就需要先转儒略日再转对应的年月日,而有些产品命名又是GPS周相关,所以就写了一个转换时间的代码,方便每次的调用。

代码里面每一个时间参数的变量都是一个列表的形式,数据为int或float。

cal指年月日时分秒(如果不足6位补0)

day指年月日(与cal差距在于没有时分秒信息)

doy指年积日

mjd指简化儒略日

gps指GPS周和周内秒

gpsday指GPS周和周内日

wd指星期几

比如2021年10月25日0时0分这个时刻。

cal=[2021,10,25,0,0,0]

day=[2021,10,25]

doy=298

#!/usr/bin/env python
# coding: utf-8
# author: GLASSYM
# 2020.10.25 in zhangshu
# some function about time transform 
# input list ; output list (of int or float)
#

import math,datetime

def cal2mjd(cal):
# cal2jd 将公历年月日时分秒转换到简化儒略日。
# 输入公历时间列表,返回儒略日
    if(len(cal)<6):
        for i in range(len(cal),6):
            cal.append(0)
    year  = cal[0]
    month = cal[1]
    day   = cal[2]+(cal[3]*3600+cal[4]*60+cal[5])/86400;
    y     = year+4800  
    m     = month
    if( year < 0 ):
        print('Year is wrong')
        return False
    
    if( m <= 2):
        # 1,2月视为前一年13,14月
        m = m + 12
        y = y - 1
    e = math.floor(30.6 * (m+1))
    a = math.floor(y/100)
    # 教皇格雷戈里十三世于1582年2月24日以教皇训令颁布,将1582年10月5日至14抹掉。1582年10月4日过完后第二天是10月15日
    if( year <1582 )or(year==1582 and month<10)or(year==1582 and month==10 and day<15):
        b = -38
    else:
        b = math.floor((a/4) - a)
    c = math.floor(365.25 * y)
    jd = b + c + e + day - 32167.5
    mjd = jd - 2400000.5
    return mjd

def mjd2cal(mjd):
# 从简化儒略日计算公历年月日时分秒
# 返回的cal是年月日时分秒 列表
# 公元1582年10月4日24:00点之前使用儒略历,公元1582年10月15日00:00点之后使用公历
    J = mjd + 2400000.5
    if (J < 1721423.5):
        #公元1月1日0时
        BC = 1;
    else:
        BC = 0;

    if( J < 2299160.5 ): 
        # 1582.10.4. 24:00 前
        j0=math.floor(J+0.5)
        dd=J+0.5-j0
    else: 
        #不是闰年的年数
        n1=math.floor((J-2342031.5)/36524.25/4)+1   #1700.3.1.0
        n2=math.floor((J-2378555.5)/36524.25/4)+1   #1800.3.1.0
        n3=math.floor((J-2415079.5)/36524.25/4)+1   #1900.3.1.0
        j0=n1+n2+n3+J+10
        dd=j0+0.5-math.floor(j0+0.5)
        j0=math.floor(j0+0.5)
    
    j0=j0+32083
    year0=math.ceil(j0/365.25)-1
    year=year0-4800
    day=j0-math.floor(year0*365.25)
    month=math.floor((day-0.6)/30.6)+3
    day=day-round((month-3)*30.6)
    
    if (month>12):
        month=month-12
        year=year+1    
    year=year-BC
    sec=round(dd*86400)    
    hour=math.floor(sec/3600)
    sec=sec-hour*3600
    minute=math.floor(sec/60)
    sec=sec-minute*60  
    return [year, month, day, hour, minute, sec]

def cal2gps(cal):
# cal2gps 将公历GPS时间转换到GPS周和周内的秒
# 返回列表,周和周内秒
    mjd=cal2mjd(cal)
    #GPS从MJD44244开始
    e=mjd-44244
    week=math.floor(e/7)
    e=e-week*7            
    return [week,round(e*86400)]

def gps2cal(gpst):
# gps2cal  将GPS周和周内的秒转换到公历年月日
# 返回列表 年月日时分秒
# GPS从MJD44244开始
    mjd = 44244+(gpst[0]*86400*7+gpst[1])/86400
    cal = mjd2cal(mjd)
    return cal

def gpsday2cal(gpst):
# gps2cal  将GPS周和周内日转换到公历GPS时间
# 返回列表 年月日时分秒
# GPS从MJD44244开始
    mjd = 44244+(gpst[0]*7+gpst[1])
    cal = mjd2cal(mjd)
    return cal

def cal2gpsday(cal):
# cal2gpsday 将年月日转化为GPS周及周内日
# 返回列表,周和周内日
    mjd=cal2mjd(cal)
    #GPS从MJD44244开始
    e=mjd-44244
    week=math.floor(e/7)
    e=e-week*7            
    return [week,int(e)]
 
def cal2wd(cal):
# 将公历年月日转换到星期几
# cal2wd1(cal) 返回星期几
# cal:1x3矩阵,3列分别为年月日
# 在公元1582年10月4日24:00点之前使用儒略历,公元1582年10月15日00:00点之后使用公历
    Y=cal[0]
    M=cal[1]
    D=cal[2]
    #一月、二月当作前一年的十三、十四月
    if ((M==1)or(M==2)):
        M=M+12
        Y=Y-1
    #判断是否在1582年10月5日前
    if ((Y<1582)or((Y==1582)and(M<10))or((Y==1582)and(M==10)and(D<5))): 
        A=(D+2*M+math.floor((3*(M+1))/5)+Y+math.floor(Y/4)+5)%7
        #1582年10月5日前的公式
    else:
        A=(D+2*M+math.floor((3*(M+1))/5)+Y+math.floor(Y/4)-math.floor(Y/100)+math.floor(Y/400))%7
        #1582年10月5日后的公式
    return A+1


def doy2day(doy):
# 年积日转年月日
# 根据输入的年份和天数计算对应的日期
    first_day=datetime.datetime(doy[0],1,1)
    add_day=datetime.timedelta(days=doy[1]-1)
    date = datetime.datetime.strftime(first_day+add_day,'%Y,%m,%d')
    date = date.split(',')
    date = [ int(x) for x in date ]
    return date

def day2doy(date):
# 年月日转年积日
# 输入列表 年月日 返回该日是年内第几日
    year = date[0]
    month= date[1]
    day  = date[2]
    months=[0,31,59,90,120,151,181,212,243,273,304,334]
    if 0<month<=12:
        sum=months[month-1]
    else:
        print("month error")
    sum+=day
    leap=0
    # 接下来判断平年闰年
    # and的优先级大于or
    # 1、世纪闰年:能被400整除的为世纪闰年
    # 2、普通闰年:能被4整除但不能被100整除的年份为普通闰年
    if(year%400==0) or ((year%4)==0) and (year%100!=0):
        leap=1
    #判断输入年的如果是闰年,且输入的月大于2月,则该年总天数加1
    if(leap==1) and (month>2):
        sum+=1
    return sum

使用方法示例:

import TimeTrans as TT

time = [2021,10,25]
print(TT.day2doy(time))

#输出:298

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐