Change seconds duration to ISO 8601 format - php

How can I convert
00:00:46.70
to
T0M46S
I try
$date = new DateTime($time); echo $date->format('\P\TG\Hi\M');
but it gives me something like this:
PT0H00M
Note I want duration... not date!

There is no native function, but you can do it with native object DateTime : calculate the duration from midnight to your time.
<?php
$time = new DateTime('00:00:46.70');
$midnight = new DateTime('00:00:00.00');
$period = $midnight->diff($time);
echo $period->format('T%iM%SS'); //output T0M46S
print_r($period);
Here is a php sandbox to test it

Carbon has the solution
function secondsToISO8601Format(int $seconds): string
{
return Carbon\CarbonInterval::seconds($seconds)->cascade()->spec();
}

Related

Date difference in PHP code does not execute

I have a code in PHP 5.5.11 where I am trying to do the following:
Get today's date in a variable --> $today
Calculate the end of month from a date in a form --> $st_dt_eom
if difference between these 2 dates is more than 5 days then execute a code. The code in the if condition below does not execute.
$today= date();
if($_POST['Submit']=='SAVE')
{
$st_dt=YYYYMMDD($_POST['st_dt'],"-");
$st_dt_eom= datetime::createfromformat('YYYYMMDD',$st_dt);;
$st_dt_eom->modify('last day of this month');
$diff = $today->diff($st_dt_eom);
$diffDays= intval($diff->format("%d")); //to get integer number of days
if($diffDays>5){
redirect("index.php");
}
}
An example:
// 2022-12-19
$today = date('Y-m-d');
// $_POST['st_dt']
$st_dt = '2022-12-31';
function dateDiffDays($today, $st_dt)
{
$today_obj= DateTime::createfromformat('Y-m-d', $today);
$st_dt_eom= DateTime::createfromformat('Y-m-d', $st_dt);
$diff = $today_obj->diff($st_dt_eom);
return $diff->days;
}
// int(12)
$res = dateDiffDays($today, $st_dt);
use var_dump to locate your bug.
A few suggestions to improve your code and produce something workable:
<?php
// Instead of using date(), use a DateTime() then you're comparing two DateTimes later on
$today = new DateTime();
// I'm assuming that your YYYYMMDD function removes "-" from the $_POST['st_dt']
// to provide a date in the format YYYYMMDD (or Ymd in PHP).
// Unfortunately, DateTime doesn't understand that format.
// So I'd change this for keeping Y-m-d (YYYY-MM-DD).
// Or modify your code to return that format!
$st_dt = $_POST['st_dt'];
// Watch out for your cAsE when using PHP functions!
$st_dt_eom = DateTime::createFromFormat('Y-m-d',$st_dt);
$st_dt_eom->modify('last day of this month');
$diff = $today->diff($st_dt_eom);
$diffDays= intval($diff->format("%d"));
if($diffDays > 5){
redirect("index.php");
}

How to retrieve the number of days from a PHP date interval?

I am trying to retrieve the number of days for a PHP interval. When I run the following piece of code on http://sandbox.onlinephpfunctions.com/:
$duration = new \DateInterval('P1Y');
echo $duration->format('%a');
echo "Done";
I get:
(unknown)Done
What am I doing wrong?
The '%a' will return the number of days only when you take a time difference otherwise it will return unknown.
You can use '%d' to get the days but it will also return 0 in the case of new \DateInterval('P1Y') as it does not convert years to days.
One easy way to get the number of days is to create a DateTime at zero time, add the interval to it, and then get the resulting timestamp:
<?php
$duration = new \DateInterval('P1Y');
$intervalInSeconds = (new DateTime())->setTimeStamp(0)->add($duration)->getTimeStamp();
$intervalInDays = $intervalInSeconds/86400;
echo $intervalInDays;
echo " Done";
The problem is here:
$duration->format('%a');
As the manual says, "Total number of days as a result of a DateTime::diff() or (unknown) otherwise".
You need a valid dateInterval object returned by DateTime's diff() method to make the "a" parameter work with DateInterval::format() function:
$now = new DateTime(date('Y-m-d H:i:s'));
$duration = (new DateTime("+1 year"))->diff($now);
echo $duration->format('%a');
Looks like if the DateInterval object is not created by DateTime::diff(), it won't work.
Hope it helps.
You have to create the interval with real dates:
<?php
$interval = date_diff(new DateTime, new DateTime('+1 year'));
echo $interval->format('%a'), PHP_EOL; // 365
if you want something aware of the year or month context, use this, february will return 28 days, leap years will have their additional day
function interval2days($day, $interval) {
$date = clone $day;
$start = $date->getTimeStamp();
$end = $date->add($interval)->getTimeStamp();
return ($end-$start)/86400;
}

How to convert a PHP DateTime object to ISO string?

I have a date that I receive in MS format for JSON dates. It looks like this:
/Date(1365004652303)/
I can convert it to a PHP DateTime object by doing this:
$timestamp = round(((int) $originalMSdate) / 1000);
$convertedDate = new DateTime();
$convertedDate->setTimestamp($timestamp);
Ultimately, though, I need it to be a string in ISO 8601 format. I tried then converting it to an ISO date object & then converting that to a string with strval() but strval() doesn't work on date objects.
I've also tried
$dateString = date_format($convertedDate, 'YY-MM-DD H:i:s');
but I need it to also include timezone info, like this: 2015-10-01T21:22:57.057Z
I don't see characters for that in date_format.
How can I achieve this?
EDIT: I should clarify that I'm not printing the resulting string. I need to pass it to a field in a database that accepts a string datatype.
Please try the below code
<?php
// input
$time = microtime(true);
// Determining the microsecond fraction
$microSeconds = sprintf("%06d", ($time - floor($time)) * 1000000);
// Creating DT object
$tz = new DateTimeZone("Etc/UTC");
$dt = new DateTime(date('Y-m-d H:i:s.'. $microSeconds, $time), $tz);
$iso8601Date = sprintf(
"%s%03d%s",
$dt->format("Y-m-d\TH:i:s."),
floor($dt->format("u")/1000),
$dt->format("O")
);
// Formatting according to ISO 8601-extended
var_dump(
$iso8601Date
);
This worked:
$timestamp = round(((int) $originalMSdate) / 1000);
$dateString = date('c', $timestamp);
The format isn't EXACTLY the same. It's in this format:
2016-04-25T14:27:00-05:00 rather than
2016-04-25T14:27:00.057Z
but it's close enough that I can do some manipulation to get what I need.
this one is worked for me. For more please refer this article.
$date = date('Y-m-d H:m:s');
echo date('c', strtotime($date)); // 2020-04-08T16:04:56+05:30
echo date(DateTime::ISO8601, strtotime($date)); // 2020-04-08T16:04:56+0530
echo date(DateTime::ATOM, strtotime($date)); // 2020-04-08T16:04:56+05:30

PHP date conversion from Facebook API

I have a problem by converting a date in proper format.
I get the time the from Facebook API in this format: 2013-08-23T09:00:00
I then $fbdate = date('2013-08-23T09:00:00');
When I echo $fbdate, it retuns 2013-08-25UTC05:00:00.
Then I tried:
$datum = date("d.m.Y",$fbdate);
$uhrzeit = date("H:i",$fbdate);
To extract the date and the time but it always returns:
01.01.1970 for $datum and 00:33 for $uhrzeit.
You should use strtotime() to parse a date string into a UNIX timestamp:
$fbdate = strtotime('2013-08-23T09:00:00');
$datum = date('d.m.Y', $fbdate);
$uhrzeit = date('H:i', $fbdate);
Try using the DateTime class:
$fbdate = '2013-08-23T09:00:00';
$date = DateTime::createFromFormat('Y-m-d\TH:i:s', $fbdate);
$datum = $date->format('d.m.Y');
$uhrzeit = $date->format('H:i');
echo $datum;
echo $uhrzeit;
$datum = date("d.m.Y",strtotime($fbdate));
$uhrzeit = date("H:i",strtotime($fbdate));
The date function in PHP is meant to convert a microtime into a date, so you need to convert your string dates to microtimes first.
Have you tried this? You should use strtotime() when using the date function.
$datum = date("d.m.Y", strtotime($fbdate));
$uhrzeit = date("H:i", strtotime($fbdate));
Use strtotime()
$a = date("Y-M-d", strtotime($datum));
echo $a.$uhrzeit;
More info http://php.net/manual/en/function.strtotime.php
I'm not a huge fan of using timestamp.
What I did to solve this issue was:
$updatedDate = new DateTime(
preg_replace('/^(.*)\+0000$/', '$1', $fbUser->getProperty("updated_time")),
new DateTimeZone("UTC")
);
It chops the +0000 part and creates the DateTime object with an explicit UTC timezone.

How to get millisecond between two dateTime obj?

How to get millisecond between two DateTime objects?
$date = new DateTime();
$date2 = new DateTime("1990-08-07 08:44");
I tried to follow the comment below, but I got an error.
$stime = new DateTime($startTime->format("d-m-Y H:i:s"));
$etime = new DateTime($endTime->format("d-m-Y H:i:s"));
$millisec = $etime->getTimestamp() - $stime->getTimestamp();`
I get the error
Call to undefined method DateTime::getTimestamp()
In the strict sense, you can't.
It's because the smallest unit of time for the DateTime class is a second.
If you need a measurement containing milliseconds then use microtime()
Edit:
On the other hand if you simply want to get the interval in milliseconds between two ISO-8601 datetimes then one possible solution would be
function millisecsBetween($dateOne, $dateTwo, $abs = true) {
$func = $abs ? 'abs' : 'intval';
return $func(strtotime($dateOne) - strtotime($dateTwo)) * 1000;
}
Beware that by default the above function returns absolute difference. If you want to know whether the first date is earlier or not then set the third argument to false.
// Outputs 60000
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31");
// Outputs -60000 indicating that the first argument is an earlier date
echo millisecsBetween("2010-10-26 20:30", "2010-10-26 20:31", false);
On systems where the size of time datatype is 32 bits, such as Windows7 or earlier, millisecsBetween is only good for dates between 1970-01-01 00:00:00 and 2038-01-19 03:14:07 (see Year 2038 problem).
Sorry to digg out an old question, but I've found a way to get the milliseconds timestamp out of a DateTime object:
function dateTimeToMilliseconds(\DateTime $dateTime)
{
$secs = $dateTime->getTimestamp(); // Gets the seconds
$millisecs = $secs*1000; // Converted to milliseconds
$millisecs += $dateTime->format("u")/1000; // Microseconds converted to seconds
return $millisecs;
}
It requires however that your DateTime object contains the microseconds (u in the format):
$date_str = "20:46:00.588";
$date = DateTime::createFromFormat("H:i:s.u", $date_str);
This is working only since PHP 5.2 hence the microseconds support to DateTime has been added then.
With this function, your code would become the following :
$date_str = "1990-08-07 20:46:00.588";
$date1 = DateTime::createFromFormat("Y-m-d H:i:s.u", $date_str);
$msNow = (int)microtime(true)*1000;
echo $msNow - dateTimeToMilliseconds($date1);
DateTime supports microseconds since 5.2.2. This is mentioned in the documentation for the date function, but bears repeating here. You can create a DateTime with fractional seconds and retrieve that value using the 'u' format string.
<?php
// Instantiate a DateTime with microseconds.
$d = new DateTime('2011-01-01T15:03:01.012345Z');
// Output the microseconds.
echo $d->format('u'); // 012345
// Output the date with microseconds.
echo $d->format('Y-m-d\TH:i:s.u'); // 2011-01-01T15:03:01.012345
// Unix Format
echo "<br>d2: ". $d->format('U.u');
function get_data_unix_ms($data){
$d = new DateTime($data);
$new_data = $d->format('U.u');
return $new_data;
}
function get_date_diff_ms($date1, $date2)
{
$d1 = new DateTime($date1);
$new_d1 = $d1->format('U.u');
$d2 = new DateTime($date2);
$new_d2 = $d2->format('U.u');
$diff = abs($new_d1 - $new_d2);
return $diff;
}
https://www.php.net/manual/en/class.datetime.php
Here's a function to do that + tests.
https://gist.github.com/vudaltsov/0bb623b9e2817d6ce359eb88cfbf229d
DateTime dates are only stored as whole seconds. If you still need the number of milliseconds between two DateTime dates, then you can use getTimestamp() to get each time in seconds (then get the difference and turn it into milliseconds):
$seconds_diff = $date2.getTimestamp() - $date.getTimestamp()
$milliseconds_diff = $seconds_diff * 1000

Categories