function varargout = GUI_DateConversions(varargin)
% GUI_DATECONVERSIONS M-file for GUI_DateConversions.fig
% GUI_DATECONVERSIONS, by itself, creates a new GUI_DATECONVERSIONS or raises the existing
% singleton*.
%
% H = GUI_DATECONVERSIONS returns the handle to a new GUI_DATECONVERSIONS or the handle to
% the existing singleton*.
%
% GUI_DATECONVERSIONS('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in GUI_DATECONVERSIONS.M with the given input arguments.
%
% GUI_DATECONVERSIONS('Property','Value',...) creates a new GUI_DATECONVERSIONS or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before GUI_DateConversions_OpeningFunction gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to GUI_DateConversions_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Copyright 2002-2003 The MathWorks, Inc.
% Edit the above text to modify the response to help GUI_DateConversions
% Last Modified by GUIDE v2.5 17-Jul-2007 10:37:43
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @GUI_DateConversions_OpeningFcn, ...
'gui_OutputFcn', @GUI_DateConversions_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before GUI_DateConversions is made visible.
function GUI_DateConversions_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to GUI_DateConversions (see VARARGIN)
% Choose default command line output for GUI_DateConversions
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
%=========================================================================
% Initialization commands/functions
%=========================================================================
radiobutton_GPStime_Callback(handles.radiobutton_GPStime, eventdata, handles)
% Initialize the date to current date & time
c = clock;
Year = c(1);
Month = c(2);
Day = c(3);
Hour = c(4);
Minute= c(5);
Second= c(6);
set( handles.edit_Year,'String', num2str(Year) );
set( handles.popupmenu_Month, 'Value', Month );
set( handles.edit_Day, 'String', num2str(Day) );
set( handles.edit_Hour,'String', num2str(Hour) );
set( handles.edit_Minute,'String',num2str(Minute) );
set( handles.edit_Second,'String',num2str(Second) );
% UIWAIT makes GUI_DateConversions wait for user response (see UIRESUME)
% uiwait(handles.figure_DateConversions);
% --- Outputs from this function are returned to the command line.
function varargout = GUI_DateConversions_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in radiobutton_GPStime.
function radiobutton_GPStime_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton_GPStime (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton_GPStime
%---------------------------------------------------------------------
% When computing GPS time, the modifiable inputs are the calendar date
% options
%---------------------------------------------------------------------
% Turn on the calendar date edit boxes
set(handles.edit_Day,'enable','on');
set(handles.popupmenu_Month,'enable','on');
set(handles.edit_Year,'enable','on');
set(handles.edit_Hour,'enable','on');
set(handles.edit_Minute,'enable','on');
set(handles.edit_Second,'enable','on');
% Turn off the GPS time edit boxes
set(handles.edit_GPStime,'enable','off');
set(handles.edit_WeekNum,'enable','off');
set(handles.edit_RollOvers,'enable','off');
% --- Executes on button press in radiobutton_CalendarDate.
function radiobutton_CalendarDate_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton_CalendarDate (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of
% radiobutton_CalendarDate
%---------------------------------------------------------------------
% When computing Calendar date, the modifiable inputs are the GPS time
% options
%---------------------------------------------------------------------
% Turn off the GPS time edit boxes
set(handles.edit_GPStime,'enable','on');
set(handles.edit_WeekNum,'enable','on');
set(handles.edit_RollOvers,'enable','on');
% Turn on the calendar date edit boxes
set(handles.edit_Day,'enable','off');
set(handles.popupmenu_Month,'enable','off');
set(handles.edit_Year,'enable','off');
set(handles.edit_Hour,'enable','off');
set(handles.edit_Minute,'enable','off');
set(handles.edit_Second,'enable','off');
% --- Executes on button press in pushbutton_Compute.
function pushbutton_Compute_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton_Compute (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%---------------------------------------------------------------------
% Check to see what kind of computation will be performed
%---------------------------------------------------------------------
if ( get(handles.radiobutton_GPStime,'value') == true )
% Extract date from GUI inputs
day = str2num( get(handles.edit_Day,'string') );
monthStr = get(handles.popupmenu_Month,'string');
monthIdx = get(handles.popupmenu_Month,'value');
month = monthStr{ monthIdx };
year = str2num( get(handles.edit_Year,'string') );
hour = str2num( get(handles.edit_Hour,'string') );
minute = str2num( get(handles.edit_Minute,'string') );
seconds = str2num( get(handles.edit_Second,'string') );
% The calendar interface function is responsible for taking the
% calendar inputs, and generating YMDS output
YMDS = CalendarInterface(day,...
month,...
year,...
hour,...
minute,...
seconds );
% Compute Julian day number
JD = CalendarDate2JulianDay( YMDS );
% Compute the day of the week from the Julian day number
weekDay = JulianDay2WeekDay(JD);
% Compute GPS time from the calendar date
[gpsTimeOfWeek, gpsWeekNum, gpsCycle] = JulianDay2GPS(JD);
% Store results of the computation in the GUI window
set(handles.edit_GPStime, 'String', num2str(gpsTimeOfWeek) );
set(handles.edit_WeekNum, 'String', num2str(gpsWeekNum) );
set(handles.edit_RollOvers, 'String', num2str(gpsCycle) );
set(handles.edit_JulianDate, 'String', num2str(JD));
set(handles.edit_WeekDay, 'String', weekDay);
elseif ( get(handles.radiobutton_CalendarDate, 'value') == true )
% Extract GPS time from GUI inputs
gpsTimeOfWeek = str2num( get(handles.edit_GPStime, 'String') );
gpsWeekNum = str2num( get(handles.edit_WeekNum, 'String') );
gpsCycle = str2num( get(handles.edit_RollOvers,'String'));
% Compute Julian day (decimal value) from the GPS time
JD = GPS2JulianDay( gpsTimeOfWeek,...
gpsWeekNum,...
gpsCycle );
% Compute the day of the week from the Julian day number
weekDay = JulianDay2WeekDay(JD);
% Compute Calendar date from Julian day
YMDS = JulianDay2CalendarDate(JD);
year = YMDS(1);
month = YMDS(2);
day = YMDS(3);
sam = YMDS(4);
% Convert SAM to HMS
TOL = 0.000001; % floor function is sensitive to near-zero values
hour = floor ((sam / 3600) + TOL);
minute = floor( ((sam - (hour * 3600) ) / 60 ) + TOL );
second = quant( sam - hour * 3600 - minute * 60, 0.001 );
% Display results in GUI window
set( handles.edit_Day, 'String', num2str( day ) );
set( handles.popupmenu_Month, 'value', month );
set( handles.edit_Year,'String',num2str(year) );
set( handles.edit_Hour,'String',num2str(hour) );
set( handles.edit_Minute,'String',num2str(minute) );
set( handles.edit_Second,'String',num2str(second) );
set( handles.edit_JulianDate, 'String', num2str(JD) );
set( handles.edit_WeekDay, 'String', weekDay );
end
%=========================================================================
% FUNCTIONS EXTERNAL TO THE GUI
%=========================================================================
function YMDS = CalendarInterface(varargin)
% CALENDARINTERFACE The date conversion functions were written to
% utilize Year, Month, Day, Second (YMDS) inputs.
% Actually, seconds are Seconds After Midgnight (SAM)
% There are several feasible ways of inputting this
% information:
%
% 1) a YMDS vector where:
% YMDS(1) = year (i.e. 2007)
% YMDS(2) = month (i.e. 1 for January, 12 for December)
% YMDS(3) = day of the month
% YMDS(4) = seconds into the current day
%
% 2) The "standard" Gregorian date format 1, i.e. Day, Month Year, HMS
% day = day of the month
% month = 'Jan','Feb','Mar',....,'Dec'
% year = 2007
% hour = 0 - 24
% minute = 0 - 60
% seconds = 0 - 60
%
% 3) The "standard" Gregorian date format, i.e. Day, Month Year, seconds
% after midnight (SAM)
% day = day of the month
% month = 'Jan','Feb','Mar',....,'Dec'
% year = 2007
% sam = 0 - 86400
%
% Constants
SEC_PER_MINUTE = 60;
SEC_PER_HOUR = 3600;
SEC_PER_DAY = 86400;
SEC_PER_WEEK = 604800;
BIRTH_YEAR = 1980; % Birth year of GPS = Jan 5, 1980
NUM_GPS_WEEKS = 1024; % Number of GPS weeks before a week rollover
% Create a string vector of the months of the year. Obviously, based
% on the ordering, string row index will correspond to month number
monthString = str2mat('JANUARY',...
'FEBRUARY',...
'MARCH',...
'APRIL',...
'MAY',...
'JUNE',...
'JULY',...
'AUGUST',...
'SEPTEMBER',...
'OCTOBER',...
'NOVEMBER',...
'DECEMBER');
%---------------------------------------------------------------------
% Extract YMDS from the input, depending on how the input was specified
%---------------------------------------------------------------------
if( length(varargin) == 1 )
% YMDS format
year = varargin{1}(1);
month = varargin{1}(2);
day = varargin{1}(3);
sam = varargin{1}(4);
elseif( length(varargin) == 6 )
% Calendar Date (Gregorian Calendar)
% Day, Month, Year, Hour, Minute, Seconds
year = varargin{3};
month = strmatch( upper(varargin{2}), monthString); % Index = month #
day = varargin{1};
sam = SEC_PER_HOUR * varargin{4}...
+ SEC_PER_MINUTE * varargin{5}...
+ varargin{6};
elseif( length(varargin) == 4 )
% Calendar Date (Gregorian Calendar)
% Day, Month, Year, Seconds After Midnight (SAM)
year = varargin{3};
month = strmatch( upper(varargin{2}), months); % Index = month #
day = varargin{1};
sam = varargin{4};
else
error( 'Invalid set of inputs. Please check and try again...');
end
% Put output into YMDS format
YMDS(1) = year;
YMDS(2) = month;
YMDS(3) = day;
YMDS(4) = sam;
function JD = CalendarDate2JulianDay(YMDS)
% CALENDARDATE2JULIANDAY Computes the decimal value of the julian day
% number based on the calendar inputs of YMDS.
% The Julian day is useful for computing elapsed
% time without needing a numerical algorithm to
% keep track of the number of days in each month,
% and how to add an extra day during each leap
% year
% Constants
SEC_PER_DAY = 86400;
% Extract YMDS
year = YMDS(1);
month = YMDS(2);
day = YMDS(3);
sec = YMDS(4);
% Compute julian day number
a = floor( (14 - month) / 12 );
y = year + 4800 - a;
m = month + 12*a - 3;
% Assume the Gregorian calendar is used (leap seconds not included)
JD = day...
+ floor( (153 * m + 2) / 5)...
+ 365 * y...
+ floor( y / 4)...
- floor( y / 100)...
+ floor( y / 400)...
- 32045 ...
- 0.5 ...
+ (sec/SEC_PER_DAY);
% Alternately, the Julian calendar could be used (very similar)
% (Leap seconds not included)
% JD = day ...
% + floor( (153 * m + 2) / 5) ...
% + 365 * y ...
% + floor( y / 4) ...
% - 32083 ...
% + (sec/SEC_PER_DAY);
function weekDay = JulianDay2WeekDay(JD)
% Day of week string
weekDayStr = {'Monday'
'Tuesday'
'Wednesday'
'Thursday'
'Friday'
'Saturday'
'Sunday'
};
% Round the julian day to the current day
% To get the calculation to come out correctly, had to add 0.5 day.
% Probably something to do with Julian days starting at noon
JulianDay = floor(JD + 0.5);
% The day of the week is the remainder of (JulianDay/7), with 0
% corresponding to a Monday. Compute the index of the weekday array
idx = mod(JulianDay, 7) + 1;
weekDay = weekDayStr{idx};
function [gpsTimeOfWeek, gpsWeekNum, gpsCycle] = JulianDay2GPS(JD)
% JULIANDAY2GPS Compute the GPS time and week number using the
% Julian day. This is an instance where we compute
% the elapsed time since the inception of GPS
% (midnight of January 5, 1980), and avoid dealing
% with the nuances of leap year days, etc.
% Constants
SEC_PER_DAY = 86400;
NUM_GPS_WEEKS = 1024; % Number of GPS weeks before a week rollover
% Julian day number of the birthday of GPS (Midnight of January 5, 1980)
% Can compute using January 6, 1980, HMS = 00:00:00
JD_GPS = 2444244.5;
% Compute the number of elapsed (decimal) days since start of GPS
nDays = JD - JD_GPS;
% Compute seconds after midnight (SAM)
sam = ( nDays - floor(nDays) ) * SEC_PER_DAY;
% Initial GPS week number
gpsWeekNum = floor(nDays/7);
% Keep track of the number of week rollovers
gpsCycle = floor( gpsWeekNum / NUM_GPS_WEEKS );
% Report GPS week number modulo 1024
gpsWeekNum = mod(gpsWeekNum,NUM_GPS_WEEKS);
% Number of days into the current week
nDays = mod(floor(nDays),7);
% Compute GPS time of week (seconds since Saturday/Sunday midnight)
gpsTimeOfWeek = nDays * SEC_PER_DAY + sam;
function JD = GPS2JulianDay( gpsTimeOfWeek, gpsWeekNum, gpsCycle )
% GPS2JULIANDAY Computes the Julian day from a GPS time and week
% number. Normally the intermediate step to
% computing the calendar date
% Constants
SEC_PER_DAY = 86400;
NUM_GPS_WEEKS = 1024; % Number of GPS weeks before a week rollover
% Julian day number of the birthday of GPS (Midnight of January 5, 1980)
% Can compute using January 6, 1980, HMS = 00:00:00
JD_GPS = 2444244.5;
% Compute the (decimal) number of elapsed days since the start of GPS
gpsDays = ((gpsCycle * NUM_GPS_WEEKS) + gpsWeekNum) * 7 ...
+ gpsTimeOfWeek / SEC_PER_DAY...
+ 0.5;
% Compute the current (decimal) Julian Day
JD = JD_GPS + gpsDays - 0.5;
function YMDS = JulianDay2CalendarDate(JD)
% JULIANDAY2CALENDARDATE Compute the (Gregorian) calendar date from the
% (decimal) Julian day.
% Constants
SEC_PER_DAY = 86400;
% Most of the calculations do not need the decimal portion
JDN = floor(JD);
% Compute Seconds After Midnight (SAM) - note that days in the Julian
% date system start at 12:00pm, so must adjust the SAM accordingly
partialDay = JD - JDN;
if ( (partialDay >= 0) && (partialDay < 0.5) )
sam = (partialDay + 0.5) * SEC_PER_DAY;
elseif( (partialDay >= 0.5) && (partialDay < 1.0) )
sam = (partialDay - 0.5) * SEC_PER_DAY;
else
error('SAM requires partial days, i.e. less than 86400 seconds!');
end
% Compute YMD
Z = JD + 0.5 ;
W = floor( (Z - 1867216.25) / 36524.25 );
X = floor( W / 4 );
A = Z + 1 + W - X;
B = A + 1524;
C = floor( (B - 122.1) / 365.25 );
D = floor( 365.25 * C );
E = floor( (B - D) / 30.6001 );
F = floor( 30.6001 * E );
% Compute day of the month
day = floor(B - D - F);
% Compute month of the year
if( (E - 1) <= 12 )
month = E - 1;
elseif( (E-13) <= 12 )
month = E - 13;
else
error('Can''t get number less than 12 in JulianDay2CalendarDate');
end
% Compute year
if ( month < 3 )
year = C - 4715;
else
year = C - 4716;
end
YMDS(1) = year;
YMDS(2) = month;
YMDS(3) = day;
YMDS(4) = sam;