I have a JSON object with data (date, kms and duration) that I have used to make an HTML table. The data is stored in order via date so its displayed how i want. See below.
Date Km's Duration Part/Service
15/10/19 16.05 01:30:09
14/10/19 16.8 01:30:42
03/10/19 13.47 02:30:36
02/10/19 15.79 01:18:54
30/09/19 17.5 01:26:56
29/09/19 13.15 01:49:38
26/09/19 12.1 01:36:37
I have another JSON object with an array of parts (4th column) and a date. I can't work out how to cycle through both to add the part row in the table in its correct row (before date of first table).
I have tried to run another for each loop within the first table for each loop to check if there is a date before the first table date, and if so insert the row and remove the element from the array so it can't duplicate. I also had to change both dates to strtotime(); otherwise the comparison of dates would only check the first number (days)
foreach($jsonData1 as $elementKey => $element) {
$durMinutes = gmdate("H:i:s", $element->elapsed_time);
$new_date_format = date('d/m/y', strtotime($element->start_date_local));
$kms = round($element->distance / 1000, 2);
foreach($jsonData2 as $eKey => $e) {
$date_ = $e->date_;
$date2_ = strtotime($date_) ;
$date2 = str_replace('20', '', $date2);
if($date2_ < $dateToCompare){
echo "<tr id='".$rowId."'>";
echo "<td></td>";
echo "<td></td>";
echo "<td></td>";
echo "<td>".$date2_."</td>";
echo "</tr>";
/
unset($jsonData2[$eKey]);
}
}
echo "<tr id='".$rowId."'>";
echo "<td>".$new_date_format."</td>";
echo "<td>".$kms."</td>";
echo "<td>".$durMinutes."</td>";
echo "<td></td>";
echo "</tr>";
$rowId++;
}
Json objest added, there was a lot of data so I shortened it. also some rangon inputs i placed in while testing
jsonData1
{"0":{"resource_state":2,"athlete":{"id":17300746,"resource_state":1},"name":"Morning Ride","distance":16046.3,"moving_time":4898,"elapsed_time":5409,"total_elevation_gain":0,"type":"Ride","workout_type":null,"id":2789696693,"external_id":"5017296437_1571097318.gpx","upload_id":2956200741,"start_date":"2019-10-14T23:58:35Z","start_date_local":"2019-10-15T09:58:35Z","timezone":"(GMT+10:00) Australia\/Brisbane","utc_offset":36000,"start_latlng":[-27.39,152.94],"end_latlng":[-27.39,152.94],"location_city":null,"location_state":null,"location_country":"Australia","start_latitude":-27.39,"start_longitude":152.94,"achievement_count":12,"kudos_count":1,"comment_count":0,"athlete_count":1,"photo_count":0,"map":{"id":"a2789696693","summary_polyline":"dddfDqgnd\\qBb#GTI|Dd#p#`#|APfAF`B[r#Ab#O^kAxBa#b#E\\H`BPx#z#rArBfCdAv#j#lA~#bDZVdAlB`A\\VTBXKt#K|Ho#lBaDvBsCnCeEnHE^Yb#qB~AaC|#wA`AMnAeBxCGt#\\lAdBvClBfB~BrAQF?zBFpES`#sB`Aq#~BCjCIV[b#}AfAcATyAx#oAxAwFq#eAfAK~Ha#vCGrAIdDJnBCpBq#`EG|ALXANo#fBO~#ExB|#rAt#h#t#VzADl#p#gBdBgAd#sBe#mBZCtBN\\r#d#xBdC|CbCnANvAFbE_#c#UqBQp#StF]vA_AdAEb#qAv#}#v#]BFa#l#Eb#_#p#HCzBiBPcADeBHWTGx#\\l#z##Jm#QWVh#\\v#rAdAh#d#E`AYZDS\\#XfAp#rAnC\\#d#oDpAw#x#}#XmD`Aq#|CQt#c#fCw#jBNrAgCW}BYg#f#KGKLMQK#MdAGB_#a#Ut#y#p#mAN#V^KbABj#Mx#s#v#_#~#XjA?ZMl#mA~Ba#VgAJmAOiBn#cAx#m#HmAQo#XG`#BvBaB`BgAt#AtDS|#UHqBiAq#uAeAg#mCBqEq#aAEgCvAgDr#uFPMMoCPm#Cw#Y]FyC_CwB}Bu#_#Yo#?eBFGpBUzAf#lAa#nBqA?_#M]]Qw##iAYq#i#w#}AO{ABoAD[|#cBO_#RB\\OxBsBP]t#_#Va#xBg#\\BLc#jB?rAa#Xf#[`#`#LDTTC#mDcAUbBa#Ze#`#wAnAa#VBXXLEEe#W[TKz#`AJXITDL\\S#_A}AeBSKOFP_#xAl#hBf#VNNZH?#Yq#sAJApBnADIK[cAcAuAg#WiAUYNQj#`Aj#QTD`#f#|Aj#RX`AZX`#|#aAx#l#NAr#mApBkAv#_AvAa#nCo#RD\\M`#s##[d#Mp#g#La#f#o#BIU?cAVr#{AlBc#f#m#Ru#]kDImC~#wOe#][q#k#uGk#eDs#PII?m#Qc#oA_AuDaEmAyDUuA#i#H]|#w#B{#mAyBgAu#ZqAFiABmCEyBIMXy#Ck#We#sAa#uAeC_#aAg#My#sBm#c#mBsB{#qAaA{BSsBzBsD#i#\\gAIiCk#oBq#cAPwDPYvBe#","resource_state":2},"trainer":false,"commute":false,"manual":false,"private":false,"visibility":"everyone","flagged":false,"gear_id":"b6289997","from_accepted_tag":false,"upload_id_str":"2956200741","average_speed":3.276,"max_speed":13.6,"device_watts":false,"has_heartrate":true,"average_heartrate":138.7,"max_heartrate":171,"heartrate_opt_out":false,"display_hide_heartrate_option":true,"elev_high":86,"elev_low":86,"pr_count":1,"total_photo_count":0,"has_kudoed":false},"1":{"resource_state":2,"athlete":{"id":17300746,"resource_state":1},"name":"Morning Ride","distance":16804.8,"moving_time":5069,"elapsed_time":5442,"total_elevation_gain":0,"type":"Ride","workout_type":null,"id":2787313119,"external_id":"5017296437_1571012018.gpx","upload_id":2953665443,"start_date":"2019-10-14T00:17:15Z","start_date_local":"2019-10-14T10:17:15Z","timezone":"(GMT+10:00) Australia\/Brisbane","utc_offset":36000,"start_latlng":[-27.39,152.95],"end_latlng":[-27.39,152.94],"location_city":null,"location_state":null,"location_country":"Australia","start_latitude":-27.39,"start_longitude":152.95,"achievement_count":7,"kudos_count":1,"comment_count":0,"athlete_count":1,"photo_count":0,"map":{"id":"a2787313119","summary_polyline":"nncfDymod\\{#KwBkBoAe#aGMmAiAsB`#{A?e#sA{A{AsGoDwA[MTKE_BqBmF{DoAqBy#[]w#My#mAcBRyL_#cDmAmEa#y#m#UKs#QsOKOEJAj#YYFcAIqBFc#c#Xa#`ANz#Ov#[j#JpA_ASYaAW#Bx#WBu#qAq#Ec#{B}#qBOm#sAOWwAa#c#_Bg#}#w#oAwBk#e#Qu#cAeAi#\\e#r#Q`Ac#MJzBZTAJg#CZn#Qp#jApCtHhDhAjDvBlErAnAXj#tB`A|#nA`Al#bFZxBtEv#nGAtBQPG`DoANSTKh#i#j#qA`#K?^WIIqBWqARkFsB`#Co#m#NAG_#o#_#Yc#wAa#eA}AQeB\\eCSGo#uAO`Au#tAP^LpAxAzDb#\\b#fAd#A^vAz#RgAXDHd#HH\\`El#hDEzDVT?d#a#zB_A~#fAl#tA|#v#lBjC#|AgAvDUtB_#JcA]SF~AdBHlAo#\\Su#w#`B#n#]CM{#i#x#q#VcALyBr#FbCg#aAw#a#uAf#g#z#hACXP#b#c#C?`#_#`#C^}A~#cA~AVlAZx#hAdBpCxFz#nApAt#Ax#aDnBYbA^?p#s#n#A|#q#`Du#lA`#dA]vANfAS|#`#IvAfARh#f#Ol#wA|A#\\LQh#VFIW_#JAh#XRG?S]SD]XTn#Fd#f#Al#dAt#l#|B_#v#i#RsGj#GVFj#Xc#b#v#xALTUzB_#l#m#R}#RMz#BM{#sAmBsGaM[U}#UgLn#oDp#_#NO\\Kc#^kBEy#gAuBi#g#cAgC{#wAkAC?NEJkAh#SGYb#Uc#uBeAoBKN\\a#P{#e#]cAHQRVVBC_#wD{B{##[qAqBcBH]EmA\\qAG]w#u#HEdA\\h#p#NSKc#HGf#f#NQQq#i#_#FMt#Ep#f#|BgC|#L`#ZbAfB|AzEfAn#z#RlClERCdAaBdAi#f#aAFe#d#GC_#[OiAFj#iAj#]f#Fz#r#Pt#Jy#Mq#JWfBu#lAO^]NDl#aAFj#j#NEk#|#iBX~#`AUAc#f#eAn#_I~#c#xAj#n#G~AfBxBZxBz#vDfCnAxBXTpDm#ZVRf#f#LbHX~B~Ah#t#h#A","resource_state":2},"trainer":false,"commute":false,"manual":false,"private":false,"visibility":"everyone","flagged":false,"gear_id":"b6289997","from_accepted_tag":false,"upload_id_str":"2953665443","average_speed":3.315,"max_speed":11.8,"device_watts":false,"has_heartrate":true,"average_heartrate":140.5,"max_heartrate":167,"heartrate_opt_out":false,"display_hide_heartrate_option":true,"elev_high":79,"elev_low":79,"pr_count":3,"total_photo_count":0,"has_kudoed":false},"2":{"resource_state":2,"athlete":{"id":17300746,"resource_state":1},"name":"Evening Ride","distance":13474.6,"moving_time":4104,"elapsed_time":9036,"total_elevation_gain":0,"type":"Ride","workout_type":null,"id":2761382734,"external_id":"5017296437_1570090432.gpx","upload_id":2926459145,"start_date":"2019-10-03T08:16:33Z","start_date_local":"2019-10-03T18:16:33Z","timezone":"(GMT+10:00) Australia\/Brisbane","utc_offset":36000,"start_latlng":[-27.34,152.98],"end_latlng":[-27.36,152.97],"location_city":null,"location_state":null,"location_country":"Australia","start_latitude":-27.34,"start_longitude":152.98,"achievement_count":5,"kudos_count":4,"comment_count":0,"athlete_count":3,"photo_count":0,"map":{"id":"a2761382734","summary_polyline":"zkzeD{xud\\Kb#GHOFoD\\aANk#GQII?c#cAGKOEYBe#PsCf#y#OKBKFIJCLCp#SdAA`#EHK#cF_#oRmBoPyAs#Bu#M_VcCwJw#ILIn#M|B]zD]zFW`Dc#Le#?gRiBSQEK?MJc#GGIARIDICINHKEIDBFI#GHDKCGHCKCGBHGFPGF#JGHHE?]BIH?#JGBFCK#?JP#GCEI#MGDEKAHINFGGEDGE[PDCH#HFIL#BHEFQBWCk#L^HPI\\AG#DDG?QFBIMAHBNOGDBJRNSKDUAKAJGECHPNH?DJt#d#VOQMq#MEMIEQ?EFFEBHIACIIEO#DFH#FI#JDGF?AMDGI?LXYWMFPCJ#DFm#MEJR#PJGBJOBFAJl#DOIISGAFGCKN{#j#sIt#BxFp#tJ|#RSFOFc#H{Ad#c#DU?K?JM\\Cn#ETBK?K#JEHCI#KDG?JDGCHFIGF#HJKPFI?CIIBIPBHHGBGAMGHGTBHAM?YEn#EDHUDe#?HGTFMBUGFALDKEHBH#IFGOR#s#HUNcAVMV#jCXDDAL]GNL?NMlBAFQGCIFa#FiAK?GJKbBJjALFPSLuBKo##NAP]fCNNJU#g#I?GHGZBLFDHIDa#CMI?EHCXHLHOFaAYTBZAXBHLED[BqA?II?EH#LCXCRIVFPJ?FO?[#WYNCLCVFLHDFCDSGQD]AQGEKf#FKFe#AMG#EHI|#JEBKH_AG[MYHLLBAKFEBNEb#KZERA^GNKE#i#Ho#A[ICAJGz##f#FV?LBNJHPSDQNiC?KESFHGn#GEAIBJGRQzAEILEBq#Da#NYBQBHCm#DIvARhADzCTlFn#dIv#PBFLF#JCrB?jFl#pKbA~NfApFh#DIDe#Jm#B_#?YBQVWPAt#H^ClBa#~#UL?JFZt#LNRJ`#?h#GtA_#jIeBbA`#zCbBLHN`#E`#Ur#S^iAfBoB|E~#fAj#dBj#pA\\Nn#Mb#?RHRRFRHv#XlAFv#JDf#IZO`#[bBMVRTd#D^DjADXTPpAb#nAh#HJHL?PyAtCOZ#r#L|#DJ\\Ph#J|##hAMf#OL[JMd#}#hByAZG\\[JEjA?HEDMBc#BGJGV_#HCn#o#TC~#DtAZPNr#Rr#G`AYrAGfA?X?fAv#RAFGLo#JuAF_BD]GAZcCXoFs#A_BOgC[CSHi#F_AJk#JA\\Bn#RvX~BlHt#rAHPBxA\\hHv#nDh#Z\\nAdAxDrEjIjJXb#QKCK","resource_state":2},"trainer":false,"commute":false,"manual":false,"private":false,"visibility":"everyone","flagged":false,"gear_id":"b6289997","from_accepted_tag":false,"upload_id_str":"2926459145","average_speed":3.283,"max_speed":22.9,"device_watts":false,"has_heartrate":true,"average_heartrate":112.7,"max_heartrate":159,"heartrate_opt_out":false,"display_hide_heartrate_option":true,"elev_high":97,"elev_low":97,"pr_count":3,"total_photo_count":0,"has_kudoed":false},"3":{"resource_state":2,"athlete":{"id":17300746,"resource_state":1},"name":"Morning Ride","distance":15789.8,"moving_time":4281,"elapsed_time":4734,"total_elevation_gain":0,"type":"Ride","workout_type":null,"id":2756177555,"external_id":"5017296437_1569974724.gpx","upload_id":2921078316,"start_date":"2019-10-02T00:06:32Z","start_date_local":"2019-10-02T10:06:32Z","timezone":"(GMT+10:00) Australia\/Brisbane","utc_offset":36000,"start_latlng":[-27.39,152.94],"end_latlng":[-27.39,152.94],"location_city":null,"location_state":null,"location_country":"Australia","start_latitude":-27.39,"start_longitude":152.94,"achievement_count":14,"kudos_count":3,"comment_count":0,"athlete_count":1,"photo_count":0,"map":{"id":"a2756177555","summary_polyline":"~qcfDorod\\SLMr#c#v#c#ZmAUmBoB]M_AQiBBiCOE]H_FGUC_B\\iB?q#GvAa#jBOvCgAlAIZa#R}#DiAa#_BmBs#oAcDkBNQL?f#Xx#RfDrDvA~#RGD_Ah#Wl#IBKm#WeBOy#iAO{#_#Hg#Qe#]QW_#uAyA}#cAyAeByAuAY{#]o#cAa#CWMk#yA[Yw#uASkCLy#GoAF]j#mA#u#Vu#PUPHx#Sh#CXUdAa#tCxA|#|#l#Tj#_#NUXQR]ZQpADlA]NJDqAJOBl#FA?c#HFFVJHDEHs#?{#ZgAKOuAGqAn#_Ft#yDgBEIBYKQ{#PQw#aAaC][i#wA#SJMb#ITTHI?OSQs#MQiAWq#yBsCc#KOJWjAA\\GDc#{#Cs#Dk#lAeCLk#OY}#CQg#IaAoAeAM[Ky#EgBRwBZMnDkC`#{AZeEbAq#f#Jr#h#hAhB~#LfBUfANrA\\HL`F~BZj#LbA\\Rf#DbBjBzBzCAh#Gh#u#nCL`GIpAGb#IL_AB}#i#y#w#kBUYa#Iu#S#i#_#u#MQ#a#PM_#qAg#g#mAsAa#eA{#{A{#qACGg#Yo#m#UKS#Ul#GOSy#I[RWh#MAI[JaAV[VGUG[N_#`#K#MkDNSdBCcC#_BjASp#QdB?xAJ|AEt#Sh#c#VaAAq#JeAi#Si#Kh#N|AIrAiAnCLp#ARc#~#CNBp#JXUC]UO_#E[KESNHb#CVMAu#mAQM_##OG{#aDIo#]_#Mi#mAQKKI{#_#g#}Ag#sAiA_AiBi#c#Y_Aa#W]k#]V_#l#S^C^WDQMDr#AbA`#Z?Ha#GGDZr#Ur#pArCtHjD`AtCzB`FnAbAd#v#vB~#r#jARRt#`#ZDxDLtBzD`AtEL`AWRSbH]Vk#AKFKLKp#g#l#_B`#EIZKuBc#yANiFwBRD?K]_#REBKIW]Qm#s#sA_#iAwASiB\\_CYO[mAGGKBQdAk#dATh#JjAV\\Pt#v#jB^Xf#bAb#CJLFRC`#LXx#L?JQHu#Nn#NL^rDd#`ADzAIrEXhAQnAg#Hi#BIJ?v#z#XdA`#r#x#f#jAhB|#z#tDdC\\l#lAdAdBRxA\\zDzB`At#Jl#^x#RR`BGvAc#f#x#d#RxBBfDT`C|Al#x#l#D","resource_state":2},"trainer":false,"commute":false,"manual":false,"private":false,"visibility":"everyone","flagged":false,"gear_id":"b6289997","from_accepted_tag":false,"upload_id_str":"2921078316","average_speed":3.688,"max_speed":11.3,"device_watts":false,"has_heartrate":true,"average_heartrate":135.4,"max_heartrate":170,"heartrate_opt_out":false,"display_hide_heartrate_option":true,"elev_high":103,"elev_low":103,"pr_count":4,"total_photo_count":0,"has_kudoed":false}}
jsonData2 (rows to add to the original table during construction)
[
{
"component":"fork",
"date_":"21\/10\/2019",
"servicetype":"gfhfh",
"notes":"fhgfghfgh"
},
{
"component":"fork",
"date_":"02\/10\/2019",
"servicetype":"gfhfh",
"notes":"fhgfghfgh"
},
{
"component":"fork",
"date_":"03\/06\/2019",
"servicetype":"gfhfh",
"notes":"fhgfghfgh"
},
{
"component":"fork",
"date_":"18\/02\/2019",
"servicetype":"gfhfh",
"notes":"fhgfghfgh"
},
{
"component":"fork",
"brand":"ppiopoip",
"date_":"16\/10\/2019"
},
{
"component":"fork",
"brand":"ppiopoip",
"date_":"16\/10\/2019"
}
]
I'm hoping there is an easier optin to do this as I think my attempt is way off?
**
I have found an error and updated the code to reflect, the second and first date formats were incorrect. I have changed $date2 to the correct format by replacing 20 from 2019 to 19.
It works beter but only compares the first numbers "dd" and doesn't take the month and year into consideration.
I have found a solution but would be happy to hear any other options.
I have used substr() to break down the dates and compare the year first, month and then days. I will just post the if statements below that I used, posted in place of the original if statement. The rest of the code is identical.
if(substr($date2,6,2) >= substr($date1,6,2)){
if(substr($date2,3,2) >= substr($date1,3,2)){
if(substr($date2,0,2) >= substr($date1,0,2)){
You have a function that always inputs an interval (natural numbers in this case), this function returns a result, but is quite expensive on the processor, simulated by sleep in this example:
function calculate($start, $end) {
$result = 0;
for($x=$start;$x<=$end;$x++) {
$result++;
usleep(250000);
}
return $result;
}
In order to be more efficient there is an array of old results, that contains the interval used an the result of the function for that interval:
$oldResults = [
['s'=>1, 'e'=>2, 'r' => 1],
['s'=>2, 'e'=>6, 'r' => 4],
['s'=>4, 'e'=>7, 'r' => 3]
];
If I call calculate(1,10) the function should be able to calculate new intervals based on old results and accumulate them, In this particular case it should take the old result from 1 to 2 add that to the old result from 2 to 6 and do a new calculate(6,10) and add that too. Take in consideration that the function ignores the old saved interval from 4 to 7 since it was more convenient to use 2-6.
This is a visual representation of the problem:
Of course in this example, calculate() is quite simple and you can just find particular ways to solve this problem around it, but in the real code calculate() is complex and the only thing I know is that calculate(n0,n3)==calculate(n0,n1)+calculate(n1,n2)+calculate(n2,n3).
I cannot find a way to solve the reuse of the old data without using a bunch of IF and foreach, I'm sure there is a more elegant approach to solve this.
You can play with the code here.
Note: I'm using PHP but I can read JS, Pyton, C and similar languages.
if you are certain that calculate(n0,n3)==calculate(n0,n1)+calculate(n1,n2)+calculate(n2,n3), then it seems to me that one approach might simply be to establish a database cache.
you can pre-calculate each discrete interval, and store its result in a record.
$start = 0;
$end = 1000;
for($i=1;$i<=$end;$i++) {
$result = calculate($start, $i);
$sql = "INSERT INTO calculated_cache (start, end, result) VALUES ($start,$i,$result)";
// execute statement via whatever dbms api
$start++;
}
now whenever new requests come in, a database lookup should be significantly faster. note you may need to tinker with my boundary cases in this rough example.
function fetch_calculated_cache($start, $end) {
$sql = "
SELECT SUM(result)
FROM calculated_cache
WHERE (start BETWEEN $start AND $end)
AND (end BETWEEN $start AND $end)
";
$result = // whatever dbms api you chose
return $result;
}
there are a couple obvious considerations such as:
cache invalidation. how often will the results of your calculate function change? you'll need to repopulate the database then.
how many intervals do you want to store? in my example, I arbitrarily picked 1000
will you ever need to retrieve non-sequential interval results? you'll need to apply the above procedure in chunks.
i wrote this:
function findFittingFromCache($from, $to, $cache){
//length for measuring usefulnes of chunk from cache (now 0.1 means 10% percent of total length)
$totalLength = abs($to - $from);
$candidates = array_filter($cache, function($val) use ($from, $to, $totalLength){
$chunkLength = abs($val['e'] - $val['s']);
if($from <= $val['s'] && $to >= $val['e'] && ($chunkLength/$totalLength > 0.1)){
return true;
}
return false;
});
//sorting to have non-decremental values of $x['s']
usort($candidates, function($a, $b){ return $a['s'] - $b['s']; });
$flowCheck = $from;
$needToCompute = array();
foreach($candidates as $key => $val){
if($val['s'] < $flowCheck){
//already using something with this interval
unset($candidates[$key]);
} else {
if($val['s'] > $flowCheck){
//save what will be needed to compute
$needToCompute[] = array('s'=>$flowCheck, 'e'=>$val['s']);
}
//increase starting position for next loop
$flowCheck = $val['e'];
}
}
//rest needs to be computed as well
if($flowCheck < $to){
$needToCompute[] = array('s'=>$flowCheck, 'e'=>$to);
}
return array("computed"=>$candidates, "missing"=>$needToCompute);
}
It is function which returns you two arrays, one "computed" holds found already computed pieces, second "missing" holds gaps between them which must be computed yet.
inside function there is 0.1 threshold, which disqualifies chunks shorter than 10% of total searched length, you can rewrite function to send threshold as parameter, or ommit it completely.
i presume results will be stored and after computing added into cache ($oldResults), which might be of any form (for example database as Jeff Puckett suggested). Do not forget to add all computed chunks and whole seeked length into cache.
I am sorry but i can't find a way without cycles and ifs
Working demo:
link
I need to get the video duration using Youtube API V3. My application was working fine with API V3 but now it doesn't work.
I found a working example and it works:
$dur = file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=[VIDOID]&key=[API KEY]");
$duration =json_decode($dur, true);
foreach ($duration['items'] as $vidTime) {
$vTime= $vidTime['contentDetails']['duration'];
}
Credits: Youtube API v3 , how to get video durations?
This will return the time format something like this.
PT24M30S
How can I convent this to a readable time. Like 24:30?
I can't believe it, anyone have used DateInterval, why? It's just like this:
$duration = new DateInterval('PT24M30S');
print $duration->format('%H:%i:%s'); // outputs: 00:24:30
Helpful links:
The DateInterval class
DateInterval::format
One possible way is to use the function str_replace();
$stamp = "PT24M30S";
$formated_stamp = str_replace(array("PT","M","S"), array("",":",""),$stamp);
echo $formated_stamp; //should give "24:30"
Bonus content - leading zeros
In order to add leading zeros one must first split the string up with explode(), then format the numbers idividually with sprintf(); and finally add it all together again.
$exploded_string = explode(":",$formated_stamp);
$new_formated_stamp = sprintf("%02d", $exploded_string[0]).":".sprintf("%02d", $exploded_string[1]);
$time_format = "PT24M30S ";
preg_match_all('/(\d+)/',$time_format,$parts);
$hours = floor($parts[0][0]/60);
$minutes = $parts[0][0]%60;
$seconds = $parts[0][1];
echo $hours . ": ". $minutes .":". $seconds;
video resource contains a duration field which is a string of the following format. It will be up to you the developer to reformat it as necessary for your application and needs.
contentDetails.duration
The length of the video. The tag value is an ISO 8601 duration. For
example, for a video that is at least one minute long and less than
one hour long, the duration is in the format PT#M#S, in which the
letters PT indicate that the value specifies a period of time, and the
letters M and S refer to length in minutes and seconds, respectively.
The # characters preceding the M and S letters are both integers that
specify the number of minutes (or seconds) of the video. For example,
a value of PT15M33S indicates that the video is 15 minutes and 33
seconds long.
If the video is at least one hour long, the duration is in the format
PT#H#M#S, in which the # preceding the letter H specifies the length
of the video in hours and all of the other details are the same as
described above. If the video is at least one day long, the letters P
and T are separated, and the value's format is P#DT#H#M#S. Please
refer to the ISO 8601 specification for complete details.
As to how to do it I would have to say remove the PT and the S and replace the M with a :. It will probably require some testing on your part depending on what happens when a value is null. I would do some research into ISO-8061
I use the following function to convert the YouTube duration. Simply replace $yt with the format YouTube provided you and it'll print it out nice and readable.
function ConvertYoutubeVideoDuration($yt){
$yt=str_replace(['P','T'],'',$yt);
foreach(['D','H','M','S'] as $a){
$pos=strpos($yt,$a);
if($pos!==false) ${$a}=substr($yt,0,$pos); else { ${$a}=0; continue; }
$yt=substr($yt,$pos+1);
}
if($D>0){
$M=str_pad($M,2,'0',STR_PAD_LEFT);
$S=str_pad($S,2,'0',STR_PAD_LEFT);
return ($H+(24*$D)).":$M:$S"; // add days to hours
} elseif($H>0){
$M=str_pad($M,2,'0',STR_PAD_LEFT);
$S=str_pad($S,2,'0',STR_PAD_LEFT);
return "$H:$M:$S";
} else {
$S=str_pad($S,2,'0',STR_PAD_LEFT);
return "$M:$S";
}
}
Solution PHP
function covtime($youtube_time){
preg_match_all('/(\d+)/',$youtube_time,$parts);
$hours = $parts[0][0];
$minutes = $parts[0][1];
$seconds = $parts[0][2];
if($seconds != 0)
return $hours.':'.$minutes.':'.$seconds;
else
return $hours.':'.$minutes;
}