-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeutils.py
156 lines (128 loc) · 3.79 KB
/
timeutils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Time and coordinate-related python libraries
# Bryan Miller
from __future__ import print_function
import sys
def sex2dec(stime,todegree=False,sep=':'):
# stime is a string of format "HR:MIN:SEC"
# returns the decimal equivalent
# Bryan Miller
# From sex2dec.pro
l_stime = str(stime).replace("+","")
if sep not in l_stime:
print ('Separator not found. Input must be in the format "HR<sep>MIN<sep>SEC"')
return -1
f = 1.0
if todegree:
f = 15.0
result = 0.0
exp = 0
sign = 1.
for val in l_stime.split(sep):
#tmp = val.lstrip('0')
#if tmp == '':
# tmp = '0'
x = float(val)
if x < 0.0:
sign = -1.
result = result + abs(x)/60.**exp
exp = exp + 1
return sign*f*result
def dtsex2dec(datetime,todegree=False):
# input is a datetime object
# Bryan Miller
f = 1.0
if todegree:
f = 15.0
sign=1.
if datetime.hour < 0:
sign = -1.
return sign*f*(abs(datetime.hour) + datetime.minute/60. + datetime.second/3600.)
def sixty(dd):
# http://stackoverflow.com/questions/2579535/how-to-convert-dd-to-dms-in-python
# Equivalent to sixty.pro
# Bryan Miller
is_positive = dd >= 0
l_dd = abs(dd)
minutes,seconds = divmod(l_dd*3600,60)
degrees,minutes = divmod(minutes,60)
if degrees > 0.:
degrees = degrees if is_positive else -degrees
elif minutes > 0.:
minutes = minutes if is_positive else -minutes
else:
seconds = seconds if is_positive else -seconds
return (degrees,minutes,seconds)
def dec2sex(d,p=3, cutsec=False, hour=False, tohour=False,sep=':',leadzero=0, round=False):
"""
Convert decimal degrees/hours to a formatted sexigesimal string
From dec2sex.pro
Bryan Miller
Parameters
:param d: input in degrees
:param p: digits for seconds
:param cutsec: Cut seconds, just display, e.g. DD:MM
:param hour: d is decimal hours, so must be <=24
:param tohour: convert from degress to hours (divide by 15.)
:param sep: Separator string
:param leadzero: if >0 display leading 0's, e.g. -05:25. The value is the number of digits for the DD or HR field.
:param round: when cutsec, round to the nearest minute rather than truncate
:return: string
"""
l_d = float(d)
sign = ''
sd = ''
dg = 0
mn = 0
sc = 0.0
maxdg = 360.
if tohour:
l_d = l_d/15.0
hour = True
if hour and (abs(l_d) > 24.):
print ('Input in hours must be less than or equal to 24.0.')
sys.exit(1)
if hour:
maxdg = 24.0
n = 2 if p==0 else 3
secstr = '{:0'+'{:1d}'.format(n+p)+'.'+'{:1d}'.format(p)+'f}'
six = sixty(l_d)
dg = abs(int(six[0]))
if (six[0] < 0):
sign = '-'
# if dg >= 100:
# ldg = 3
# elif dg >= 10:
# ldg = 2
# else:
# ldg = 1
if leadzero > 0:
sldg = '0' + str(leadzero)
else:
sldg = str(len(str(dg)))
mn = abs(int(six[1]))
if (six[1] < 0):
sign = '-'
sc = float(secstr.format(abs(six[2])))
if (six[2] < 0.0):
sign = '-'
# print sign,dg,mn,sc
if sc >= 60.0:
sc -= 60.0
mn = mn + 1
if cutsec:
if round and sc >= 30.:
# Round to the nearest minute, otherwise truncate
mn += 1
sc = 0.0
if mn >= 60:
mn -= 60
dg = dg + 1
if dg >= int(maxdg):
dg = dg - int(maxdg)
if cutsec and sc == 0.0:
fmt = '{:1s}{:'+sldg+'d}'+sep+'{:02d}'
s = fmt.format(sign,dg,mn)
else:
fmt = '{:1s}{:'+sldg+'d}'+sep+'{:02d}'+sep+secstr
s = fmt.format(sign,dg,mn,sc)
return s.strip()