cell array with date and time
Show older comments
{[11-Jun-1962 00:00:00]}
{[16-Mar-1961 00:00:00]}
{[02-Jun-1934 00:00:00]}
{[02-Jun-1934 00:00:00]}
{[09-Jun-1965 00:00:00]}
{[09-Jun-1965 00:00:00]}
{[13-Apr-1955 00:00:00]}
{[13-Apr-1955 00:00:00]}
{[09-Dec-1947 00:00:00]}
I have a cell array like above.
I want to convert this to a cell array only with dates.
18 Comments
Walter Roberson
on 12 Aug 2019
Are those character vectors, or are they datetime objects?
babyelephant
on 12 Aug 2019
Doesn't this do what you're asking?
dob2.Format = 'dd-MMM-yyyy';
Demo
K>> dob = datetime('now')
dob =
datetime
12-Aug-2019 10:04:31
K>> dob.Format = 'dd-MMM-yyyy'
dob =
datetime
12-Aug-2019
K>> dob = cellstr(dob) % <--- if you must
dob =
1×1 cell array
{'12-Aug-2019'}
madhan ravi
on 12 Aug 2019
"...done this way."
Perhaps the OP implies the task has been accomplished.
Adam Danz
on 12 Aug 2019
Ah, maybe. I interpreted it as a response to Walter showing whether the variable was char or dt.
Guillaume
on 12 Aug 2019
Note that:
dob=cell2table(dob);
dob2=datetime(dob.dob(1:end));
is a convoluted and slow way of doing:
dob2 = datetime(dob);
dpb
on 13 Aug 2019
Also note that a datetime object cannot exist w/o both a date and a time...you can change the 'Format' property to display only the date (or only the time) or almost any imaginable format of both, but the value itself will still contain a full date and time quantity; only the display is changed.
This is completely different behavior than the venerable (and deprecated) datenum which stored dates as the integer portion of a float and time as the fraction of days. Thus, one could "zero out" and keep only the integer or fractional portion. Not possible w/ datetime.
Guillaume
on 13 Aug 2019
Well, you can set the time portion of a datetime to 00:00:00.000, I don't see that being any different than setting the fractional part of a datenum to 0.
dpb
on 13 Aug 2019
That's similar, yes, but there's no equivalent to the obverse. Altho there's a difference still in that int() of a datenum returns a valid date but there is no equiavlent to the numeric portion in a datetime object that can be manipulated with ordinary math operations.
Guillaume
on 13 Aug 2019
Well, yes datetime is not intended to be manipulated as a single number. On the other hand:
dt = dt + years(5)
is a lot simpler than whatever the equivalent would be with datenum (I've actually forgotten how to do it!)
dn = dn + 5 * 365 %is obviously wrong since there's most likely a leap year in the range.
Steven Lord
on 13 Aug 2019
This is completely different behavior than the venerable (and deprecated) datenum which stored dates as the integer portion of a float and time as the fraction of days. Thus, one could "zero out" and keep only the integer or fractional portion. Not possible w/ datetime.
You're right that you can't do this with datetime alone. That's one of the reasons duration exists.
rightNow = datetime('now');
dateWithoutTime = dateshift(rightNow, 'Start', 'day')
timeSinceMidnight = rightNow - dateWithoutTime
rightNow == (dateWithoutTime + timeSinceMidnight) % true
whos rightNow dateWithoutTime timeSinceMidnight
You want to know how many days it's been since midnight, what you would receive from the fractional part of the serial date number? That's easy.
D = days(timeSinceMidnight)
Since it's just after 10:30 in the morning here in Natick as I type this, D is about 0.44. That's just about what I receive by taking mod of the serial date number created from rightNow using datenum on it and 1.
D2 = mod(datenum(rightNow), 1)
You may ask whether or not dateshift is discoverable easily. If you try calling floor on a datetime like you would on a serial date number to truncate it, the error you receive tells you about dateshift (at least in release R2019a, and I suspect in earlier releases as well.)
>> floor(rightNow)
Error using datetime/floor (line 1608)
Undefined function 'floor' for input arguments of type 'datetime'. Use the DATESHIFT function instead.
No argument aginst datetime being more powerful -- the comment was intended only to emphasize the difference as often see people who expect to be able to create a datetime without one or the other of the two components--particularly often the time of day without the date.
But, adding five calendar years isn't that simple with datetime() either... :)
>> t0=datetime(date);
>> t0+years(5)
ans =
datetime
12-Aug-2024 05:06:00
>>
isn't 13-Aug-2024 but something less with odd hours and minutes. years(N) when the argument is numeric returns in units of fixed-length, 365.2425 day years. It has no time reference from which to compute how many leapyears are included in the span so is just long-term average.
To get five "real" years, you have to use the calyears() function
>> t0+calyears(5)
ans =
datetime
13-Aug-2024
>>
which has enough additional logic built into the combination of it and the overloaded plus operator to do the calendar calculations.
OTOH, for this datenum is easy...
>> datestr(datenum(2019+5,8,13))
ans =
'13-Aug-2024'
>>
as it has the calendar arithmetic builtin and so just adding 5 to the year is all that is needed. Now, granted, to get the year from date() string means parsing it back out or using datevec() to extract the components of t0.
>> datestr(datenum(datevec(t0)+[5,0,0,0,0,0]))
ans =
'13-Aug-2024'
>>
This diverged from the point of the comment which wasn't to denigrate datetime but just to emphasize that it is, as you note, a compound object, not just a number like a datenum is (albeit with a very specialized meaning/scaling).
Steven Lord
on 13 Aug 2019
If you have Y, M, and D data adding 5 years is just as easy with datetime as with datenum. In fact, it looks quite similar (modulo not needing the datestr call to get it in a human interpretable form.)
Y = 2019;
M = 8;
D = 13;
T = datetime(Y+5, M, D)
Y2 = year(T)
It's true that when adding to an already existing datetime you do need to distinguish between years and calyears. Of course, as Guillaume pointed out if you're doing this with an existing datenum you need to account for things like leap years yourself.
True, Steven...again the comment wasn't trying to denigrate datetime but just that it is NOT a serial date number...this sidebar has grown legs of its own... :)
"... doing this with an existing datenum you need to account for things like leap years yourself."
The point of doing the arithmetic in the argument to datenum -- just like datetime it has the smarts to do the calendar rollover correctly internally. In my example above the serial date number came out right with datenum and there are two leap years in the time range to account for
>> isleapyr(2019:2024) % my homebuilt utility function
ans =
1×6 logical array
0 1 0 0 0 1
>>
If one tries to compute the days in the years, then yes, you do have to do so...it's just
>> 365+isleapyr(2019:2024)
ans =
365 366 365 365 365 366
>>
In the expression Guillaume wanted of
t1=t0+calyears(5);
the time rollover logic has to be hidden in the overloaded plus method for datetime class.
Walter Roberson
on 13 Aug 2019
>> datetime('2008-2-29') + calyears(5)
ans =
datetime
28-Feb-2013
>> datestr(datenum(2008+5,2,29))
ans =
'01-Mar-2013'
It is not immediately obvious that one is more "correct" than the other.
Walter Roberson
on 13 Aug 2019
"int() of a datenum returns a valid date"
int() is not a method available for datatype double. int() is primarily for symbolic expressions or symbolic functions. It does not make sense to me to ask about the area under a date curve, and if you were to take such a thing then the unit of the result would be in days squared, which would not be a valid date.
dpb
on 14 Aug 2019
That was an inadvertent INT() for FIX() , Walter. Seems in context of the reply would have been clear what was intended. Often fall into that as while ML has the the many intXX() versions, there's no generic as used to in Fortran...
dpb
on 14 Aug 2019
>> datetime(2008+5,2,29)
ans =
datetime
01-Mar-2013
>>
"+calyears()" is probably the more expected behavior for financial and date-keeping purposes.
>> which -all plus
built-in (C:\ML_R2017\toolbox\matlab\ops\@double\plus) % double method
built-in (C:\ML_R2017\toolbox\matlab\ops\@uint8\plus) % uint8 method
built-in (C:\ML_R2017\toolbox\matlab\ops\@uint16\plus) % uint16 method
...
built-in (C:\ML_R2017\toolbox\matlab\ops\@single\plus) % single method
built-in (C:\ML_R2017\toolbox\matlab\ops\@char\plus) % char method
built-in (C:\ML_R2017\toolbox\matlab\ops\@logical\plus) % logical method
plus is a built-in method % string method
C:\ML_R2017\toolbox\matlab\timefun\@duration\plus.m % duration method
C:\ML_R2017\toolbox\matlab\timefun\@calendarDuration\plus.m % calendarDuration method
C:\ML_R2017\toolbox\matlab\timefun\@datetime\plus.m % datetime method
...
>>
All three classes have methods specific to them.
The upshot is, one has to have an understanding of how things work to ensure one gets the result wanted for a particular purpose. Any of the above could conceivably be the desired result for a specific application.
The conversation has pointed out more specifics of the original point made...a datetime is a totally different animal than a datenum...
Answers (0)
Categories
Find more on Dates and Time in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!