[go: up one dir, main page]

Menu

[57f2a1]: / anal / timeconv.m  Maximize  Restore  History

Download this file

180 lines (178 with data), 5.1 kB

  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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
function [date,leaps] = timeconv(date0,direction)
% [date,leaps] = timeconv(date0,direction,inleap)
% Convert between different time formats utc|tai|mat|unx|gup
%
% date: output time in new format
% leaps: tot no leap seconds at dates
%
% date0: input time to be converted, column vecctor
% direction: specifies the time formats of the input and output.
% Possible options: '(tai|utc|mat|unx|gup|kst)2(tai|utc|mat|unx|gup)'
% Default 'utc2tai'
%
% time formats: tai float secs since 1970-01-01
% utc datevec [y,m,d,h,m,s], s>=60 for leaps
% mat matlab date
% unx float secs since 1970-01-01 without leaps
% gup [y,secs] secs>365*86400 for leaps
% kst eros3 parameter block yymm ddHH MMSS format
%
% Optional extra column for tai|utc|unx|gup with nanosecs
% Optional extra column for mat with leapsecs used
%
% Currently step times are through Jan 1 2017, but need to be added in the
% function list as they are instuted. The first addition of leapseconds (10 s) was at
% 'Jan 1 1972'. Following dates correspond to additions of new individual
% leapseconds.
if nargin<2 | isempty(direction)
direction='utc2tai';
end
if nargin<3
inleap=[];
end
f='utc mat unx tai gup kst';
dir=split(direction,'2');
unx0=datenum(1970,1,1);
leapin=[];
if ~contains(f,dir{1}) && length(dir)>1 && ~contains(f,dir{2})
error(['Error: ' direction ' is not a possible convert direction.'])
end
%% ADD NEW LEAP DATES HERE:
stepdate = [...
'Jan 1 1972'
'Jul 1 1972'
'Jan 1 1973'
'Jan 1 1974'
'Jan 1 1975'
'Jan 1 1976'
'Jan 1 1977'
'Jan 1 1978'
'Jan 1 1979'
'Jan 1 1980'
'Jul 1 1981'
'Jul 1 1982'
'Jul 1 1983'
'Jul 1 1985'
'Jan 1 1988'
'Jan 1 1990'
'Jan 1 1991'
'Jul 1 1992'
'Jul 1 1993'
'Jul 1 1994'
'Jan 1 1996'
'Jul 1 1997'
'Jan 1 1999'
'Jan 1 2006'
'Jan 1 2009'
'Jul 1 2012'
'Jul 1 2015'
'Jan 1 2017'];
%% Convert Steps to datenums and make step offsets
step=[0;10;ones(length(stepdate)-1,1);Inf]/86400;
steptime=cumsum(step);
jansteps=strfind(stepdate(:,2)','a')'; %guptime can handle leaps over new year
stepdate=[-Inf;datenum(stepdate);Inf]; %step date conversion
ncol=size(date0,2);
ns_in=0;
%% Arg Checking
if contains('tai unx',dir{1})
if ncol>1
ns=date0(:,2); ns_in=1;
else
ns=rem(date0,1)*1e9;
end
date0=fix(date0(:,1))/86400+unx0;
elseif strcmp('gup',dir{1})
if ncol>2
ns=date0(:,3); date0(:,2)=date0(:,2)+ns*1e-9; ns_in=1;
else
ns=rem(date0(:,2),1)*1e9;
end
leapin=find(date0(:,2)>=365*86400); % tentative leaps
date0=fix(date0(:,2))/86400+datenum(date0(:,1),1,1);
else
if strcmp('kst',dir{1})
date0=sscanf(sprintf('%04d%04d%04d',date0),'%02d%02d%02d%02d%02d%02d',[6 Inf])';
date0(:,1)=date0(:,1)+1900; dir{1}='utc'; ncol=6;
elseif strcmp('utc',dir{1}) && ncol>5 % extract secs>=60
if ncol>6
ns=date0(:,7); date0(:,7:end)=[]; ns_in=1;
else
ns=rem(date0(:,6),1)*1e9; date0(:,6)=fix(date0(:,6));
end
leapin=find(date0(:,6)>=60); % tentative leaps
elseif ncol>1
inleap=date0(:,2); date0(:,2:end)=[];
end
date0=datenum(date0); %will error if not a proper format
if ~exist('ns') & ~ns_in
ns=rem(date0*86400,1)*1e9; date0=fix(date0*86400)/86400;
end
end
%% Conversion to tai
if ~strcmp(dir{1},'tai')
l=discretize(date0,stepdate);
if ~isempty(leapin)
stepdates=sort([stepdate;stepdate(2:end-1)+step(2:end-1)]);
l60=discretize(date0(leapin),stepdates);
d=find(rem(l60,2)==0);
l(leapin(d))=l(leapin(d))-1; % valid leaps
elseif ~isempty(inleap)
d=find(steptime(l)*86400~=inleap);
date0(d)=date0(d)-step(l(d));
end
date0=date0+steptime(l);
end
l=discretize(date0,stepdate+steptime);
leaps=steptime(l)*86400;
%% Conversion from tai
if strcmp(dir{2},'tai')
date=round((date0-unx0)*86400);
if ns_in
date=[date ns];
else
date=date+ns*1e-9;
end
elseif strcmp(dir{2},'utc')
date=date0-steptime(l);
stepdates=sort([stepdate+steptime;stepdate(2:end-1)+steptime(1:end-2)]);
l60=discretize(date0,stepdates);
d=find(rem(l60,2)==0);
date(d)=date(d)-1;
date=round(datevec(date));
ld=length(d);
date(d,4:6)=[repmat([23 59 60],ld,1)+[zeros(ld,2) date(d,6)]];
if ns_in
date=[date ns];
else
date(:,6)=date(:,6)+ns*1e-9;
end
else
date=date0-steptime(l);
if strcmp('unx',dir{2})
date=round((date-unx0)*86400);
if ns_in
date=[date ns];
else
date=date+ns*1e-9;
end
elseif strcmp('gup',dir{2})
stepdates=sort([stepdate+steptime;stepdate(2:end-1)+steptime(1:end-2)]);
l60=discretize(date0,stepdates);
i=find(rem(l60,2)==0 & ismember(l60/2,jansteps));
dated=datevec(date);
dated(i,1)=dated(i,1)-1;
date=[dated(:,1) round((date-datenum(dated(:,1),1,1))*86400)];
if ns_in
date=[date ns];
else
date(:,2)=date(:,2)+ns*1e-9;
end
elseif strcmp('mat',dir{2})
if ns_in
date=[date ns];
else
date=date+ns/86400e9;
end
end
end