Convert a string to seconds with PHP - php

I have string '6m15s' in PHP that I would like to convert in to time or ideally seconds. I am using the strtotime() function like:
$time = date('H:i:s', strtotime('6m15s'));
echo $time;
But all I get '01:00:00'. Is this possible to convert my string and if so what would be the best way to do so?

You could use substr():
$string = '6m15s';
$minute = substr($string, 0, 1);
$second = substr($string, 2, 2);
echo date('H:i:s', strtotime("00:$minute:$second"));
// outputs 00:06:15

If you're trying to get the total number of seconds then something like:
preg_match('/((?<h>[\d]+)h)?((?<m>[\d]+)m)?((?<s>[\d]+)s?)/', $var, $m);
echo ($m['h']* 60 + $m['m']) * 60 + $m['s']; // 375
This looks for hours as well, as in 1h6m15s.

If you are working with the fix patterns then you can construct a method like:
function stringToSecondByPattern($subject, $pattern = '/(\d+)m(\d+)s/') {
$matches = [];
preg_match($pattern, $subject, $matches);
list($original, $minuets, $seconds) = $matches;
$secondsSum = $seconds + ($minuets * 60);
return $secondsSum;
}
print stringToSecondByPattern('6m15s');

Related

How to split a string in desired format in php

I've a string like below
$num = "20142311.235504";
I want to split the string in below format
$date['year'] = 2014;
$date['Month'] = 23;
$date['day'] = 11;
$date['hour'] = 23;
$date['min'] = 55;
$date['sec'] = 04;
or even in date form like below
2014/23/11 23:55:04
I tried using preg_split('/(d{4})/',$num,$matches); and str_split but am not getting the desired output. Your help is highly appreciated.
If the string is a date, you can do this :
$num = "20142311.235504";
// You create a date with your string according to your current format
$date = date_create_from_format("Ydm.His", $num);
// Now you can play with it
$formattedDate = $date->format("Y/d/m H:i:s"); // `string(19) "2014/23/11 23:55:04"`
$dateTest['year'] = $date->format("Y"); // 2014
$dateTest['Month'] = $date->format("m"); // 11
$dateTest['day'] = $date->format("d"); // 23
$dateTest['hour'] = $date->format("H"); // 23
$dateTest['min'] = $date->format("i"); // 55
$dateTest['sec'] = $date->format("s"); // 04
Demo here : http://sandbox.onlinephpfunctions.com/
With the help of regex you can do this. In pattern create capture group for garbing year, months, days, hours, minutes and seconds. Simple example:
$str = "20142311.235504";
preg_match('~^(?<year>\d{4})(?<day>\d{2})(?<month>\d{2}).(?<hour>\d{2})(?<minute>\d{2})(?<second>\d{2})$~', $str, $match);
echo '<pre>', print_r($match);
But I prepare you to use date_create_from_format() which is more easier and faster than regex. First, convert a known date format separated by -, explode that format to convert an array and finally assign the array to a set of key [by array_combine()]. Example:
$str = "20142311.235504";
$match = array_combine(['year', 'month', 'day', 'hour', 'minute', 'second'], explode('-', (date_create_from_format("Ydm.His", $str))->format('Y-m-d-H-i-s')));
echo '<pre>', print_r($match);

most efficient means of parsing a simple clearly defined string?

I'm only asking because this is looping millions of times.
string is simply like this:
01-20
Its always like that... 2 digits (leading zero) followed by hyphen and another 2 digits (leading zero). I simply need to assign the first (as integer) to one variable and the second (as integer) to another variable.
str_split? substr? explode? regex?
Given a variable $txt, this has the best performance:
$a = (int)$txt;
$b = (int)substr($txt, -2);
You could measure the performance of different alternatives with a script like this:
<?php
$txt = "01-02";
$test_count = 4000000;
// SUBSTR -2
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
$a = (int)$txt; // numeric conversion ignores second part of string.
$b = (int)substr($txt, -2);
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "substr(s,-2): {$a} {$b}, process time: {$duration}ms <br />";
// SUBSTR 3, 2
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
$a = (int)$txt; // numeric conversion ignores second part of string.
$b = (int)substr($txt, 3, 2);
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "substr(s,3,2): {$a} {$b}, process time: {$duration}ms <br />";
// STR_SPLIT
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
$arr = str_split($txt, 3);
$a = (int)$arr[0]; // the ending hyphen does not break the numeric conversion
$b = (int)$arr[1];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "str_split(s,3): {$a} {$b}, process time: {$duration}ms <br />";
// EXPLODE
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
$arr = explode('-', $txt);
$a = (int)$arr[0];
$b = (int)$arr[1];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "explode('-',s): {$a} {$b}, process time: {$duration}ms <br />";
// PREG_MATCH
$time_start = microtime(true);
for ($x = 0; $x <= $test_count; $x++) {
preg_match('/(..).(..)/', $txt, $arr);
$a = (int)$arr[1];
$b = (int)$arr[2];
}
$duration = round((microtime(true) - $time_start) * 1000);
echo "preg_match('/(..).(..)/',s): {$a} {$b}, process time: {$duration}ms <br />";
?>
When I ran this on PhpFiddle Lite I got results like this:
substr(s,-2): 1 2, process time: 851ms
substr(s,3,2): 1 2, process time: 971ms
str_split(s,3): 1 2, process time: 1568ms
explode('-',s): 1 2, process time: 1670ms
preg_match('/(..).(..)/',s): 1 2, process time: 3328ms
The performance of substr with either (s, -2) or (s, 3, 2) as arguments perform almost equally well, provided you use only one call. Sometimes the second version came out as the winner. str_split and explode perform rather close, but not as well, and preg_match is the clear looser. The results depend on the server load, so you should try this on your own set-up. But it is certain that regular expressions have a heavy payload. Avoid them when you can do the job with the other string functions.
I edited my answer when I realised that you can cast the original string immediately to int, which will ignore the part it cannot parse. This practically means you can get the first part as a number without calling any of the string functions. This was decisive to make substr the absolute winner!
Try to convert the string to an array then use each array index to different variable your want
<?php
$str = '01-20'
$number = explode('-',$str);
$variable_1 = (int)$number[0];
$variable_2 = (int)$number[1];
?>

PHP - For Loop Keep Significant Digits [duplicate]

This question already has answers here:
Zero-pad digits in string
(5 answers)
Closed 2 years ago.
I have a variable which contains the value 1234567.
I would like it to contain exactly 8 digits, i.e. 01234567.
Is there a PHP function for that?
Use sprintf :
sprintf('%08d', 1234567);
Alternatively you can also use str_pad:
str_pad($value, 8, '0', STR_PAD_LEFT);
Given that the value is in $value:
To echo it:
printf("%08d", $value);
To get it:
$formatted_value = sprintf("%08d", $value);
That should do the trick
When I need 01 instead of 1, the following worked for me:
$number = 1;
$number = str_pad($number, 2, '0', STR_PAD_LEFT);
echo str_pad("1234567", 8, '0', STR_PAD_LEFT);
sprintf is what you need.
EDIT (somehow requested by the downvotes), from the page linked above, here's a sample "zero-padded integers":
<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>
Though I'm not really sure what you want to do you are probably looking for sprintf.
This would be:
$value = sprintf( '%08d', 1234567 );
Simple answer
$p = 1234567;
$p = sprintf("%08d",$p);
I'm not sure how to interpret the comment saying "It will never be more than 8 digits" and if it's referring to the input or the output. If it refers to the output you would have to have an additional substr() call to clip the string.
To clip the first 8 digits
$p = substr(sprintf('%08d', $p),0,8);
To clip the last 8 digits
$p = substr(sprintf('%08d', $p),-8,8);
If the input numbers have always 7 or 8 digits, you can also use
$str = ($input < 10000000) ? 0 . $input : $input;
I ran some tests and get that this would be up to double as fast as str_pad or sprintf.
If the input can have any length, then you could also use
$str = substr('00000000' . $input, -8);
This is not as fast as the other one, but should also be a little bit faster than str_pad and sprintf.
Btw: My test also said that sprintf is a little faster than str_pad. I made all tests with PHP 5.6.
Edit: Altough the substr version seems to be still very fast (PHP 7.2), it also is broken in case your input can be longer than the length you want to pad to. E.g. you want to pad to 3 digits and your input has 4 than substr('0000' . '1234', -3) = '234' will only result in the last 3 digits
$no_of_digit = 10;
$number = 123;
$length = strlen((string)$number);
for($i = $length;$i<$no_of_digit;$i++)
{
$number = '0'.$number;
}
echo $number; /////// result 0000000123
I wrote this simple function to produce this format: 01:00:03
Seconds are always shown (even if zero).
Minutes are shown if greater than zero or if hours or days are required.
Hours are shown if greater than zero or if days are required.
Days are shown if greater than zero.
function formatSeconds($secs) {
$result = '';
$seconds = intval($secs) % 60;
$minutes = (intval($secs) / 60) % 60;
$hours = (intval($secs) / 3600) % 24;
$days = intval(intval($secs) / (3600*24));
if ($days > 0) {
$result = str_pad($days, 2, '0', STR_PAD_LEFT) . ':';
}
if(($hours > 0) || ($result!="")) {
$result .= str_pad($hours, 2, '0', STR_PAD_LEFT) . ':';
}
if (($minutes > 0) || ($result!="")) {
$result .= str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':';
}
//seconds aways shown
$result .= str_pad($seconds, 2, '0', STR_PAD_LEFT);
return $result;
} //funct
Examples:
echo formatSeconds(15); //15
echo formatSeconds(100); //01:40
echo formatSeconds(10800); //03:00:00 (mins shown even if zero)
echo formatSeconds(10000000); //115:17:46:40
You can always abuse type juggling:
function zpad(int $value, int $pad): string {
return substr(1, $value + 10 ** $pad);
}
This wont work as expected if either 10 ** pad > INT_MAX or value >= 10 * pad.

PHP date(): minutes without leading zeros

I'd like to know if there is a formatting letter for PHP's date() that allows me to print minutes without leading zeros, or whether I have to manually test for and remove leading zeros?
Use:
$minutes = intval(date('i'));
For times with more information than just minutes:
ltrim() - Strip whitespace (or other characters) from the beginning of a string
ltrim(date('i:s'), 0);
returns:
8:24
According to the PHP Documentation, the date() function does not have a placeholder for minutes without leading zeros.
You could, however, get that information by simply multiplying the dates, with a leading zero, by 1, turning it into an integer.
$minutesWithoutZero = 1* date( 'i' );
I tried to find this for seconds as well, gave up the search and just casting the result as a int like this:
echo (int)date("s");
That will get rid of the leading zero's in a fast efficient way.
Doesn't look like it, but you could do something like...
echo date('g:') . ltrim(date('i'), '0');
Alternately, you could cast the second call to date() with (int).
This also works
$timestamp = time(); // Or Your timestamp. Skip passing $timestamp if you want current time
echo (int)date('i',$timestamp);
I use this format if I need a XXmXXs format:
//Trim leading 0's and the 'm' if no minutes
ltrim(ltrim(gmdate("i\ms\s", $seconds), '0'), 'm');
This will output the following:
12m34s
1m23s
12s
i just did this one line solution
$min = intval(date('i',strtotime($date)));
Using ltrim method may remove all the leading zeroes.For ex if '00' min.In this case this will remove all the zeroes and gives you empty result.
My solution:
function seconds2string($seconds) {
if ($seconds == 0) {
return '-';
}
if ($seconds < 60) {
return date('0:s', $seconds);
}
if ($seconds < 3600) {
return ltrim(date('i:s', $seconds), 0);
}
return date('G:i:s', $seconds);
}
This will output:
0 seconds: -
10 seconds: 0:10
90 seconds: 1:30
301 seconds: 5:01
1804 seconds: 30:04
3601 seconds: 1:00:01
Just use this:
(int) date('i');
Or in mySQL just multiply it by 1, like such:
select f1, ..., date_format( fldTime , '%i' ) * 1 as myTime, ..., ...
$current_date = Date("n-j-Y");
echo $current_date;
// Result m-d-yy
9-10-2012
A quickie from me. Tell me what you think:
<?php function _wo_leading_zero($n) {
if(!isset($n[1])) return $n;
if(strpos($n, '.') !== false) {
$np = explode('.', $n); $nd = '.';
}
if(strpos($n, ',') !== false) {
if(isset($np)) return false;
$np = explode(',', $n); $nd = ',';
}
if(isset($np) && count($np) > 2) return false;
$n = isset($np) ? $np[0] : $n;
$nn = ltrim($n, '0');
if($nn == '') $nn = '0';
return $nn.(isset($nd) ? $nd : '').(isset($np[1]) ? $np[1] : '');
}
echo '0 => '._wo_leading_zero('0').'<br/>'; // returns 0
echo '00 => '._wo_leading_zero('00').'<br/>'; // returns 0
echo '05 => '._wo_leading_zero('05').'<br/>'; // returns 5
echo '0009 => '._wo_leading_zero('0009').'<br/>'; //returns 9
echo '01 => '._wo_leading_zero('01').'<br/>'; //returns 1
echo '0000005567 => '._wo_leading_zero('0000005567').'<br/>'; //returns 5567
echo '000.5345453 => '._wo_leading_zero('000.5345453').'<br/>'; //returns 0.5345453
echo '000.5345453.2434 => '._wo_leading_zero('000.5345453.2434').'<br/>'; //returns false
echo '000.534,2434 => '._wo_leading_zero('000.534,2434').'<br/>'; //returns false
echo date('m').' => '._wo_leading_zero(date('m')).'<br/>';
echo date('s').' => '._wo_leading_zero(date('s')).'<br/>'; ?>
use PHP's absolute value function:
abs( '09' ); // result = 9
abs( date( 'i' ) ); // result = minutes without leading zero
My Suggestion is Read this beautiful documentation it have all details of php date functions
Link of Documentation
And as per your question you can use i - Minutes with leading zeros (00 to 59) Which return you minutes with leading zero(0).
And Also introducing [Intval()][2] function returns the integer value of a variable. You can not use the intval() function on an object

Formatting a number with leading zeros in PHP [duplicate]

This question already has answers here:
Zero-pad digits in string
(5 answers)
Closed 2 years ago.
I have a variable which contains the value 1234567.
I would like it to contain exactly 8 digits, i.e. 01234567.
Is there a PHP function for that?
Use sprintf :
sprintf('%08d', 1234567);
Alternatively you can also use str_pad:
str_pad($value, 8, '0', STR_PAD_LEFT);
Given that the value is in $value:
To echo it:
printf("%08d", $value);
To get it:
$formatted_value = sprintf("%08d", $value);
That should do the trick
When I need 01 instead of 1, the following worked for me:
$number = 1;
$number = str_pad($number, 2, '0', STR_PAD_LEFT);
echo str_pad("1234567", 8, '0', STR_PAD_LEFT);
sprintf is what you need.
EDIT (somehow requested by the downvotes), from the page linked above, here's a sample "zero-padded integers":
<?php
$isodate = sprintf("%04d-%02d-%02d", $year, $month, $day);
?>
Though I'm not really sure what you want to do you are probably looking for sprintf.
This would be:
$value = sprintf( '%08d', 1234567 );
Simple answer
$p = 1234567;
$p = sprintf("%08d",$p);
I'm not sure how to interpret the comment saying "It will never be more than 8 digits" and if it's referring to the input or the output. If it refers to the output you would have to have an additional substr() call to clip the string.
To clip the first 8 digits
$p = substr(sprintf('%08d', $p),0,8);
To clip the last 8 digits
$p = substr(sprintf('%08d', $p),-8,8);
If the input numbers have always 7 or 8 digits, you can also use
$str = ($input < 10000000) ? 0 . $input : $input;
I ran some tests and get that this would be up to double as fast as str_pad or sprintf.
If the input can have any length, then you could also use
$str = substr('00000000' . $input, -8);
This is not as fast as the other one, but should also be a little bit faster than str_pad and sprintf.
Btw: My test also said that sprintf is a little faster than str_pad. I made all tests with PHP 5.6.
Edit: Altough the substr version seems to be still very fast (PHP 7.2), it also is broken in case your input can be longer than the length you want to pad to. E.g. you want to pad to 3 digits and your input has 4 than substr('0000' . '1234', -3) = '234' will only result in the last 3 digits
$no_of_digit = 10;
$number = 123;
$length = strlen((string)$number);
for($i = $length;$i<$no_of_digit;$i++)
{
$number = '0'.$number;
}
echo $number; /////// result 0000000123
I wrote this simple function to produce this format: 01:00:03
Seconds are always shown (even if zero).
Minutes are shown if greater than zero or if hours or days are required.
Hours are shown if greater than zero or if days are required.
Days are shown if greater than zero.
function formatSeconds($secs) {
$result = '';
$seconds = intval($secs) % 60;
$minutes = (intval($secs) / 60) % 60;
$hours = (intval($secs) / 3600) % 24;
$days = intval(intval($secs) / (3600*24));
if ($days > 0) {
$result = str_pad($days, 2, '0', STR_PAD_LEFT) . ':';
}
if(($hours > 0) || ($result!="")) {
$result .= str_pad($hours, 2, '0', STR_PAD_LEFT) . ':';
}
if (($minutes > 0) || ($result!="")) {
$result .= str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':';
}
//seconds aways shown
$result .= str_pad($seconds, 2, '0', STR_PAD_LEFT);
return $result;
} //funct
Examples:
echo formatSeconds(15); //15
echo formatSeconds(100); //01:40
echo formatSeconds(10800); //03:00:00 (mins shown even if zero)
echo formatSeconds(10000000); //115:17:46:40
You can always abuse type juggling:
function zpad(int $value, int $pad): string {
return substr(1, $value + 10 ** $pad);
}
This wont work as expected if either 10 ** pad > INT_MAX or value >= 10 * pad.

Categories