display clock time from decimal time in matlab - matlab

I have this code as part of my program to calculate the solar time. But my calculation using decimal time. And now, I need to display the result in clock time.
%To calculate solar time
stime = time + (((4*(Lloc-Lsm))+ Et)/60);
disp(['The true solar time is ' num2str(stime),'hr']); %To display the solar time
The answer goes like this:
The true solar time is 13.0501hr
How can I convert the time to clock time (12hr or 24 hr format). i.e the minute should multiply by 60 (0.0501*60min = 3.006) and the time should display as 13:03 or 1:03PM.
Appreciate your help. Thank you.
Regards, -researcher-

you can use the following
my_hour = floor(stime);
my_minute = round(mod(stime, 1) * 60);
disp(['The true solar time is ', num2str(my_hour), ':', num2str(my_minute)]);

Use datenum to convert to a serial date number and then datestr to build the string with appropriate format:
h = 13.0501; %// your computed decimal time
string = datestr(datenum([0 0 0 h 0 0]),14); %// or change "14" for other formats
The two formats you specify correspond to formats 13 through 16 in datestr (see link to the documentation above). For example, with format 14 the string is
>> disp(string)
1:03:00 PM

Related

Convert milliseconds into hours and plot

I'm trying to convert an array of milliseconds and its respective data. However I want to do so in hours and minutes.
Millis = [60000 120000 180000 240000....]
Power = [ 12 14 12 13 14 ...]
I've set it up so the data records every minute, hence the 60000 millis (= 1 minimte). I am trying to plot time on the x axis and power on the y. I would like to have the x axis displayed in hours and minutes with each respective power data corresponding to its respective time.
I've tried this
for i=2:length(Millis)
Conv2Min(i) = Millis(i) / 60000;
Time(i) = startTime + Conv2Min(i);
if (Time(i-1) > Time(i) + 60)
Time(i) + 100;
end
end
s = num2str(Time);
This in attempt to turn the milliseconds into hours starting at 08:00 and once 60 minutes have past going to 09:00, the problem is plotting this. I get a gap between 08:59 and 09:00. I also cannot maintain the 0=initial 0.
In this scenario it is preferable to work with datenum values and then use datetick to set the format of the tick labels of your plot to 'HH:MM'.
Let's suppose that you started taking measurements at t_1 = [HH_1, MM_1] and stopped taking measurements at t_2 = [HH_2, MM_2].
A cool trick to generate the array of datenum values is to use the following expression:
time_datenums = HH_1/24 + MM_1/1440 : 1/1440 : HH_2/24 + MM_2/1440;
Explanation:
We are creating a regularly-spaced vector time_datenums = A:B:C using the colon (:) operator, where A is the starting datenum value, B is the increment between datenum values and C is the ending datenum value.
Since your measurements have been taken every minute (60000 milliseconds), then the increment between datenum values should be of 1 minute too. As a day has 24 hours, that makes 1440 minutes a day, so use B = 1/1440 as the increment between vector elements, to get 1 minute increments.
For A and C we simply need to divide the hour digits by 24 and the minute digits by 1440 and sum them up like this:
A = HH_1/24 + MM_1/1440
C = HH_2/24 + MM_2/1440
So for example, if t_1 = [08, 00], then A = 08/24 + 00/1440. As simple as that.
Notice that this procedure doesn't use the datenum function at all, and still, it manages to generate a valid array of datenum values only taking into consideration the time of the datenum, without needing to bother about the date of the datenum. You can learn more about this here and here.
Going back to your original problem, let's have a look at the code:
time_millisec = 0:60000:9e6; % Time array in milliseconds.
power = 10*rand(size(time_millisec)); % Random power data.
% Elapsed time in milliseconds.
elapsed_millisec = time_millisec(end) - time_millisec(1);
% Integer part of elapsed hours.
elapsed_hours_int = fix(elapsed_millisec/(1000*60*60));
% Fractional part of elapsed hours.
elapsed_hours_frac = (elapsed_millisec/(1000*60*60)) - elapsed_hours_int;
t_1 = [08, 00]; % Start time 08:00
t_2 = [t_1(1) + elapsed_hours_int, t_1(2) + elapsed_hours_frac*60]; % Compute End time.
HH_1 = t_1(1); % Hour digits of t_1
MM_1 = t_1(2); % Minute digits of t_1
HH_2 = t_2(1); % Hour digits of t_2
MM_2 = t_2(2); % Minute digits of t_2
time_datenums = HH_1/24+MM_1/1440:1/1440:HH_2/24+MM_2/1440; % Array of datenums.
plot(time_datenums, power); % Plot data.
datetick('x', 'HH:MM'); % Set 'HH:MM' datetick format for the x axis.
This is the output:
I would use datenums:
Millis = [60000 120000 180000 240000 360000];
Power = [ 12 14 12 13 14 ];
d = [2017 05 01 08 00 00]; %starting point (y,m,d,h,m,s)
d = repmat(d,[length(Millis),1]);
d(:,6)=Millis/1000; %add them as seconds
D=datenum(d); %convert to datenums
plot(D,Power) %plot
datetick('x','HH:MM') %set the x-axis to datenums with HH:MM as format
an even shorter approach would be: (thanks to codeaviator for the idea)
Millis = [60000 120000 180000 240000 360000];
Power = [ 12 14 12 13 14 ];
D = 8/24+Millis/86400000; %24h / day, 86400000ms / day
plot(D,Power) %plot
datetick('x','HH:MM') %set the x-axis to datenums with HH:MM as format
I guess, there is an easier way using datetick and datenum, but I couldn't figure it out. This should solve your problem for now:
Millis=6e4:6e4:6e6;
power=randi([5 15],1,numel(Millis));
hours=floor(Millis/(6e4*60))+8; minutes=mod(Millis,(6e4*60))/6e4; % Calculate the hours and minutes of your Millisecond vector.
plot(Millis,power)
xlabels=arrayfun(#(x,y) sprintf('%d:%d',x,y),hours,minutes,'UniformOutput',0); % Create time-strings of the format HH:MM for your XTickLabels
tickDist=10; % define how often you want your XTicks (e.g. 1 if you want the ticks every minute)
set(gca,'XTick',Millis(tickDist:tickDist:end),'XTickLabel',xlabels(tickDist:tickDist:end))

Generate timestamp series in Matlab?

all
I wonder if there is a way to generate timestamp series in Matlab ?
I assume there will be a start time, a end time, and a frequency.
It is simple to generate normal series using 1:1:100 (1 to 100 by 1)
How I can use a similar way to generate a time stamp series?
For instance, I specify start time as 9am, up to 10am, I want to generate something like 9:00:00:000, 9:00:00:500, 9:00:01:000, ....
gaped by 500 millisecond
Or even better, include date as well.
Use datenum, the only problem you might have is that your colliding with a gap second/day or summer savings time if you're spanning a long time period (but I don't think that's implemented in datestr as you can read here).
Play around with datenum, now and datestr
starttime = datenum(2000, 1, 1, 9, 0, 0);
dt = 0.500/86400; % datenum is a serial time format with 1 = 1 day = 86400 sec
N = 5;
timevec = starttime + dt*(0:(N-1));
>> datestr(timevec, 'HH:MM:SS.FFF')
ans =
09:00:00.000
09:00:00.500
09:00:01.000
09:00:01.500
09:00:02.000
Starting from 2015a, you can use the milliseconds function to build a vector of timesteps between to time points:
start = datetime('2017/1/3 9:00:00:000','InputFormat','yyyy/MM/dd H:mm:ss:SSS');
step = milliseconds(500);
fin = datetime('2017/1/3 10:00:00:000','InputFormat','yyyy/MM/dd H:mm:ss:SSS');
time_vec = start:step:fin;
If you don't define the date explicitly it will choose the current date.
You can also have one structure for both the time and the data, you can use the timeseries class (using start from above):
data = rand(7201,1);
ts = timeseries(data,'Name','MyTs');
ts.TimeInfo.StartDate = start;
ts.TimeInfo.Units = 'milliseconds';
ts = setuniformtime(ts,'Interval',500);
This will create a time series object:
>> ts
timeseries
Common Properties:
Name: 'MyTs'
Time: [7201x1 double]
TimeInfo: [1x1 tsdata.timemetadata]
Data: [7201x1 double]
DataInfo: [1x1 tsdata.datametadata]
with the following time info:
>> ts.TimeInfo
tsdata.timemetadata
Package: tsdata
Uniform Time:
Length 7201
Increment 500 milliseconds
Time Range:
Start 03-Jan-2017 09:00:00
End 03-Jan-2017 10:00:00
Common Properties:
Units: 'milliseconds'
Format: ''
StartDate: '03-Jan-2017 09:00:00'
It depends on your needs, but you can consider using the combination of datetime() and one or many of days(), hours(), minutes(), seconds() etc. functions.
Lets write some code:
start=datetime(1985,07,13,9,0,0); % your start date
steps=seconds(0:0.5:100); % your vector with steps
timeseries=start+steps; % your time series
you can also set format for displaying data that meets your needs, to do so check datetime properties manual.

matlab: how to find interval of data

I have a dataset of trajectories of users: every current location of the traiectories has these fields:_ [userId year month day hour minute second latitude longitude regionId]. Based on the field day, I want to divide trajectories based on daily-scale in interval of different hours: 3 hours, 4 hours, 2 hours. I have realized this code that run for interval of 4 hours
% decomposedTraj is a struct that contains the trajectories based on daily scale
for i=1:size(decomposedTraj,2)
if ~isempty(decomposedTraj(i).dailyScaled)
% find the intervals
% interval [0-4]hours
Interval(i).interval_1=(decomposedTraj(i).dailyScaled(:,5)>=0&decomposedTraj(i).dailyScaled(:,5)<4);
% interval [4-8]hours
Interval(i).interval_2=(decomposedTraj(i).dailyScaled(:,5)>=4&decomposedTraj(i).dailyScaled(:,5)<8);
% interval [8-12]hours
Interval(i).interval_3=(decomposedTraj(i).dailyScaled(:,5)>=8&decomposedTraj(i).dailyScaled(:,5)<12);
% interval [12-16]hours
Interval(i).interval_4=(decomposedTraj(i).dailyScaled(:,5)>=12&decomposedTraj(i).dailyScaled(:,5)<16);
% interval [16-20]hours
Interval(i).interval_5=(decomposedTraj(i).dailyScaled(:,5)>=16&decomposedTraj(i).dailyScaled(:,5)<20);
% interval [20-0]hours
Interval(i).interval_6=(decomposedTraj(i).dailyScaled(:,5)>=20);
end
end
or more easily to understand the logic of the code:
A=[22;19;15;15;0;20;22;19;15;15;0;20;20;0;22;21;17;23;22]';
A(A>=0&A<4)
A(A>=4&A<8)
A(A>=8&A<12)
A(A>=12&A<16)
A(A>=16&A<20)
A(A>=20)
It runs and gives the right answer but it's not smart: if I want to change the interval, I have to change all the code... can you help me to find a smart solution more dinamical of this? thanks
0 Comments
Interval k is defined as [(k-1)*N k*N] where N=4 in your example. Therefore you can do the same using a for loop:
for k=1:floor(24/N)
Interval(k) = A(A>=(k-1)*N & A<k*N);
end
Note that in this example A(A>=(k-1)*N & A<k*N) is not necessarily the same size for each k so Interval should be a cell array.

clock Time on x-axis in matlab

I need some help related to plots in MATLAB.
I want to plot my data with respect to clock time on x-axis. I have an occupancy information data for every 15 minutes interval. I want to plot it against time. How can i do it? The problem is with the x-axis, how can i handle time and uniform intervals e.g data is of the form
data=[1 0 0 0 0 1 1 1 1 0 0 0 .............]
value of time is from 9 AM to 9 PM and the interval is 15 minutes
How can i set the intervals on the x-axis?
Thank you
The following code solves the problem. you enter Integer values for starting hour and minute, the ending time and the time steps between the measurements. Further enter/change the steps_x value. This shows how many time values are skipped on the x-axis. 7=skip6 values. Below the for-loop is my y-data. I just used random-function.
The resulting x-axis is a cell-array. This could be a problem for some applications. Further I used some 'unneccessary' variables. These i used for verifing my code. I didn't change it, because i thought that it would be easier to understand that way.
The biggest problem of my so
clc; clear all; close all;
%%//Variable declaration
start_hour = 9; %in hours
start_min = 5; %//in minutes
steps_min = 10; %//in minutes
end_hour = 21.0; %//in hours
end_min= 0; %//in minutes
steps_x = 7; %//how many times are displayed on the axis, doesn't change data
%%// code for computing internal values, steps and transforming to am/pm
%//changes the entries above to hour display(9.75=9h45min)
start_time= (start_hour+start_min/60);
%//changes the entries above to hour display(9.75=9h45min)
end_time=(end_hour+end_min/60);
%//changes steps to hour
steps_hour= steps_min/60;
%//array of hours
mytest_timeline = start_time:steps_hour:end_time;
%//array of minutes(copied and modified from #natan)
mytest_minutes = mod((0:steps_min:(steps_min*(length(mytest_timeline)-1)))+start_min,60);
%//cell array for am/pm display
mytest_timeline_ampm = num2cell(mytest_timeline);
%//if hour is smaller 12 write am otherwise pm
for k=1:length(mytest_timeline);
if mytest_timeline(k) < 12
mytest_ampm = {'am'};
%//converting the down rounded hour to str
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
%//converting the minute to str and giving it 2 digits eg. 05 for 5min
helper_minute = num2str(mytest_minutes(k),'%02d');
%//joining strings
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
%//same as for am just for pm
else
mytest_ampm = {'pm'};
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
helper_minute = num2str(mytest_minutes(k),'%02d');
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
end
end
%%// generated y data so that i could test the code
mytest_y = rand(size(mytest_timeline));
%%// changing display
%//x-coordinates(for displaying x,y)
mytest_x= 1:length(mytest_timeline);
%//x-axis label
mytest_x_axis = 1:steps_x:length(mytest_timeline);
%//plots the data mytest_y in uniform distances (mytest_x)
plot(mytest_x, mytest_y, 'b')
%//changes the x-label accordingly to mytest_x_axis to the am/pm timeline
set(gca, 'XTick',mytest_x_axis, 'XTickLabel',mytest_timeline_ampm(mytest_x_axis))

Matlab: time series plot for 44100 hz data

I'm trying to plot a time series which has been collected at a rate of 44100 hz. I would like to have the time (in seconds) and possibly the date on the x-axis.
Say I have data for one minute, i.e. 2646001 data points and assume, for simplicity, all data points are ones:
y=repmat(1,2646001,1);
I created a vector of date numbers by converting the start and end date into serial date numbers and then create a vector from the first time number to the last time number with rate 44100 hz:
StartTimeNum = datenum(2013,11,12,23,00,0);
EndTimeNum = datenum(2013,11,12,23,01,0);
T = EndTimeNum-StartTimeNum;
TimeNum = StartTimeNum:(T/length(y)):EndTimeNum;
I then define the format I would like the date string to be in and convert the time number vector into time string.
FormatOut = 'dd/mm/yy, HH:MM:SS.FFF';
TimeStr= datestr(TimeNum, FormatOut);
but now TimeStr is a <2646001x22 char>, rather than a <2646001x1 char> which Matlab doesn't allow me to use as the input for the x-axis.
In another attempt I found the timeseries class (http://www.mathworks.co.uk/help/matlab/ref/timeseries.plot.html) which would be perfect, but because my data is in 44100 hz, I am not sure how to define the units (ts1.TimeInfo.Units), which are generally described as 'days', or 'hours' or 'seconds' but not in hz...
Is there any way around this?
Thanks
y=ones(2646001,1); % use ones(m,n) for more efficiency
StartTimeNum = datenum(2013,11,12,23,00,0);
EndTimeNum = datenum(2013,11,12,23,01,0);
T = EndTimeNum-StartTimeNum;
TimeNum = StartTimeNum:(T/(length(y)-1)):EndTimeNum; % length consistent
FormatOut = 'dd/mm/yy, HH:MM:SS.FFF';
figure,plot(TimeNum, y),datetick('x',FormatOut)
Plot your data vs. TimeNum directly, then use datetick to set the labels:
plot(TimeNum, y);
datetick('x', 'dd/mm/yy, HH:MM:SS.FFF');
Or try just datetick with no arguments. The default format might be better.