php protobuf uint64 is converted to negative number - php

I have this proto definition
message Product {
uint64 id = 1;
uint64 order_id = 2;
}
then build the response in PHP
(new Product())
->setId(3)
->setOrderId(3875412541)
what I get then is
{
"id": 3,
"order_id": -419554755
}
the order id in this example is 10 characters long. Starting from 11 characters I get
13 INTERNAL: Failed to parse server response
it only works if the order_id is 8 characters long
{
"id": 3,
"order_id": 38754125
}

Related

sum availibilty of user in minute

I want to calcul the total availability of an user:
I store availibilty like this :
And I have history of availibilty cause user can change their availibilty so I need to make the sum with this.
signupDate to first UpdateDATE and after
updateDate[i] to updateDate[i+1]
and at the end
updateDate[i+n] to now;
and get for each duration in minute :
endHours - startHours
I got json like this :
availibility object are per week
{
"2022-12-20" (date when user have signup ): [
{
dayNumber : 2,
startHours:08:00,
endHours :10:00;
},
{
dayNumber : 3,
startHours:11:00,
endHours :16:00;
}
],
"2022-12-28" (date when user have update his availibilties): [
{
dayNumber : 2,
startHours:08:00,
endHours :10:00;
},
{
dayNumber : 3,
startHours:11:00,
endHours :16:00;
}
],
"2023-01-01" (date when user have update his availibilties): [
{
dayNumber : 5,
startHours:05:00,
endHours :10:00;
},
{
dayNumber : 7,
startHours:19:00,
endHours :22:00;
}
]
}
Whats I have start for the moment :
I have count number of weeks beetwen signupDate and now :
$number_of_week = Carbon::parse($user->signupDate)->diffInWeeks(Carbon::now());
Finaly I want to get total availibilty of the user
Thanks
After our chat, I think I got the full picture of the problem, so lets see if we can solve this together:
I'm not sure where the json comes from, so let's just assign it to a variable for now:
$jsonString = '
{
"2022 - 12 - 20": [
{
"dayNumber": 2,
"startHours": "08:00",
"endHours": "10:00"
},
{
"dayNumber": 3,
"startHours": "11:00",
"endHours": "16:00"
}
],
"2022 - 12 - 28": [
{
"dayNumber": 2,
"startHours": "08:00",
"endHours": "10:00"
},
{
"dayNumber": 3,
"startHours": "11:00",
"endHours": "16:00"
}
],
"2023 - 01 - 01": [
{
"dayNumber": 5,
"startHours": "05:00",
"endHours": "10:00"
},
{
"dayNumber": 7,
"startHours": "19:00",
"endHours": "22:00"
}
]
}
';
Then, we can run the code like so:
//I'm assuming that the json only contains availabilities for 1 user
//This creates an associated array out of your json
$assocArray = json_decode($jsonString, true);
$totalAvailabilityInMinutes = 0;
foreach($assocArray as $updatedAvailabilityAt => $availabilityArray) {
$availabilityOfDayInMinutes = 0;
foreach($availabilityArray as $availability) {
$explodedStart = explode(':', $availability['startHours']);
$explodedEnd = explode(':', $availability['endHours']);
//Perform calculation from my comment
$availabilityOfDayInMinutes = ($explodedEnd[0] * 60 + $explodedEnd[1]) - ($explodedStart[0] * 60 + $explodedStart[1]);
dump("Availability of day {$availability['dayNumber']}: $availabilityOfDayInMinutes");
$totalAvailabilityInMinutes += $availabilityOfDayInMinutes;
}
}
dump($totalAvailabilityInMinutes);
Please note that I used 2 variables to store the minutes, one per day, and one accumulating the days. You can pick which one is most applicable to you.
I've tested the code locally, it should work and provide correct numbers ;)
Edit:
So since you already have an array, not a json, you could skip this step:
$assocArray = json_decode($jsonString, true);

how to check if a number starts with two allowed numbers php?

How to validate that the numeric string starts the first two numbers only with the following list allowed:
01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, and 30.
$number = 1234567890;
if(ctype_digit($number)){
if (strlen($number) <= 10) {
echo "The registered number is correct";
} else {
echo "The number must have 10 digits";
}
} else {
echo "Number must be digit / numeric only.";
}
What I want to add to this functionality is to validate that said number that is stored in $number must start with the first two numbers that are in the list in order to continue.
Another way is to temporarily cast the number into a string and make use of the regular expression of ^([01]\d|2[0-4]|30) to check whether the number string starts with the specific values you mentioned in the above. You can use PHP's preg_match function to help check whether the string matches the regular expression.
So your code becomes:
if(ctype_digit($number)){
if (strlen($number) <= 10 and preg_match('/^([01]\d|2[0-4]|30)/', (string)$number)) {
echo "The registered number is correct";
} else {
echo "The number must have 10 digits or it begins with incorrect values";
}
} else {
echo "Number must be digit / numeric only.";
}
Regular expression explanation:
^: Matches the pattern from the start of the string
[01]\d: Matches 00, 01, 02, ... , 10, 11, ... , 19
2[0-4]: Matches 20, 21, ... , 24
30: Matches 30
([01]\d|2[0-4]|30): Match either [01]\d, 2[0-4] or 30
preg_match function returns 1 if the regular expression pattern is matched successfully.
If your allowed starting numbers are stored in an array, you could extract the 2 first numbers from $number using substr() and then check with in_array().
You can use regular expressions for this, but something to note: a number starting with a 0 will be interpreted as octal and converted to base 10. To avoid this, you must quote the number:
$number = '055231';
// Fill the list of allowed numbers
$allowed = array_map(function($number) {
// Fill each element to length 2 with '0' to the left
return str_pad($number, 2, '0', STR_PAD_LEFT);
}, range(1, 24));
$allowed[] = 30;
if (preg_match('/^\d{2,10}$/', $number)) {
// At this point we know it contains only numbers
// Extract first two characters
$start = substr($number, 0, 2);
// Check if it's in the allowed list
if (in_array($start, $allowed)) {
echo "The registered number is correct";
} else {
echo "The number is incorrect";
}
} else {
echo "Number must be digit / numeric only.";
}
Regex breakdown:
^ and $ are delimiters. The string must match exactly.
\d. Digit character class. Matches only numbers.
{2,10}. Previous group must be of length between 2 and 10 (since it must start with two digits).
Function reference:
range
array_map
str_pad
in_array
substr
A possible alternate solution could be to hardcode the valid prefixes and check if the first 2 characters of the string is one of them using array_key_exists:
$valid_prefixes = array_fill_keys(array("01", "02", "03", "04", "05",
"06", "07", "08", "09", "10",
"11", "12", "13", "14", "15",
"16", "17", "18", "19", "20",
"21", "22", "23", "24", "30"), true);
function starts_with_valid_prefix($str) {
global $valid_prefixes;
return strlen($str) >= 2 && array_key_exists(substr($str, 0, 2), $valid_prefixes);
}

Sorting Minutes

im trying to sort soccer minutes, but is not sorting right, for example in soccer is very normal minutes be like "1,2,3,40+5...". Basically is saying 40 minutes + 5 minutes (45 minutes).
So in my records i a colllection like:
[
{
"id": 9876,
"minute": "90+30",
},
{
"id": 9874,
"minute": "90+10",
},
{
"id": 9873,
"minute": "105",
},
{
"id": 9873,
"minute": "90",
},
...
]
So to make it order the minutes right, i need to use explode on the string "minute", than make a array_sum, but in my code, it still doesnt order right, still in the 105 is above of "90+10".
Here is my code:
$timelines = SoccerTime::where('match_id',$id)
->orderBy('minute', 'desc')
->get();
$collection = collect($timelines);
$sorted = $collection->sortByDesc('minute');
$test = $sorted->values()->all();
//Here i begin the new Sort
$newSort = collect($test)->sort(function ($a, $b) {
return array_sum(explode("+",$a->minute)) - array_sum(explode("+",$b->minute));
});
return $newSort;
I think you should change a couple of field in your model. I'd use a minute field to store the actual minute (100 in cases like your "90+10" example) and another integer field period to indicate the "period", where:
- 1 for 1T
- 2 for 2T
- 3 for 1ET
- 4 for 2ET.
So your new way of sorting should be:
First by period (solving your problem of getting 90'+4' of 2T before 93' of 1ET) and then by minute (the actual sort).
It would be so much easier and it could also help you to do some other reporting queries.

I want to sort arrays, but I can't?

I have a JSON file that I created, and I want to sort from the biggest price value.
JSON is like this:
[
{
"username": "elbugato",
"sold": 19,
"qmimi": 38.5
},
{
"username": "Pablo",
"sold": 12,
"qmimi": 42
},
{
"username": "Hqstuff",
"sold": 0,
"qmimi": "0"
},
{
"username": "matchspamm3rs",
"sold": 0,
"qmimi": "0"
},
{
"username": "Pachenko",
"sold": 1,
"qmimi": 1.1
},
I want to sort qmimi from the highest value
My php code is this.
$sellertop8json = json_decode(get_html('link'));
$i = 1;
sort($sellertop8json->qmimi, SORT_NUMERIC);
foreach($sellertop8json as $top8){
max($top8);
if (++$i == 8) break;
echo '<tr>
<td>'.$top8->username.'</td>
<td># '.$top8->sold.'</td>
<td>$ '.$top8->qmimi.'</td>
</tr>
';
}
but they aren't sorting from the biggest value
The results I get :
Look at "Pachenko", he is after a seller that has "0" Earned.
Thank You
Sorry for my bad English
P.S : JSON ISN'T RAW, I copied from some extension I am using on google chrome, so JSON it's not the problem.
You need to use usort and provide custom function comparing the field of the element:
usort($sellertop8json, function($a, $b) {
return $a->qmimi == $b->qmimi ? 0 :
$a->qmimi < $b->qmimi ? 1 : -1;
}
);
The comparison function must return 0 if the elements are equal, less than 0 if the first element is lower and greater than 0 if the second element is higher.
This may be a bit confusing as you're sorting from highest and therefore the swap of the sign in comparison - see the last part of comparison.

Is there a maximum length for json in Java?

I'm getting an output of the classes that students saw through all the university career.
this is an example of the output
{
"HISTORICOP": [
{
"MATERIA": "PROCESOS DEL LENGUAJE ",
"NOTA": "7 ",
"ANIO": "2000",
"PERIODO": "001",
"ENEMENOSUNO": "0 "
},
{
"MATERIA": "RAZONAMIENTO BASICO FG ",
"NOTA": "13 ",
"ANIO": "2000",
"PERIODO": "001",
"ENEMENOSUNO": "0 "
},
{
"MATERIA": "DESARROLLO DE COMPETENCIAS ",
"NOTA": "8 ",
"ANIO": "2000",
"PERIODO": "001",
"ENEMENOSUNO": "n-1 "
}
]
}
these are 3 of the results
but the whole output are 91 results,
when I run it on a emulator the blackberry is not able to read it
but when I try with less results he can read it!
Is there a maximum json length size so it can be read in java?
this is how I retrieve the info! from SAP
try {
$conn = new sapnwrfc($config);
$fds = $conn->function_lookup("ZCM_GET_HORARIO");
$parms = array('CEDULA' => '16814224');
$results = $fds->invoke($parms);
echo "[".json_encode($results)."]";
$conn->close();
} catch (Exception $e) {
echo "Connection Failed 3";
}
There is no absolute limitation in JSON. In Java there is a limit to the length of a String, which is 2^31-1 or over 2 billion characters long. But given the snippet of code you showed us you are not actually using Java (Java doesn't have "$" before variable names).
There may be a limitation in whatever library you are using which is not a fundamental limitation of the data format or the language.
But if you are having problems with just 91 items (not 91 thousand or 91 million) then it is far more likely that you problem is NOT due to a fundamental size limitation. If you post more about what actual errors you saw you might get a more useful response.

Categories