Unknown date format from API response - php

API Server responds with token expiration date in the following format:
2022-05-09T02:11:27.747
What format is it?

That's ISO-8601 standard time format. Year month day T hour minute second millisecond. The date_parse function will handle this.
<?php
$x = '2021-04-01T19:18:17.654';
print_r(date_parse($x));
?>
Output:
Array
(
[year] => 2021
[month] => 4
[day] => 1
[hour] => 19
[minute] => 18
[second] => 17
[fraction] => 0.654
[warning_count] => 0
[warnings] => Array
(
)
[error_count] => 0
[errors] => Array
(
)
[is_localtime] =>
)

Related

(PHP) strtotime function false positive with char

I don't understand why this is a valid date
strtotime("1920-09k-12") // -1556877600 // I expect false
I see that adding a char after the month or day is a valid date.
strtotime("1920-09-12d") // -1555905600 // I expect false
strtotime("1920-09n-12") // -1556838000 // I expect false
Instead
strtotime("1920-09k-12k") // false
strtotime("1920r-09-12") // false
strtotime("1920-09-12") // -1555862400
Is this the expected behaviour?
I use Laravel and the strtotime function is used for validate date in the framework but when go to save a record in DB with a "false positive" date a QueryException is raised.
I resolved the problem with a custom validation but i'm curious to know why strtotime has this behaviour.
This may not fully answer your question, but examining the results of date_parse() for your sample dates, it appears that the first letter in the string is interpreted as the timezone, and the remainder of the string as well, which either causes a warning or an error of "Double timezone specification", and in the case of an error, the DateTime cannot be created.
For example:
date_parse("1920-09-12d")
Array
(
[year] => 1920
[month] => 9
[day] => 12
[hour] =>
[minute] =>
[second] =>
[fraction] =>
[warning_count] => 0
[warnings] => Array
(
)
[error_count] => 0
[errors] => Array
(
)
[is_localtime] => 1
[zone_type] => 2
[zone] => -240
[is_dst] =>
[tz_abbr] => D
)
Notice the timezone "D"
date_parse("1920-09n-12")
Array
(
[year] => 1920
[month] => 9
[day] => 1
[hour] =>
[minute] =>
[second] =>
[fraction] =>
[warning_count] => 1
[warnings] => Array
(
[8] => Double timezone specification
)
[error_count] => 0
[errors] => Array
(
)
[is_localtime] => 1
[zone_type] => 2
[zone] => 60
[is_dst] =>
[tz_abbr] => N
)
Notice the timezone "N", furthermore the 12 is not interpreted as the day of month, but rather I suspect "-12" is interpreted as an additional timezone specification, hence the warning.
date_parse("1920r-09-12")
Array
(
[year] =>
[month] =>
[day] =>
[hour] => 19
[minute] => 20
[second] => 0
[fraction] =>
[warning_count] => 1
[warnings] => Array
(
[5] => Double timezone specification
)
[error_count] => 1
[errors] => Array
(
[8] => Double timezone specification
)
[is_localtime] => 1
[zone_type] => 2
[zone] => 300
[is_dst] =>
[tz_abbr] => R
)
Notice the timezone "R", furthermore no date is parsed, rather 1920 is interpreted as the time 19:20:00, and I suspect the remainder of the string is interpreted as 2 timezones, "-09" & "-12", causing the error "Double timezone specification".

Search array of dates does not return result

Hello I am trying to search for an hour based on the current date with the following function:
$key = array_search($todayday, array_column($days, 'date', 'hours'));
Where $todayday is equal to today day which comes from the sever day date.
the Array $days is:
Array
(
[0] => Array
(
[date] => 01
[hours] => 0
)
[1] => Array
(
[date] => 02
[hours] => 8
)
[2] => Array
(
[date] => 03
[hours] => 16
)
[3] => Array
(
[date] => 04
[hours] => 24
)
[4] => Array
(
[date] => 05
[hours] => 32
)
[5] => Array
(
[date] => 06
[hours] => 40
)
[6] => Array
(
[date] => 07
[hours] => 40
)
... etc....
while $todaydate is equal to 1,2,3,4,5 it works. but for 6 and 7 does not return anything. Any help is welcome to resolve this issue. Thanks
I suspect that since date = 6 and 7 have the same value of hours this is why it does not return anything but the question is how to return it actually.
Your supposition is correct, you can not have duplicate keys. Use the key from the search and then access hours:
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];
Or shorter:
$hours = $days[array_search($todayday, array_column($days, 'date'))]['hours'];
In the case where the indexes are not 0 based and sequential, use array_values() to re-index:
$days = array_values($days);
$key = array_search($todayday, array_column($days, 'date'));
$hours = $days[$key]['hours'];

Combine intersecting keys and values in 2 arrays

I'm running through all of the array functions on php.net and unable to figure this out.
Essentially I want to take these two arrays:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
)
)
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => August
[year] => 2015
[debit] => 50.00
)
)
...and have the output look like this:
Array
(
[0] => stdClass Object
(
[month] => October
[year] => 2015
[credit] => 1000.00
[debit] => 2000.00
)
[1] => stdClass Object
(
[month] => September
[year] => 2015
[credit] => 200.00
[debit] => 0
)
[2] => stdClass Object
(
[month] => August
[year] => 2015
[credit] => 0
[debit] => 50.00
)
)
I'm looked to merge "month" and "year" and combine the other keys, using a default value if the key doesn't exist. Any guidance?
Assuming $debits and $credits are the arrays shown in your question, I would approach it like this:
First loop over the credits, inserting them into the new "combined" array and adding a default value for debit as you go.
foreach ($credits as $credit) {
$credit->debit = 0.00; // provide a default value for debit
$combined[$credit->year . $credit->month] = $credit;
}
Then loop over the debits. Since there is the possibilities that entries will already be there from credits, there needs to be a check for this. This part should update existing values inserted from credits, or insert new values if there is no existing value.
foreach ($debits as $debit) {
if (isset($combined[$debit->year . $debit->month])) {
// update the debit if the entry already exists
$combined[$debit->year . $debit->month]->debit = $debit->debit;
} else {
// otherwise create a new entry with a default value for credit
$debit->credit = 0.00;
$combined[$debit->year . $debit->month] = $debit;
}
}
// If you need the results to be numerically indexed, you can use array_values
$numerically_indexed = array_values($combined);

PHP preg_match constant output

I'm trying to parse out a string that could have multiple values and if one doesn't exist the array is outputting the part I'm looking for up one spot, causing me logic headaches.
What I'm trying to parse: P1DT12H15M, or PT1H5M, or PT15M
Basically it's P(Number of Days) T(Number of Hours)(Number of Minutes). The P and T are constant. Here's the match string I have so far:
'/P([0-9]*?)D?T([1-2]?[0-9]?)H?([1-5]?[0-9]?)M?/'
It pulls everything apart, but the array output is not what I'm looking for.
PT2H gives Array ( [0] => PT2H [1] => [2] => 2 [3] => )
PT2H15M gives Array ( [0] => PT2H15M [1] => [2] => 2 [3] => 15 )
But
PT15M gives Array ( [0] => PT15M [1] => [2] => 15 [3] => )
I need that number to be in position 3, if possible.
$exp = '/P(?:([0-9]+)D)*T(?:([1-2]?[0-9])H)*(?:([1-5]?[0-9])M)*/';
preg_match($exp, 'PT2H15M', $m); print_r($m);
preg_match($exp, 'PT15M', $m); print_r($m);
preg_match($exp, 'P1DT12H15M',$m); print_r($m);
result
Array
(
[0] => PT2H15M
[1] =>
[2] => 2
[3] => 15
)
Array
(
[0] => PT15M
[1] =>
[2] =>
[3] => 15
)
Array
(
[0] => P1DT12H15M
[1] => 1
[2] => 12
[3] => 15
)
So, you can take $P = m[1], $H= m[2], $M = m[3]
Your input strings looks like time interval specifiers. Let the PHP internal class DateInterval parse them then access the properties of [DateInterval] to get the values you need:
$int = new DateInterval('P1DT12H15M');
print_r($int);
produces:
DateInterval Object
(
[y] => 0
[m] => 0
[d] => 1
[h] => 12
[i] => 15
[s] => 0
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 0
[days] =>
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)
You can access the properties directly (they are public):
printf("%d days, %d hours, %d minutes\n", $int->d, $int->h, $int->i);
If you need them as array you can even convert $int to an array and use them this way:
$date = (array)$int;
printf("%d days, %d hours, %d minutes\n", $date['d'], $date['h'], $date['i']);
If you insist, you can even emulate the behaviour of the preg_match() you struggle to create:
$string = 'P1DT12H15M';
$interval = new DateInterval($string);
$array = (array)$interval;
$matches = array_merge(array($string), array_slice(array_values($array), 0, 6));
print_r($matches);
displays:
Array
(
[0] => P1DT12H15M
[1] => 0
[2] => 0
[3] => 1
[4] => 12
[5] => 15
[6] => 0
)
(use array_slice(..., 3, 6) to keep only the time components)

time in array - how to convert to timestamp?

I have an array with time in PHP:
[time] => Array (
[year] => 2007
[month] => 1
[day] => 2
[hour] => 1
[minute] => 1 )
)
i must save this in MySQL. in MySQL i have format
2007-01-02 01:01
how is the best method for modify array with time to timestamp?
sprintf("%04d-%02d-%02d %02d:%02d", $arr['time']['year'], $arr['time']['month'], $arr['time']['day'], $arr['time']['hour'], $arr['time']['minute']);

Categories