{"id":61,"date":"2015-10-12T21:06:06","date_gmt":"2015-10-12T19:06:06","guid":{"rendered":"http:\/\/lab.fawno.com\/?p=61"},"modified":"2022-03-07T01:08:11","modified_gmt":"2022-03-07T00:08:11","slug":"","status":"publish","type":"post","link":"https:\/\/lab.fawno.com\/en\/2015\/10\/12\/programar-una-espera-hasta-un-momento-determinado\/","title":{"rendered":"","raw":""},"content":{"rendered":"","protected":false,"raw":""},"excerpt":{"rendered":"","protected":false,"raw":""},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"IBM Plex Sans,","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_typography_data":[],"_editorskit_blocks_typography":"","_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_es_post_content":"\n

En ocasiones necesitamos que un script realice una tarea determinada cada cierto tiempo o a partir de un momento (fecha\/hora) determinados.<\/p>\n\n\n\n

En linux es f\u00e1cil realizar esto mediante cron<\/a>, sin embargo el programador de tareas de Windows es m\u00e1s farragoso de configurar para estos menesteres. Adem\u00e1s puede que no nos interese\/guste que el script est\u00e9 continuamente arrancando\/parando.<\/p>\n\n\n\n

Hasta ahora realizaba este tipo de bucles para estas tareas:<\/p>\n\n\n\n

do {\n  \/\/ anything\n  sleep($interval);\n} while (true);<\/pre>\n\n\n\n

En este caso es un bucle infinito, pero eso ahora no importa, el sleep($interval);<\/code> (l\u00ednea 3) es el tiempo de espera entre dos ejecuciones del bucle... pero podemos encontrarnos con que si $interval = 300;<\/code> (segundos) luego a la hora de la verdad se nos ir\u00e1 a\u00f1adiendo alg\u00fan segundo que otro entre las ejecuciones del bucle... y esto puede no importar o todo lo contrario.<\/p>\n\n\n\n

Ayer encontr\u00e9 una funci\u00f3n maravillosa: time_sleep_until()<\/a><\/p>\n\n\n\n

Tal y como dice la documentaci\u00f3n esta funci\u00f3n dejar\u00e1 el script en pausa hasta que llegue el momento determinado en la funci\u00f3n:<\/p>\n\n\n\n

$next = time();\ndo {\n  \/\/ anything\n  $next = strtotime('+5min', $next);\n  time_sleep_until($next);\n} while (true);<\/pre>\n\n\n\n

El problema es que seg\u00fan parece esta funci\u00f3n trabaja en microsegundos<\/a>, y guarda el valor con un entero de 32 bits, lo que nos da un m\u00e1ximo de 2^32 microsegundos, unos 4295 segundos (1 hora, 11 minutos y 35 segundos). Para solventar esto se me ha ocurrido la misma soluci\u00f3n que la que apunta \"purdue\" en la documentaci\u00f3n:<\/p>\n\n\n\n

while (time() < $next) time_sleep_until($next);<\/pre>\n\n\n\n

Y bueno, juntando algunas cosas m\u00e1s podemos hacer que el script realice una tarea cada cierto tiempo durante unas horas al d\u00eda:<\/p>\n\n\n\n

&lt;?php\n  $runfile = 'runfile.log';\n  $interval = '5min';\n  $start = '18:00:00';\n  $end = '22:00:00';\n\n  $time_start = strtotime($start);\n  $time_end = strtotime($end);\n  $next = $time_start;\n\n  do {\n    file_put_contents($runfile, date('Y-m-d H:i:s')); \n    if ($time_end &lt;= strtotime('+1sec')) {\n      $time_start = strtotime('+1day', $time_start);\n      $time_end = strtotime('+1day', $time_end);\n      $next = $time_start;\n    }\n    while ($next &lt;= strtotime('+1sec')) $next = strtotime($interval, $next);\n    echo date('Y-m-d H:i:s', $next), HT, 'next', \"\\n\";\n    while (time() &lt; $next) time_sleep_until($next);\n    \/\/ anything\n  } while (file_exists($runfile));<\/pre>\n\n\n\n

En el ejemplo completo he hecho que el bucle se ejecute siempre y cuando exista un fichero \"runfile\", cuando lo borremos el bucle se ejecutar\u00e1 una \u00faltima vez y terminara.<\/p>\n","_es_post_name":"programar-una-espera-hasta-un-momento-determinado","_es_post_excerpt":"","_es_post_title":"Programar una espera hasta un momento determinado","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"en","footnotes":""},"categories":[5,3],"tags":[6],"class_list":["post-61","post","type-post","status-publish","format-standard","hentry","category-php","category-tips","tag-php"],"ninja_gutenberg_blocks_featured_media_urls":{"thumbnail":"","ninja_gutenberg_blocks_landscape_large":"","ninja_gutenberg_blocks_portrait_large":"","ninja_gutenberg_blocks_square_large":"","ninja_gutenberg_blocks_landscape":"","ninja_gutenberg_blocks_portrait":"","ninja_gutenberg_blocks_square":"","full":""},"_links":{"self":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":86,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"predecessor-version":[{"id":1850,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/posts\/61\/revisions\/1850"}],"wp:attachment":[{"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lab.fawno.com\/en\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}