NotionCommotion
Members-
Posts
2,446 -
Joined
-
Last visited
-
Days Won
10
Everything posted by NotionCommotion
-
Combining time series data with irregular timestamps
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Maybe doesn't come up with equations, but does come up with the constants in those equations. Agree one needs to understand the system (unless you got yourself a billion polynomials of course). While I have seemed to gained a reputation for being abstract and maybe well earned, I am not trying to be so now. I need to provide the appropriate data to render a chart, and am currently providing a start date, an interval time and 400 values per series data using a GROUP BY query. The chart renders well when I have sufficient data samples per each GROUP BY duration, but when less sufficient, I am providing 400 values of step data and Highcharts renders it as if it was actually measured that way. One option is to only provide the values and timestamps that I have and let Highcharts use its own algorithm to smooth out the curve, but I would rather have the server perform this task. -
Combining time series data with irregular timestamps
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Yeah, my initial thought were the same. My memory was that LSR would come up with f(x) = c0 + c1*x + c2*x^2 + c3*x^4... The more polynomials, the more it can reflect the curve. Obviously, I don't have enough! For what I am doing, however, I don't think LSR is the right solution. If I wanted to predict the whatever sometime in the future, it might be a good solution (especially since no one could doubt me!), but I am just trying to fit a curve within existing data. I am sure there is a de facto standard for doing so and most likely an existing PHP class, but I don't know what it is called and haven't found it yet. Not necessarily. If the curve is trending one way or another either linearly or by change in slope, etc, it might be the right results. That being said, don't think so and agree with you. -
Combining time series data with irregular timestamps
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
I've been doing so, but it doesn't make pretty results when I have gaps. I haven't yet validated the results, but the following was a pretty easy solution. <?php use Phpml\Regression\LeastSquares; error_reporting(E_ALL); require __DIR__.'/../../vendor/autoload.php'; $scale=[1, 2, 3, 4]; $date = new DateTime(); $date->setTime(0,0,0)->sub(new DateInterval('P1D')); $date2 = clone $date; printf('%20s | %20s |%10s |%10s |%10s |%10s'.PHP_EOL, 'Time', 'Timestamp', 'Value1', 'Value2', 'Value3', 'Value4'); $series = [ ['samples'=>[], 'targets'=>[]], ['samples'=>[], 'targets'=>[]], ['samples'=>[], 'targets'=>[]], ['samples'=>[], 'targets'=>[]], ]; for ($i = 0; $i <= 20; $i++) { $record=array_fill(0,4,null); $date->add(new DateInterval(sprintf('PT%sS', rand(60, 60*60)))); $timestamp = $date->getTimestamp(); $item = rand(0,3); $value = rand(30,50)*$scale[$item]; $series[$item]['samples'][] = [$timestamp]; $series[$item]['targets'][] = $value; $record[$item] = $value; $item = rand(0,6); if($item<=3 && !isset($record[$item])){ $value = rand(30,50)*$scale[$item]; $series[$item]['samples'][] = [$timestamp]; $series[$item]['targets'][] = $value; $record[$item] = $value; } printf('%20s | %20d |%10s |%10s |%10s |%10s'.PHP_EOL, $date->format('Y-m-d H:i:s'), $timestamp, ...$record); } echo("\n\n\n\n"); $ls = []; foreach($series as $item=>$rs) { $ls[$item] = new LeastSquares(); $ls[$item]->train($rs['samples'], $rs['targets']); } $interval = new DateInterval('PT1H'); printf('%20s | %20s |%10s |%10s |%10s |%10s |%10s'.PHP_EOL, 'Time', 'Timestamp', 'Value1', 'Value2', 'Value3', 'Value4', 'Total'); while ($date2 < $date) { $record = []; $sum = 0; $ts = $date2->getTimestamp(); foreach($series as $item=>$rs) { $v = round($ls[$item]->predict([$ts]), 2); $record[$item] = $v; $sum+=$v; } $record[] = $sum; printf('%20s | %20d |%10s |%10s |%10s |%10s |%10s'.PHP_EOL, $date2->format('Y-m-d H:i:s'), $ts, ...$record); $date2->add($interval); } Time | Timestamp | Value1 | Value2 | Value3 | Value4 2020-12-15 00:01:34 | 1607990494 | 37 | | | 2020-12-15 00:04:04 | 1607990644 | | | 120 | 164 2020-12-15 00:51:11 | 1607993471 | | | 114 | 2020-12-15 01:47:15 | 1607996835 | | | 141 | 164 2020-12-15 02:13:54 | 1607998434 | 34 | 88 | | 2020-12-15 02:43:55 | 1608000235 | | | 120 | 2020-12-15 03:14:47 | 1608002087 | 40 | | 150 | 2020-12-15 04:11:14 | 1608005474 | | 84 | 114 | 2020-12-15 05:04:15 | 1608008655 | | 90 | 114 | 2020-12-15 05:45:17 | 1608011117 | | | | 188 2020-12-15 05:52:47 | 1608011567 | | | 111 | 2020-12-15 05:56:44 | 1608011804 | | | | 156 2020-12-15 06:54:21 | 1608015261 | | | 114 | 120 2020-12-15 07:21:56 | 1608016916 | | | 132 | 2020-12-15 07:30:44 | 1608017444 | 40 | | | 2020-12-15 08:06:50 | 1608019610 | | | | 136 2020-12-15 08:09:03 | 1608019743 | 50 | | | 2020-12-15 08:21:22 | 1608020482 | 35 | 100 | | 2020-12-15 09:00:20 | 1608022820 | 34 | | | 144 2020-12-15 09:49:22 | 1608025762 | | | | 196 2020-12-15 10:23:03 | 1608027783 | | 76 | | 180 Time | Timestamp | Value1 | Value2 | Value3 | Value4 | Total 2020-12-15 00:00:00 | 1607990400 | 36.63 | 90.24 | 126.1 | 158.33 | 411.3 2020-12-15 01:00:00 | 1607994000 | 36.98 | 89.81 | 125.28 | 158.73 | 410.8 2020-12-15 02:00:00 | 1607997600 | 37.33 | 89.37 | 124.47 | 159.13 | 410.3 2020-12-15 03:00:00 | 1608001200 | 37.69 | 88.93 | 123.66 | 159.53 | 409.81 2020-12-15 04:00:00 | 1608004800 | 38.04 | 88.49 | 122.84 | 159.93 | 409.3 2020-12-15 05:00:00 | 1608008400 | 38.39 | 88.06 | 122.03 | 160.32 | 408.8 2020-12-15 06:00:00 | 1608012000 | 38.75 | 87.62 | 121.22 | 160.72 | 408.31 2020-12-15 07:00:00 | 1608015600 | 39.1 | 87.18 | 120.41 | 161.12 | 407.81 2020-12-15 08:00:00 | 1608019200 | 39.45 | 86.75 | 119.59 | 161.52 | 407.31 2020-12-15 09:00:00 | 1608022800 | 39.81 | 86.31 | 118.78 | 161.92 | 406.82 2020-12-15 10:00:00 | 1608026400 | 40.16 | 85.87 | 117.97 | 162.31 | 406.31 -
I have some data where each has a timestamp when is was measured, and not all data points will be necessarily measured at the same time. Time | Value1 | Value2 | Value3 | Value4 2020-12-15 00:05:07 | | 27.6 | | 2020-12-15 00:30:27 | | | 26 | 2020-12-15 01:20:10 | 53.9 | 25.2 | | 2020-12-15 02:09:44 | | 26.4 | | 60.2 2020-12-15 02:43:19 | 33 | 49.2 | | 2020-12-15 03:04:44 | 30.8 | | | 42 2020-12-15 03:21:46 | | 54 | | 2020-12-15 03:47:19 | 52.8 | | 53.3 | 2020-12-15 04:26:20 | | | 27.3 | 2020-12-15 04:45:10 | 37.4 | | | 2020-12-15 05:24:25 | | 42 | | 2020-12-15 05:34:49 | 36.3 | | 41.6 | 2020-12-15 05:36:04 | 24.2 | | | 2020-12-15 06:06:47 | 49.5 | | | 2020-12-15 07:00:07 | | | | 49 2020-12-15 07:59:17 | | 27.6 | | 2020-12-15 08:14:45 | | | 48.1 | 51.8 2020-12-15 08:26:36 | | | 53.3 | 2020-12-15 08:54:23 | 50.6 | | | 2020-12-15 09:46:53 | | | 58.5 | 43.4 2020-12-15 10:25:03 | | | | 36.4 I am trying to obtain the total value (i.e. value1 + value2 + value3 + value4) and since there is no common time interval, come up with an arbitrary one such as one hour. It doesn't need to be exact and one option is to linearize each sample between each of their individual timestamps, but ideally I can do a little better. It has been many, many years, and I recall that least squares regression used to be used for things like this, but I think I would need to the process the entire series for each which I expect would require many polynomials. I've never used R and it might be an option if necessary. Not sure if there is anything baked into PHP which would be great. Any ideas? Thanks Time |Total Value 2020-12-15 00:00:00 | 27.3 2020-12-15 01:00:00 | 48.4 2020-12-15 02:00:00 | 21 2020-12-15 03:00:00 | 22 2020-12-15 04:00:00 | 49 2020-12-15 05:00:00 | 38 2020-12-15 06:00:00 | 49 2020-12-15 07:00:00 | 29 2020-12-15 08:00:00 | 49 2020-12-15 09:00:00 | 46 2020-12-15 10:00:00 | 36
-
A couple suggestions: Display errors ini_set('display_errors', 1); Do a reality check: echo("$from,$subject2,$message2,$headers2"); //Added mail($from,$subject2,$message2,$headers2); I wouldn't expect that spaces need to be in the header, but regardless arrays seem more fullproof. $headers2 = array( 'From' => $to, ); Read https://www.php.net/manual/en/function.mail.php again.
-
Thanks requinix, While I haven't done any research and do not claim that my opinion is sensible, I agree with you as I feel either PHP is being used for a simple website and there is no need to use gc_collect_cycles(), or else either PHP is being used to execute some very memory intensive single page requirements or some continuously run server in which one should fully understand what is going on and tweak the code so that it is not required. However, it would sure be nice to tell PHP to almost do what gc_collect_cycles() does and go through the symbol tables looking for circular references for a given object as a troubleshooting tool.
-
Thanks kicken, I see your point and have no compelling need to code this in the destructor for aesthetics reasons alone. I do, however, think it is important to allow PHP's garbage collector to do its job for a server application, and while I will likely abandon the notion of performing this work in the destructor, am glad I attempted so if for no other reason to learn I wasn't releasing the no longer needed client objects. Turned out my issues were caused by two objects having references back to one another. As overkill, I have set both Client::stream and Stream::client to null before detaching and now the destructor fires, and expect I really only need to set one of them to null. function setClient(StreamParser $stream, AbstractClient $client){ $stream->setClient($client); $storage[$stream] = $client; } // on connection $initialClient = new UnregisteredClient($stream); setClient($stream, $initialClient); // on data -> register $actualClient = new SpecificClient($stream); setClient($stream, $actualClient); // on close $storage->detach($stream);
-
Updating the DB when the server stops is a different need. When a client connects, I add it to a SplObjectStorage object, and if it disconnects, I remove it from that object and and need to perform some other tasks as well. I suppose I could just explicitly perform those other tasks the same time I remove it from the list, but it seemed like using the destructor was a more elegant solution. Maybe not? Regardless, now that I know the destructor isn't being executed, I know there is some other reference to the client and I am not releasing the memory and still need to fix that. While I am surprised that there isn't some function/etc to find existing references to an existing object, at least now I know there isn't any common ones and will stop looking. Thanks for your help.
-
Okay, thanks. For my test script, unsetting $func allows the garbage collector to delete the object in question and thus its destructor is called, but for my real example the destructor isn't being called and therefore some object or function must still be using it. That being said, figuring out where it is still being used is not so easy. I thought that either debug_zval_dump or xdebug_debug_zval might provide a clue, but it doesn't appear to do so. Any other strategies to identify what is still using it?
-
Ah, I need to unset $func! And in my real example, unset the TimerInterface returned by addGatewayClient(). Let me give that a try. Thanks PS. Ended up installing Xdebug. It helps with the recursion and the documentation claims it is "more accurate" because it doesn't pass a variable but doesn't seem to provide more information.
-
Try adding var_dump($key) and var_dump($item) in your loop so you know what you are looking at.
-
$item->Users is an array. Try $item->Users[$key]->UserObject->UserName; PS. Recommend changing your variable names to something other than $1, etc.
-
I thought I was deleting (unset) an object, but when adding a destructor, found it was never being fired. I then used debug_zval_dump() and found that my refcount is 7, and it is my understanding that it must be 3 (more on why I think this later). I searched where I might have left a copy, but couldn't find it. Any recommendations how to do so? I looked for ways to find all references to an object https://www.php.net/manual/en/language.references.spot.php seems to be on topic, but doesn't say much? https://www.php.net/manual/en/features.gc.refcounting-basics.php seems to imply that xdebug_debug_zval() might help, but I haven't installed http://xdebug.org/ and haven't tested yet. https://stackoverflow.com/questions/2893672/is-there-any-way-to-access-all-references-to-given-object doesn't say much After manually searching and not finding exactly what I was looking for, I came across this script. public function addGatewayClient(GatewayClient $client):TimerInterface { return $this->loop->addPeriodicTimer($this->period, function() use($client) { // bla bla bla }); } To verify whether a reference was being created, I wrote the below script. <?php ini_set('display_errors', 1); class MyClass { public function __destruct() { echo('__destruct'.PHP_EOL); } } function getZval($v):string { ob_start(); debug_zval_dump($v); $rs = ob_get_clean(); return str_replace(PHP_EOL, '', $rs); } $obj = new MyClass; echo('create object: '.getZval($obj).PHP_EOL); $objC1 = $obj; echo('save first reference: '.getZval($obj).PHP_EOL); $objC2 = $obj; echo('save second reference: '.getZval($obj).PHP_EOL); // This is the line to comment out $func = function() use($obj) {}; echo('set function: '.getZval($obj).PHP_EOL); unset($objC1); echo('delete first reference: '.getZval($obj).PHP_EOL); unset($objC2); echo('delete second reference: '.getZval($obj).PHP_EOL); unset($obj); echo('Done'.PHP_EOL); If I comment out \\$func = function() use($obj) {};, I see the refcount start at 3, go up to 5 and then back down to 3, then __destruct() being called, and then the script completion "Done". But then when I don't comment the closure function, I see it go up to 6, go down to 4, the script completion "Done", and then __destruct() being called. Guess I can just set the object to be deleted to NULL, but I feel there should be a better way. Any recommendations? On a side note, debug_zval_dump() is more difficult in the real world if there is recursion, and my getZval() function results in a fatal error by exhausting too much memory. I also tried just calling debug_zval_dump(), but it definitely wasn't a good call.
-
I've never dealt with signals before, or more accurately I likely have done so but didn't know I was doing so. Interesting use cases! When I was messing around with this yesterday, got a little worried about my program going rouge and had to kill the process from the command line. Below is the PHP script, my systemctl service, actions I performed, and journalctl output. I have a few questions included in the PHP script as comments and would appreciate your thoughts. Thanks <?php ini_set('display_errors', 1); declare(ticks = 1); //Maybe do less often to improve performance because quick response is not necessary? //The following has no affect. phpinfo shows zend.signal_check off and Zend Signal Handling enabled. Need I call it? //pcntl_async_signals(true); pcntl_signal(SIGTERM, function() { $pid = getmypid(); echo "received SIGTERM. Update DB and kill process $pid\n"; //updateDatabase(); //How should the process be stopped? While it works, journalctl shows "failed state.." Also, do I care about "Unregistered Authentication Agent" in journalctl? posix_kill($pid, SIGKILL); }); // Below script is for testing only and will be replaced with a reactphp loop $x = 0; while (true) { echo "."; sleep(1); //sleep(1) && pcntl_signal_dispatch(); // pcntl_signal_dispatch — Calls signal handlers for pending signals. Why call it? if ($x >= 10) { posix_kill($pid, SIGKILL); } ++$x; } $ cat /usr/lib/systemd/system/pcntl_async_signals.service [Unit] Description=my_pcntl_async_signals After=syslog.target [Service] ExecStart=/usr/bin/php /var/www/testing/pcntl_async_signals.php [Install] WantedBy=multi-user.target $ sudo systemctl start pcntl_async_signals.service $ sudo systemctl stop pcntl_async_signals.service Dec 14 14:04:20 devserver sudo[27683]: michael : TTY=pts/0 ; PWD=/var/www/testing ; USER=root ; COMMAND=/bin/systemctl start pcntl_async_signals.service Dec 14 14:04:20 devserver sudo[27683]: pam_unix(sudo:session): session opened for user root by michael(uid=0) Dec 14 14:04:20 devserver polkitd[766]: Registered Authentication Agent for unix-process:27684:8411203 (system bus name :1.322 [/usr/bin/pkttyagent --notify-fd 5 --fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) Dec 14 14:04:20 devserver systemd[1]: Started my_pcntl_async_signals. Dec 14 14:04:20 devserver sudo[27683]: pam_unix(sudo:session): session closed for user root Dec 14 14:04:20 devserver polkitd[766]: Unregistered Authentication Agent for unix-process:27684:8411203 (system bus name :1.322, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus) Dec 14 14:04:26 devserver influxd[1145]: [httpd] 127.0.0.1 - - [14/Dec/2020:14:04:26 +0000] "POST /write?db=greenbean&precision=s HTTP/1.1" 204 0 "-" "GuzzleHttp/6.5.5 curl/7.29.0 PHP/7.4.12" 46a1b0c0-3e15-11eb-9cdd-0050563b3f69 3262 Dec 14 14:04:26 devserver sudo[27691]: michael : TTY=pts/0 ; PWD=/var/www/testing ; USER=root ; COMMAND=/bin/systemctl stop pcntl_async_signals.service Dec 14 14:04:26 devserver sudo[27691]: pam_unix(sudo:session): session opened for user root by michael(uid=0) Dec 14 14:04:26 devserver polkitd[766]: Registered Authentication Agent for unix-process:27692:8411859 (system bus name :1.324 [/usr/bin/pkttyagent --notify-fd 5 --fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) Dec 14 14:04:26 devserver systemd[1]: Stopping my_pcntl_async_signals... Dec 14 14:04:26 devserver php[27690]: .......received SIGTERM. Update DB and kill process 27690 Dec 14 14:04:26 devserver systemd[1]: pcntl_async_signals.service: main process exited, code=killed, status=9/KILL Dec 14 14:04:26 devserver systemd[1]: Stopped my_pcntl_async_signals. Dec 14 14:04:26 devserver systemd[1]: Unit pcntl_async_signals.service entered failed state. Dec 14 14:04:26 devserver systemd[1]: pcntl_async_signals.service failed. Dec 14 14:04:26 devserver sudo[27691]: pam_unix(sudo:session): session closed for user root Dec 14 14:04:26 devserver polkitd[766]: Unregistered Authentication Agent for unix-process:27692:8411859 (system bus name :1.324, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus)
-
I would like to update the DB when a service ends and thought about doing so in the destructor, but I did not make much progress. Then tried using pcntl_signal(), but also didn't get far. Is doing so possible? Thanks /usr/lib/systemd/system/test123.service [Unit] Description=bla After=syslog.target [Service] ExecStart=/usr/bin/php /var/www/testing/__destruct.php [Install] WantedBy=multi-user.target /var/www/testing/__destruct.php <?php ini_set('display_errors', 1); pcntl_signal(SIGTERM, function() { syslog(LOG_INFO, 'Caught SIGTERM'); die; }); pcntl_signal(SIGHUP, function() { syslog(LOG_INFO, 'Caught SIGHUP'); die; }); pcntl_signal(SIGUSR1, function() { syslog(LOG_INFO, 'Caught SIGUSR1'); die; }); pcntl_signal(SIGINT, function() { syslog(LOG_INFO, 'Caught SIGINT'); die; }); pcntl_signal(SIGABRT , function() { syslog(LOG_INFO, 'Caught SIGABRT '); die; }); /* pcntl_signal(SIGSTOP , function() { syslog(LOG_INFO, 'Caught SIGSTOP '); die; }); */ /* pcntl_signal(SIGKILL , function() { syslog(LOG_INFO, 'Caught SIGKILL '); die; }); */ class Bla { private $bla; public function __construct($bla) { syslog(LOG_INFO, '__construct'); $this->bla = $bla; } public function __destruct() { syslog(LOG_INFO, '__destruct'); } public function start() { $counter=0; $counter2=0; while(true) { $counter++; if($counter>10000000) { $counter2++; $counter=0; syslog(LOG_INFO, '.'); } if($counter2>5) { die('all done!'); } } } } $bla = new Bla('hello'); $bla->start();
-
Thanks requinix, If you vote for Approach 1 and considering the fact that it is complete and working, will stay the course.
-
Not ultra sensitive and I think it is sufficient. Don't fully follow. What I am currently doing is something like the following: APPROACH 1 $token = getJWT(['accountId'=>123, 'originalUserIdWhichProbablyShouldNotBeTrusted'=>321, 'method'=>'getSomeResource', 'args'=>['fu'=>321, 'bar'=>123]]); sendEmail("some HTML <a href='https://myserver.com/$token'>view some resource</a>"); The webserver then redirects to index.php?token=asdfklsad;lhjfgasfljkfh89zhdxcfou8fasdbn5rw3jaksejkefhalsdfasdfasddfSADFASDSDKRJYHAHUVCNAOSDFROASYSDERHFCVOASDFR, I decode the token, and respond as appropriate. It works fine when going to my desktop gmail account, but the links don't work when going to an iphone using the same gmail account. Not sure if the culprit, but thinking it might be due to long URLs. As an alternative, thinking of the following: APPROACH 2: $hash=md5($salt.json_encode(['method'=>'get/Some/Resource', 'args'=>['fu'=>321, 'bar'=>123]])); $token = getJWT(['accountId'=>123, 'originalUserIdWhichProbablyShouldNotBeTrusted'=>321, 'hash'=>$hash]); sendEmail("some HTML <a href='https://myserver.com/get/Some/Resource?token=$token&fu=321&bar=123'>view some resource</a>"); I would then decode the token and ensure that the action requested is the action in the token hash. APPROACH 3: Alternatively, I could save the method/path and arguments in the DB when generating the email and then include the PK in the token. Does my approach 1 and 3 reflect your statement "...you probably don't need to put it into the link anymore. So the token will inherently be identifying both the user and the action"?
-
From a ux perspective, I don't want to make the user first go to some website and then include the JWT in the header, but instead just a single click action.
-
I am using JWT for an API authentication and like them. Previously, I would query both some GUID and the user's ID (which wasn't their PK but a unique key per GUID), but now I just include both the account and user's DB PK in the token. Also, including something regarding the user's permissions, however, I still haven't bought into this approach as I don't know how to deal with changing permissions and still having some JWT with different permissions floating around. I suppose I could save the JWT's timestamp in the DB, but that seems to eliminate the benefit of token expirations... Sorry, back to the question at hand. I now have a need to provide emails with a reduced subset of endpoints to either view some resource or update some status. I don't want to make the user first go to some website and then include the JWT in the header, but instead just a single click action. Problem is now I have their JWT which is effectively their password in some email which isn't ideal, and their is no way to ensure that the specific user was the individual that viewed the resource or performed some action. Then I thought maybe I would make some common low access JWT and use the exact same GET routes as I would do so normally and create some new GET routes to emulate main application POST/PUT/PATCH routes. Before going down that path, I would like to investigate other solutions. Often single use tokens are used to reset passwords and other actions which should only performed once and this is not my need but maybe close. I am thinking of creating a token that includes the actual resource path with URL parameters along with the HTTP method. Since everything is in the token, I wouldn't need a typical REST path to identify the resource but would have a single endpoint to retrieve them. I searched for related information and didn't find anything which makes me concerned I am going down a rabbit hole. Any thoughts on how to implement this? Thanks
-
When should DateTime be injected with DateTimeZone?
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks requinix, Haven't spent much time with time zones before now. When using "now", everything made sense, but was first confused with my results when injecting DateTime with a timestamp. In addition to what you already said, I found another important thing to always do: inject the users time zone into DateTime if they provide a time. While DateTime is smart enough for the math to work without changing the timezone to UTC, I will always convert to UTC right after creating the DateTime and not when saving the data as using "now" doesn't require such. All good and thanks again. <?php ini_set("display_errors", 1); function test($time, $timezone) { $date = new DateTimeImmutable($time); echo "(new DateTimeImmutable('$time'))->format('Y-m-d H:i:s e'):<br>".$date->format('Y-m-d H:i:s e').'<br>'; echo "(new DateTimeImmutable('$time'))->setTimezone(new DateTimeZone('$timezone'))->format('Y-m-d H:i:s e'):<br>".$date->setTimezone(new DateTimeZone($timezone))->format('Y-m-d H:i:s e').'<br>'; $date = new DateTimeImmutable($time, new DateTimeZone($timezone)); echo "(new DateTimeImmutable('$time', new DateTimeZone('$timezone')))->format('Y-m-d H:i:s e'):<br>".$date->format('Y-m-d H:i:s e').'<br>'; echo "(new DateTimeImmutable('$time', new DateTimeZone('$timezone')))->setTimezone(new DateTimeZone('utc'))->format('Y-m-d H:i:s e'):<br>".$date->setTimezone(new DateTimeZone('utc'))->format('Y-m-d H:i:s e').'<br><hr>'; } test("now", "America/Los_Angeles"); test("2020-11-03 00:00:00", "America/Los_Angeles"); test("now", "America/New_York"); test("2020-11-03 00:00:00", "America/New_York"); -
Reading Modbus-tcp registers of Solaredge inverter
NotionCommotion replied to rene's topic in PHP Coding Help
What was the fix? -
Quotes are normally required, however, see https://www.php.net/manual/en/language.types.string.php for details. The only way I would expect things to work find without them is if your code was something like this: define("green", "Some important stuff"); $_SESSION["favcolor"] = green;
-
It is my belief that when storing time in the DB, it should always be at UTC. Agree? My question is whether one should work with DateTimes with a specific time zone or only do so when displaying the time to the user? For example, if I have multiple users which have a timezone string property based on their physical location as well as a datatime property when some event occurred for the given user, and need to implement some logic if the event occurred more than a given duration from the current time, which of the following approaches should be used? $currentTime = new DateTimeImmutable(); $userEventTime = new DateTime($queryResults['theEventField']); if($currentTime->sub(new DateInterval('P10D')) < $userEventTime) { //Display time to the user $displayEventTime = new DateTime('@'.$userEventTime->getTimestamp(), new DateTimeZone($queryResults['userTimeZone']))->format('Y-m-d H:i:sP'); } $currentTime = new DateTimeImmutable('now', new DateTimeZone($queryResults['userTimeZone'])); $userEventTime = new DateTime($queryResults['theEventField'], new DateTimeZone($queryResults['userTimeZone'])); if($currentTime->sub(new DateInterval('P10D')) < $userEventTime) { //Display time to the user $displayEventTime = $userEventTime->format('Y-m-d H:i:sP'); }
-
Cooperative multitasking, promises, and future ticks
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks kicken! I updated my original post before even knowing you commented, however, your advise is 100% relevant. While I wish promises were magical, I unfortunately don't believe so but instead boringly somehow execute a quick loop which constantly checks if anything is ready to perform work. I have some limited experience with it and will focus more on it. Thank you for your example of use. Almost didn't see this, and never knew they were options. Another maybe option I know nothing about is https://www.php.net/manual/en/intro.parallel.php.