How to use datetime with leap second strings?
60 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
James Tursa
el 16 de Nov. de 2024 a las 4:23
Respondida: Shivam Gothi
el 17 de Nov. de 2024 a las 8:58
Suppose we have the following date time string:
ds1 = "30-Jun-1972 23:59:59.5";
You can convert that to a datetime easily:
datetime(ds1)
But now suppose you have a string that is in the middle of a leap second:
ds2 = "30-Jun-1972 23:59:60.5";
MATLAB won't convert this:
try
datetime(ds2)
catch
disp('Error')
end
So apparently the seconds value >= 60 is causing this. But what if I tell it to use leap seconds? Still doesn't work:
try
datetime(ds2,'TimeZone','UTCLeapSeconds')
catch
disp('Error')
end
This is disappointing, and quite frankly inconsistent with other ways of creating a datetime within a leap second. E.g., this works fine:
datetime(1972,6,30,23,59,60.5,'TimeZone','UTCLeapSeconds')
So, is there a way to coax datetime( ) into reading a date time string in the middle of a leap second? And at the same time retain full precision of the string? I would like to avoid manually parsing this myself if possible, but currently see no other way. E.g., the precision loss issue with string input illustrated:
format longg
ds3 = "01-Jan-2024";
dt3 = "23:59:01.2345678912345";
d3 = datetime(ds3+" "+dt3)
d3.Second
d3.Second == 1.2345678912345 % LOSES PRECISION!
d4 = datetime(ds3) + duration(dt3)
d4.Second
d4.Second == 1.2345678912345 % LOSES PRECISION!
You can see the loss of precision datetime has when reading strings in general. The duration class has a similar issue. So even if datetime could handle seconds >= 60, there would be a precision loss issue. I would like to avoid that.
At the moment, the only solution I see is to manually parse out the seconds and then piece things together. E.g.,
dt3a = "23:59:00";
dt3b = "00:00:01.2345678912345";
d5 = datetime(ds3) + duration(dt3a) + duration(dt3b)
d5.Second
d5.Second == 1.2345678912345
Even this approach has problems with duration in the middle of a leap second because it can't handle string seconds >=60 for some reason:
seconds(60.5) % this is OK
duration("00:00:60.5") % but not this!
So to handle the leap second issue I would be forced to read the seconds manually instead of using duration. (Why???)
I am hoping for a simpler way.
0 comentarios
Respuestas (1)
Shivam Gothi
el 17 de Nov. de 2024 a las 8:58
As per my understanding, you are trying to save leap-seconds in "datetime" object, in such a way that it does not looses precision. You want to pass the date-time string as an input argument to the "datetime" function.
I also faced similiar issue, but tried to resolve it by using the following work-around.
The documentation of "datetime" function (https://www.mathworks.com/help/matlab/ref/datetime.html#d126e365305) say that:
While passing character string as an input argument to the "datetime" function, we can specify the precision upto 9 decimal places by specifing an additional input argument "infmt", as demonstrated below:
DT_string= "2024-01-01T23:59:01.2345678912345Z"; %Same date and time as used in the above question
t = datetime(DT_string,'InputFormat','uuuu-MM-dd''T''HH:mm:ss.SSSSSSSSS''Z')
format longg;
t.Second
This says that the maximum precision available is "9". Therefore, "1.2345678912345" is getting truncated to "1.234567891" in your case. Even if we do not explicitely specify the "inputFormat", it will automatically truncate to the maximum 9 digits after decimal.
Therefore, if you want to retain the precision, the below given command works perfectly.
t=datetime(1972,1,1,23,59,01.2345678912345,'TimeZone','UTCLeapSeconds') % same date and time entered manually
t.Second %This is not truncated
In this case, instead of passing the date-time string, you have to manually enter the the values of year, months, days and time. This is not favourable as mentioned by you.
I am suggesting one of the possible work-around which I implemented in order to pass date-time string and store it in a "datetime" object which supports leap seconds as well as retains precision.
I have made a user defined function "DateTime" which takes the date-time string and returns a "datetime" object. It is demonstrated below:
format longg
ds3 = "01-Jan-2024";
dt3 = "23:59:01.2345678912345";
stringg=(ds3+" "+dt3);
t=DateTime(stringg)
t.Second %this does not losses precision
function out=DateTime(DT_string)
arguments
DT_string string
end
C = textscan(DT_string,'%s %s'); %gives (1 x 2) cell array consisting of date and time
date_string=string(C{1});
time_string=string(C{2});
Date=textscan(date_string,'%f %s %f','delimiter','-'); %save the day, month, year in cell array
Time=textscan(time_string,'%f %f %f','delimiter',':'); %Save hour, minutes and seconds in celll array
DT_object=datetime(date_string);
DT_object.Hour = Time{1}; %extract the hour, minutes and seconds and save them in variable
DT_object.Minute = Time{2};
DT_object.Second = Time{3};
DT_object.TimeZone='UTCLeapSeconds';
out=DT_object;
end
I hope you find this information useful !!
0 comentarios
Ver también
Categorías
Más información sobre Data Type Conversion en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!