How to convert Facebook time zone to a custom string - php

I am working on facebook integration in my application.
Facebook returns users timezone in the format like for India its
5.5
But the existing timezones are saved in database in format
+05:30
Any functions or algorithm suggestions for this conversion.
thanks .

This one is a bit long but it adds necessary preceding zeros etc if that's a requirement.
$num = -5.5;
$res = ($num < 0 ? '-' : '+') . (abs($num) < 10 ? '0' : '') . abs((int)$num) . ':';
// --> -05:
$mins = round((abs($num) - abs((int)$num)) * 60);
// --> 30
$res .= ($mins < 10 ? '0' : '') . $mins;
echo $res;
// -05:30

Easy peasy (assume $a = 5.5):
$tz = ($a > 0 ? '+' : '-') . ((int) $a) . ':' . (($a - (int)$a)*60)
First bit gets you the - or + sign (left/right timezones), secondly casting $a to (int) you lose the fractional part and the third bit first gets the fractional part (I'm sure there's a php function for this but I come from C so basically: 5.5 - (int)5.5 = 5.5 - 5 = 0.5). The fractional part is expressed in hours (5.5 hours is 5 hours and 30 minutes) so basically 0.5 * 60 gets you the fractional part in minutes.
EDIT: Here's a cleaner (one-liner) version:
$time = sprintf("%+03d:%2d", (int)$a, abs($a-(int)$a)*60);
This one is pretty much the easiest. Thanks inhan for pointing out the abs() detail :)

Related

Find first and last number of length n and starting in digit d?

I need to find the first and last number with length n and starting with digit d.
For example.
i need to find the first and last number with length 6 and starting in 2
The result should be first number=200000 and last number=299999 .
I there any functions available in php to help me to get a logic to solve this.??
Hope Someone can help me..
You could try relying on the fact that the smallest number will end in all 0's and the largest in all 9's, and then use str_repeat to generate the appropriate tailing digits:
echo $d . str_repeat('0', $n-1);
echo $d . str_repeat('9', $n-1);
For $d = 2 and $n = 6, this will give you 200000 and 299999.
If you need them as integers, just do
$start = (int)($d . str_repeat('0', $n-1));
$finish = (int)($d . str_repeat('9', $n-1));
var_dump($start);
var_dump($finish);
Output:
int(200000)
int(299999)
Here is an option which uses algebra to get the numbers you want. Based on the width of the number, we can compute the smallest number with that width. Then, the starting number is simply this value times the starting first digit. And the ending number can also be teased out.
$length = 6;
$first = 2;
$begin = pow(10, $length-1);
$start = $first * $begin;
$end = (($first + 1) * $begin) - 1;
echo $start . "\n";
echo $end;
200000
299999
Demo
This should outperform the accepted answer because generating the numbers requires only a few arithmetic operations, rather than complex string manipulation operations.

How to find average of something like this in php $a = 01:04:06:02:55:28 $b = 03:04:06:02:54:34?

$a = 01:04:06:02:55:28
$b = 03:04:06:02:54:34
//format("%Y:%M:%D:%H:%I:%S")
I would like to find average of these two.
In this case $a is time taken to finish task 1 and $b is time taken to finish task 2, Now I would like to know average time taken by the person to complete two tasks.
You can calculate the mean of the two timestamp. live demo
<?php
$a = '01:04:06:02:55:28';
$b = '03:04:06:02:54:34';
$aTimestamp = DateTime::createFromFormat('m:d:y:h:i:s', $a, new DateTimeZone('Europe/Warsaw'))->getTimestamp();
$bTimestamp = DateTime::createFromFormat('m:d:y:h:i:s', $b, new DateTimeZone('Europe/Warsaw'))->getTimestamp();
echo date("m:d:y:h:i:s", ($aTimestamp + $bTimestamp)/2);
You should use timedelta objects if your format corresponds to a duration and not exact dates (see live demo or code below, assuming 1 year=365 days and 1 month=30 days). Notice that timedelta objects accept just days (rather than months or years, avoiding ambiguity). Timedelta objects allow arithmetic operations (see https://docs.python.org/2.4/lib/datetime-timedelta.html)
Datetime objects assume a calendar, which means that they would use the actual duration of months and years between the two points (with months ranging 28-31 and maybe leap years instead of "standard" durations).
from datetime import timedelta
a = "01:04:06:02:55:28"
b = "03:04:06:02:54:34"
(y,mo,d,h,mi,s) = a.split(":");
tda = timedelta(days=int(y)*365+int(mo)*30+int(d), hours=int(h), minutes=int(mi), seconds=int(s));
(y,mo,d,h,mi,s) = b.split(":");
tdb = timedelta(days=int(y)*365+int(mo)*30+int(d), hours=int(h), minutes=int(mi), seconds=int(s));
print("a: " + str(tda))
print("b: " + str(tdb))
print("average: " + str((tda+tdb)/2))
# now we only need to format the output as needed
avgtd = (tda+tdb)/2
avgy = avgtd.days/365
avgm = (avgtd.days - avgy*365) / 30
avgd = (avgtd.days - avgy*365 - avgm*30)
avghou = avgtd.seconds / 3600
avgmin = (avgtd.seconds - avghou*3600) / 60
avgsec = (avgtd.seconds - avghou*3600 - avgmin*60)
print("average: " + str(avgtd))
print ("{}:{}:{}:{}:{}:{}".format(avgy,avgm,avgd,avghou,avgmin, avgsec))
Alternatively, you could just calculate the average of each field. But I think it would be strange having 0.5 years, 0 months, 0 days instead of having 0 years, 6 months. The code would be easier, though, if this is a valid option:
a = "01:04:06:02:55:28"
b = "03:04:06:02:54:34"
(ay,amo,ad,ah,ami,asec) = a.split(":");
(by,bmo,bd,bh,bmi,bsec) = b.split(":");
print ("{}:{}:{}:{}:{}:{}".format((int(ay)+int(by))/2.0,(int(amo)+int(bmo))/2.0,(int(ad)+int(bd))/2.0,(int(ah)+int(bh))/2.0,(int(ami)+int(bmi))/2.0,(int(asec)+int(bsec))/2.0))

compare times with hundredths in php

I try to compare two swim times in php. They are like HH:MM:SS.XX (XX are hundreths). I get them as string and i want to find out which swimmer is faster. I tryed to convert them using strtotime(). It works with hours, minutes and seconds but it ignores hundreths. Here is my code for better explanation:
$novy = strtotime($input1);
$stary = strtotime($input2);
if($novy < $stary){
//change old(stary) to new(novy)
}
If $input1 is 00:02:14.31 and $input2 is 00:02:14.32 both $novy and $stary are 1392850934.
I read some solution to similar problem in javascript but I can`t use it, this must be server-side.
Thank you for help.
If you use date_create_from_format you can specify the exact date format for php to convert the string representations to:
<?php
$input1 = '00:02:14.31';
$input2 = '00:02:14.32';
$novy = date_create_from_format('H:i:s.u', $input1);
$stary = date_create_from_format('H:i:s.u',$input2);
if ($novy < $stary) {
echo "1 shorter\n";
} else {
echo "2 longer\n";
}
Recommended reading: http://ie2.php.net/datetime.createfromformat
If the format is really HH:MM:SS.XX (ie: with leading 0's), you can just sort them alphabetically:
<?php
$input1 = '00:02:14.31';
$input2 = '00:02:14.32';
if ($input1 < $input2) {
echo "1 faster\n";
} else {
echo "2 faster\n";
}
It prints 1 faster
You could write some conditional logic to test if HH::MM::SS are identical, then simply compare XX, else use the strtotime() function that you are already using
You are working with durations, not dates. PHP's date and time functions aren't really of any help here. You should parse the string yourself to get a fully numeric duration:
$time = '00:02:14.31';
sscanf($time, '%d:%d:%d.%d', $hours, $minutes, $seconds, $centiseconds);
$total = $centiseconds
+ $seconds * 100
+ $minutes * 60 * 100
+ $hours * 60 * 60 * 100;
var_dump($total);
The total is in centiseconds (100th of a second, the scale of your original input). Multiply/divide by other factors to get in others scales, as needed.

How to get current time in milliseconds in PHP?

time() is in seconds - is there one in milliseconds?
The short answer is:
$milliseconds = floor(microtime(true) * 1000);
Use microtime. This function returns a string separated by a space. The first part is the fractional part of seconds, the second part is the integral part. Pass in true to get as a number:
var_dump(microtime()); // string(21) "0.89115400 1283846202"
var_dump(microtime(true)); // float(1283846202.89)
Beware of precision loss if you use microtime(true).
There is also gettimeofday that returns the microseconds part as an integer.
var_dump(gettimeofday());
/*
array(4) {
["sec"]=>
int(1283846202)
["usec"]=>
int(891199)
["minuteswest"]=>
int(-60)
["dsttime"]=>
int(1)
}
*/
Short answer:
64 bits platforms only!
function milliseconds() {
$mt = explode(' ', microtime());
return intval( $mt[1] * 1E3 ) + intval( round( $mt[0] * 1E3 ) );
}
[ If you are running 64 bits PHP then the constant PHP_INT_SIZE equals to 8 ]
Long answer:
If you want an equilvalent function of time() in milliseconds first you have to consider that as time() returns the number of seconds elapsed since the "epoch time" (01/01/1970), the number of milliseconds since the "epoch time" is a big number and doesn't fit into a 32 bits integer.
The size of an integer in PHP can be 32 or 64 bits depending on platform.
From http://php.net/manual/en/language.types.integer.php
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18, except for Windows, which is always 32 bit. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.
If you have 64 bits integers then you may use the following function:
function milliseconds() {
$mt = explode(' ', microtime());
return intval( $mt[1] * 1E3 ) + intval( round( $mt[0] * 1E3 ) );
}
microtime() returns the number of seconds since the "epoch time" with precision up to microseconds with two numbers separated by space, like...
0.90441300 1409263371
The second number is the seconds (integer) while the first one is the decimal part.
The above function milliseconds() takes the integer part multiplied by 1000
1409263371000
then adds the decimal part multiplied by 1000 and rounded to 0 decimals
1409263371904
Note that both $mt[1] and the result of round are casted to int via intval(). This is necessary because they are floats and the operation on them without casting would result in the function returning a float with a loss in precision.
Finally, that function is slightly more precise than
round(microtime(true)*1000);
that with a ratio of 1:10 (approx.) returns 1 more millisecond than the correct result.
This is due to the limited precision of the float type (microtime(true) returns a float).
Anyway if you still prefer the shorter round(microtime(true)*1000); I would suggest casting to int the result.
Even if it's beyond the scope of the question it's worth mentioning that if your platform supports 64 bits integers then you can also get the current time in microseconds without incurring in overflow.
If fact 2^63 - 1 (biggest signed integer) divided by 10^6 * 3600 * 24 * 365 (approximately the microseconds in one year) gives 292471.
That's the same value you get with
echo intdiv( PHP_INT_MAX, 1E6 * 3600 * 24 * 365 );
In other words, a signed 64 bits integer have room to store a timespan of over 200,000 years measured in microseconds.
You may have then
function microseconds() {
$mt = explode(' ', microtime());
return intval( $mt[1] * 1E6 ) + intval( round( $mt[0] * 1E6 ) );
}
As other have stated, you can use microtime() to get millisecond precision on timestamps.
From your comments, you seem to want it as a high-precision UNIX Timestamp. Something like DateTime.Now.Ticks in the .NET world.
You may use the following function to do so:
function millitime() {
$microtime = microtime();
$comps = explode(' ', $microtime);
// Note: Using a string here to prevent loss of precision
// in case of "overflow" (PHP converts it to a double)
return sprintf('%d%03d', $comps[1], $comps[0] * 1000);
}
Shortest version of string variant (32-bit compatibile):
$milliseconds = date_create()->format('Uv');
echo date('Y-m-d H:i:s.') . gettimeofday()['usec'];
output:
2016-11-19 15:12:34.346351
Use microtime(true) in PHP 5, or the following modification in PHP 4:
array_sum(explode(' ', microtime()));
A portable way to write that code would be:
function getMicrotime()
{
if (version_compare(PHP_VERSION, '5.0.0', '<'))
{
return array_sum(explode(' ', microtime()));
}
return microtime(true);
}
This works even if you are on 32-bit PHP:
list($msec, $sec) = explode(' ', microtime());
$time_milli = $sec.substr($msec, 2, 3); // '1491536422147'
$time_micro = $sec.substr($msec, 2, 6); // '1491536422147300'
Note this doesn't give you integers, but strings. However this works fine in many cases, for example when building URLs for REST requests.
If you need integers, 64-bit PHP is mandatory.
Then you can reuse the above code and cast to (int):
list($msec, $sec) = explode(' ', microtime());
// these parentheses are mandatory otherwise the precedence is wrong!
// ↓ ↓
$time_milli = (int) ($sec.substr($msec, 2, 3)); // 1491536422147
$time_micro = (int) ($sec.substr($msec, 2, 6)); // 1491536422147300
Or you can use the good ol' one-liners:
$time_milli = (int) round(microtime(true) * 1000); // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300
try this:
public function getTimeToMicroseconds() {
$t = microtime(true);
$micro = sprintf("%06d", ($t - floor($t)) * 1000000);
$d = new DateTime(date('Y-m-d H:i:s.' . $micro, $t));
return $d->format("Y-m-d H:i:s.u");
}
PHP 5.2.2 <
$d = new DateTime();
echo $d->format("Y-m-d H:i:s.u"); // u : Microseconds
PHP 7.0.0 < 7.1
$d = new DateTime();
echo $d->format("Y-m-d H:i:s.v"); // v : Milliseconds
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;
NOTE: PHP5 is required for this function due to the improvements with
microtime() and the bc math module is also required (as we’re dealing
with large numbers, you can check if you have the module in phpinfo).
Hope this help you.
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
($the_date_time->format('u') / 1000);
This is my implementation, should work on 32bit as well.
function mstime(){
$mstime = explode(' ',microtime());
return $mstime[1].''.(int)($mstime[0]*1000);
}
If you want to see real microseconds, you will need to change the precision setting in php.ini to 16.
After that, microsecond(true) gave me the output of 1631882476.298437.
So I thought that I need to divide the remainder (298437) with 1000, but in fact, the remainder is 0.298437 of a second. So I need to multiply that by 1000 to get the correct result.
function get_milliseconds()
{
$timestamp = microtime(true);
return (int)(($timestamp - (int)$timestamp) * 1000);
}
I personaly use this:
public static function formatMicrotimestamp(DateTimeInterface $dateTime): int
{
return (int) substr($dateTime->format('Uu'), 0, 13);
}
Use this:
function get_millis(){
list($usec, $sec) = explode(' ', microtime());
return (int) ((int) $sec * 1000 + ((float) $usec * 1000));
}
Bye

Dividing with a remainder in PHP

I have a part in my code where I need to divide and have a remainder instead of a decimal answer.
How can I do this?
$quotient = intval($dividend / $divisor);
$remainder = $dividend % $divisor;
Using intval instead of floor will round the quotient towards zero, providing accurate results when the dividend is negative.
You can do what you are describing using the "%" (modulus) operator. The following code is an example of dividing with a remainder.
$remainder=$num % $divideby;
$number=explode('.',($num / $divideby));
$answer=$number[0];
echo $answer.' remainder '.$remainder;
A solution for positive and negative numbers:
$quotient = $dividend / $divison;
$integer = (int) ($quotient < 0 ? ceil($quotient) : floor($quotient));
$remainder = $dividend % $divisor;
The mathematical correct answer is:
remainder = dividend % divisor;
quotient = (dividend - remainder) / divisor;
and the remainder verifies the condition 0 <= remainder < abs(divisor).
Unfortunately, many programming languages (including PHP) don't handle the negative numbers correctly from the mathematical point of view. They use different rules to compute the value and the sign of the remainder. The code above does not produce the correct results in PHP.
If you need to work with negative numbers and get the mathematical correct results using PHP then you can use the following formulae:
$remainder = (($dividend % $divider) + abs($divider)) % abs($divider);
$quotient = ($dividend - $remainder) / $divider;
They rely on the way PHP computes modulus with negative operands and they may not provide the correct result if they are ported to a different language.
Here is a script that implements these formulae and checks the results against the values provided as example in the aforementioned mathematical correct answer.
If you need to look it up, the % operator is called mod (or modulus).
I had to develop this approach because my numerator was a float value and modulus was rounding results.
Using Raffaello's approach offered here for dividing floats and taking from Sam152's solution above came up with the following.
$a = 2.1;
$b = 8;
$fraction = $a / (float) $b;
$parts = explode('.', $fraction);
$int = $parts[0];
$remainder = $score - ($int*$b) ;
Use This Function Its an array
Description
array gmp_div_qr ( resource $n , resource $d [, int $round ] )
The function divides n by d .
reference : http://php.net/manual/en/function.gmp-div-qr.php
An example to show strings like 1 hour 6 minutes using floor() and modulus (%) if only minutes/seconds given:
$minutes=126;
if($minutes < 60) {
$span= $minutes.' min.';
} else {
$rem=$minutes % 60;
$span=floor($minutes/60).' h. '. (($rem>0) ? $rem.' min.':'');
}
// echo 'Hello Jon Doe, we notify you that even will last for 2 h. 6 min.
echo 'Hello Jon Doe, we notify you that event will last for '.$span;
It seems to be an old post, but for those who might be interested here is a very light package that could meet your needs: https://github.com/romainnorberg/residue (feedbacks are welcome)

Categories