Datetime with variable format

205 ビュー (過去 30 日間)
Winston Black
Winston Black 2016 年 2 月 11 日
編集済み: dpb 2017 年 9 月 26 日
I have an output file that has timestamps in the form of 'yyyy-MM-dd HH:mm:ss.S' or 'yyyy-MM-dd HH:mm:ss'. I would like a clean way to convert them from date strings into an array of date time format.
Example code:
a={'2016-02-09 10:28:00';'2016-02-09 10:28:01.5'}
out=datetime(a,'InputFormat','yyyy-MM-dd HH:mm:ss.S','InputFormat','yyyy-MM-dd HH:mm:ss','Format','yyyy-MM-dd HH:mm:ss.S');
Actual output:
out =
2016-02-09 10:28:00.0
NaT
Desired output:
out =
2016-02-09 10:28:00.0
2016-02-09 10:28:00.5

採用された回答

Brendan Hamm
Brendan Hamm 2016 年 2 月 11 日
編集済み: Brendan Hamm 2016 年 2 月 11 日
Unfortunatelly you cannot specify multiple InputFormats simultaneously. Common to Name-Value pairs is that the last instance of a name value pair is used; in your example this is: 'yyyy-MM-dd HH:mm:ss'. One thing you can do to work around this issue is to convert the cell string to a vector of MATALB Serial Date Numbers and then to a datetime:
d = datenum(a);
d = datetime(d,'Format','yyyy-MM-dd HH:mm:ss.S','convertFrom','datenum');
I would caution you here as if you attempt to change the format in the line d = datenum(a) you will error due to a non-conforming entry.
  12 件のコメント
Peter Perkins
Peter Perkins 2017 年 9 月 26 日
Running R2017b, which was released like yesterday ...
>> version
ans =
'9.3.0.713579 (R2017b)'
>> a = {'2016-02-09 10:28:00.5';'2016-02-09 10:28:01'}
a =
2×1 cell array
{'2016-02-09 10:28:00.5'}
{'2016-02-09 10:28:01' }
>> fmt = {'yyyy-MM-dd HH:mm:ss.S';'yyyy-MM-dd HH:mm:ss'}
fmt =
2×1 cell array
{'yyyy-MM-dd HH:mm:ss.S'}
{'yyyy-MM-dd HH:mm:ss' }
>> cellfun(@(t,f) datetime(t,'format',f),a,fmt)
ans =
2×1 datetime array
2016-02-09 10:28:00.5
2016-02-09 10:28:01.0
Just to be clear, this does not allow you to provide multiple formats to the datetime constructor, but it does allow dpb's solution using cellfun to work.
dpb
dpb 2017 年 9 月 26 日
編集済み: dpb 2017 年 9 月 26 日
Nice enhancement...I've noted in the past that datetime class is clearly "a work in progress" and while basic functionality and interaction is pretty good start there were/are still missing pieces. This just took care of one; not sure I'd actually run across it before, but it's a continuing step to fully integrate the facility.
Kudos! :)
PS: I note you carefully arranged to put the format with the .S format string first so the output format included it and didn't have to reset the display format... :)

サインインしてコメントする。

その他の回答 (3 件)

dpb
dpb 2016 年 2 月 11 日
編集済み: dpb 2016 年 2 月 11 日
I'm frankly surprised the above doesn't give a syntax error on the duplicated named input, but guess it likely just takes the first occurrence and doesn't count the number...will have to do some testing on that behavior; never thought of even trying it before.
Anyway, the doc says " All strings in DateStrings must have the same format." so you have only one shot at getting it right! :)
If you can't fixup the input format to become consistent, you'll have to fixup the data before converting--
>> a={'2016-02-09 10:28:00';'2016-02-09 10:28:01.5'};
>> ix=cellfun(@isempty,strfind(a,'.')) % find the locations missing the fractional seconds
ix =
1
0
>> a(ix)={[char(a(ix)) '.0']} % add the superfluous '.0' to make format match
a =
'2016-02-09 10:28:00.0'
'2016-02-09 10:28:01.5'
>>
Now you can convert with the fractional second format.
I thought you might get lucky if you skipped defining an input format string entirely but the requirement for all to be the same means that will also fail, undoubtedly.

Peter Perkins
Peter Perkins 2016 年 2 月 18 日
Winston, I recommend that you NOT mix datenum and datetime. If you're in R2014b or later, don't use datenums. Among other things, because they count in units of days, using datenums runs the risk of round-off problems for sub-second timestamps.
You're right, datetime requires a single format. But it's pretty easy to get what you want.Convert using the first format. You'll get a vector of datetimes, with NaTs where the format was different. Then use isnat to convert those strings with the other format and assign into the appropriate elements.
Hope this helps.

Winston Black
Winston Black 2016 年 2 月 12 日
Thanks for these solutions! I think they are both nice though Brendan's is a bit cleaner.
Another alternative solution (which I think is less attractive) would be to run datetime twice - once with each format - then combine the results into one variable.

カテゴリ

Help Center および File ExchangeData Type Conversion についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by