No BSD License  

Highlights from
Date Conversion Utility GUI

image thumbnail
from Date Conversion Utility GUI by Chad Webb
A GUI utility to compute calendar date, GPS time, Julian day, and day of the week

GUI_DateConversions(varargin)
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;


Contact us at files@mathworks.com