1

Suppose that we have these two types of dates:

type_1 = {'23.2.2005', '23.4.2015', '5.1.2015'};

type_2 = {'23.02.2005', '23.04.2015', '05.01.2015'};

When we compare these two types using this function:

ismember(type_1,type_2)

These isn't any equality in these two types (because of adding zero in type2). How we can correctly compare these two types?

Eghbal
  • 3,892
  • 13
  • 51
  • 112

3 Answers3

6

Another way is to use datestr and datenum to enforce the extra zeroes for conversion.

type_1 = datestr(datenum(type_1, 'dd.mm.yyyy'), 'dd.mm.yyyy');
type_2 = datestr(datenum(type_2, 'dd.mm.yyyy'), 'dd.mm.yyyy');

datestr requires a MATLAB date number to be able to output a string representation of a date. That's why datenum is used and you can see that even though we specify two digits for the month or day, it's smart enough to sense that if there is one digit for these quantities and the date number is successfully converted. We'd then use these date numbers to pipe into datestr to ensure that we have extra zeroes when we need them.

However, this will convert the cell arrays into character arrays. You'll have to put these back into cell arrays by using cellstr:

type_1 = cellstr(type_1);
type_2 = cellstr(type_2);

Here's some sample output:

>> type_1 = {'23.2.2005', '23.4.2015', '5.1.2015'}

type_1 = 

    '23.2.2005'    '23.4.2015'    '5.1.2015'

>> type_2 = {'23.02.2005', '23.04.2015', '05.01.2015'}

type_2 = 

    '23.02.2005'    '23.04.2015'    '05.01.2015'

>> type_1 = datestr(datenum(type_1, 'dd.mm.yyyy'), 'dd.mm.yyyy')

type_1 =

23.02.2005
23.04.2015
05.01.2015

>> type_2 = datestr(datenum(type_2, 'dd.mm.yyyy'), 'dd.mm.yyyy')

type_2 =

23.02.2005
23.04.2015
05.01.2015

>> type_1 = cellstr(type_1)

type_1 = 

    '23.02.2005'
    '23.04.2015'
    '05.01.2015'

>> type_2 = cellstr(type_2)

type_2 = 

    '23.02.2005'
    '23.04.2015'
    '05.01.2015'

>> ismember(type_1, type_2)

ans =

     1
     1
     1
rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • 2
    I was just about to post this ... :'( – TroyHaskin Feb 12 '16 at 00:30
  • @TroyHaskin Sorry :( This is the second time I seem to be getting into your head. http://stackoverflow.com/questions/34641506/calculate-angle-of-n-dimensional-vector-in-matlab - remember this conversation? – rayryeng Feb 12 '16 at 00:37
  • 3
    Indeed. I always fallback to the Great Minds explanation. +1 – TroyHaskin Feb 12 '16 at 00:38
  • 2
    Possibly worth noting that you can compare the `datenum` quantities directly if like-formatted strings aren't necessary later on (though I'd probably do it anyway, having dissimilar formats would bother me) – sco1 Feb 12 '16 at 00:41
  • 2
    @excaza I wasn't sure whether the exact representation of the date given by the OP is required so I decided to convert back to a cell array of strings to be sure, but if it were me I agree. I'd simply use `datenum` and leave it at that to facilitate comparison of dates. – rayryeng Feb 12 '16 at 01:10
5

This avoids using regexp, by using numeric conversion tricks:

del0str     = @(x) sprintf('%d.%d.%d',sscanf(x,'%d.%d.%d'));
del0cell    = @(x) cellfun(del0str, x, 'UniformOutput', false);
[ix1, ix2]  = ismember(del0cell(type_1), del0cell(type_2));

Please note that this works regardless the order or day/month/year in a date, as long as the order is consistent between the two cell array of dates.

  • 3
    @rayryeng Thanks! I would do *anything* to avoid debugging a `regexp`, starting with not writing one in the first place. :-D –  Feb 12 '16 at 00:25
  • I avoid regex whenever possible. It's tricky to use the right search string here.... so bravo! – rayryeng Feb 12 '16 at 00:32
  • 2
    True story on that, @rayryeng. It even looks like the `datetime` object calls a full blown parser (I'm guessing since its a mex file) for creating the strings, which is always best (though not always practical). – TroyHaskin Feb 12 '16 at 00:39
3

The "modern" (R2014b+) way would be to use MATLAB's datetime class, like so:

>> dt1 = datetime(type_1, 'InputFormat', 'dd.MM.yyyy')
dt1 = 
   23-Feb-2005   23-Apr-2015   05-Jan-2015
>> dt2 = datetime(type_2, 'InputFormat', 'dd.MM.yyyy')
dt2 = 
   23-Feb-2005   23-Apr-2015   05-Jan-2015
>> ismember(dt1, dt2)
ans =
     1     1     1
Edric
  • 23,676
  • 2
  • 38
  • 40