obtener formato fecha espaƱol actual php date intervals iso8601

formato - Analice y cree ISO 8601 Intervalos de fecha y hora, como PT15M en PHP



string to date php (5)

strtotime no funcionará directamente con el formato ISO 8601 (por ejemplo, P1Y1DT1S), pero el formato que sí comprende (1Year1Day1Second) no está demasiado lejos, sería una conversión bastante sencilla. (un poco "hacky" ... pero eso es PHP para ti).

Gracias Lee, no sabía que strtotime aceptó este formato. Esta fue la parte faltante de mi rompecabezas. Quizás mis funciones puedan completar tu respuesta.

function parse_duration($iso_duration, $allow_negative = true){ // Parse duration parts $matches = array(); preg_match(''/^(-|)?P([0-9]+Y|)?([0-9]+M|)?([0-9]+D|)?T?([0-9]+H|)?([0-9]+M|)?([0-9]+S|)?$/'', $iso_duration, $matches); if(!empty($matches)){ // Strip all but digits and - foreach($matches as &$match){ $match = preg_replace(''/((?!([0-9]|-)).)*/'', '''', $match); } // Fetch min/plus symbol $result[''symbol''] = ($matches[1] == ''-'') ? $matches[1] : ''+''; // May be needed for actions outside this function. // Fetch duration parts $m = ($allow_negative) ? $matches[1] : ''''; $result[''year''] = intval($m.$matches[2]); $result[''month''] = intval($m.$matches[3]); $result[''day''] = intval($m.$matches[4]); $result[''hour''] = intval($m.$matches[5]); $result[''minute''] = intval($m.$matches[6]); $result[''second''] = intval($m.$matches[7]); return $result; } else{ return false; } }

La función también soporta formatos negativos. -P10Y9MT7M5S devolverá una matriz como: [año] => -10 [mes] => -9 [día] => 0 [hora] => 0 [minuto] => -7 [segundo] => -5 Si esto No se desea el comportamiento pase falso como segundo parámetro. De esta manera la función siempre devolverá valores positivos. El símbolo min / plus seguirá estando disponible en la tecla de resultado [''símbolo''].

Y una pequeña actualización: esta función usa la primera función para obtener la cantidad total de segundos.

function get_duration_seconds($iso_duration){ // Get duration parts $duration = parse_duration($iso_duration, false); if($duration){ extract($duration); $dparam = $symbol; // plus/min symbol $dparam .= (!empty($year)) ? $year . ''Year'' : ''''; $dparam .= (!empty($month)) ? $month . ''Month'' : ''''; $dparam .= (!empty($day)) ? $day . ''Day'' : ''''; $dparam .= (!empty($hour)) ? $hour . ''Hour'' : ''''; $dparam .= (!empty($minute)) ? $minute . ''Minute'' : ''''; $dparam .= (!empty($second)) ? $second . ''Second'' : ''''; $date = ''19700101UTC''; return strtotime($date.$dparam) - strtotime($date); } else{ // Not a valid iso duration return false; } } $foo = ''-P1DT1S''; echo get_duration_seconds($foo); // Output -86399 $bar = ''P1DT1S''; echo get_duration_seconds($bar); // Output 86401

Una biblioteca y un servicio web que estoy utilizando comunican intervalos de tiempo en formato ISO 8601: PnYnMnDTnHnMnS . Quiero convertir tales formatos a segundos. Y viceversa. Los segundos son mucho más fáciles de calcular con.

Los valores de intervalo de ejemplo son:

  • PT1M o PT60S (1 minuto)
  • PT1H, PT60M o PT3600S (1 hora)

Necesito dos funciones: analizar estos valores en segundos: iso8601_interval_to_seconds() y de segundos en dichos intervalos: iso8601_interval_from_seconds() .

El último es bastante simple, porque se podría hacer como `" PT {$ segundos} S ", solo pase los segundos, todo el tiempo. ¿Quizás esto se puede hacer mejor con un analizador que cambia a H (hora) o M (minuto)?

El primero es más difícil, pero ¿quizás hay un truco con uno de los muchos convertidores de cadena a fecha en PHP? Me encantaría aprender a usar esa función para analizar los intervalos. O aprender una alternativa.


Lo que estás buscando es DateTime :: diff

El objeto DateInterval que representa la diferencia entre las dos fechas o FALSE en caso de error, como se ilustra a continuación:

$datetime1 = new DateTime(''2009-10-11''); $datetime2 = new DateTime(''2009-10-13''); $interval = $datetime1->diff($datetime2); echo $interval->format(''%R%d days'');

Solo usa segundos en lugar de fechas.

Esto es de http://www.php.net/manual/en/datetime.diff.php

Para obtener una referencia a DateInterval, visite http://www.php.net/manual/en/class.dateinterval.php


Parece que DateInterval PHP 5.3 soporta esto.

Si no puede usar 5.3, supongo que cualquier función de conversión sabría cuántos segundos hay en un año, un mes, un día, una hora y un minuto. Luego, al convertir de segundos, se dividiría en ese orden, tomando cada vez el módulo de la operación anterior, hasta que solo queden <60 segundos. Al convertir desde una representación de intervalo ISO 8601, debe ser trivial analizar la cadena y multiplicar cada elemento encontrado en consecuencia.


Tenga en cuenta que la conversión de duraciones que contienen Días, Meses y / o Años en una duración como segundos no se puede hacer con precisión sin conocer la fecha / hora de inicio real.

Por ejemplo

1 SEP 2010: +P1M2D means +2764800 seconds 1 OCT 2010: +P1M2D means +2851200 seconds

Eso es porque septiembre tiene 30 días y octubre tiene 31 días. El mismo problema ocurre con la conversión de intervalos de Año, debido a los años bisiestos y los segundos saltos. Los años bisiestos también introducen una mayor complejidad en la conversión del mes, ya que febrero es un día más largo en años bisiestos que de otra manera. Los días son problemáticos en áreas donde se practica el horario de verano: un período de un día que se produce durante la transición de horario de verano, en realidad es 1 hora más de lo que sería de otra manera.

Todo lo que se dice: puede, por supuesto, comprimir los valores que contienen solo Horas, Minutos y Segundos en valores que solo contienen Segundos. Le sugiero que cree un analizador simple para hacer el trabajo (o quizás considere una expresión regular).

Solo ten en cuenta las trampas descritas anteriormente: allí hay dragones. Si tiene la intención de lidiar con Días, Meses y / o Años, necesita usar uno de los mecanismos incorporados para hacer las cuentas por usted en el contexto de una fecha / hora conocida. Como han mencionado otros: la clase DateInterval, en combinación con las funciones proporcionadas en la clase DateTime, es probablemente la forma más intuitiva de lidiar con esto. Pero eso solo está disponible en PHP versión 5.3.0 o superior.

Si tienes que trabajar con menos de v5.3.0, puedes intentar construir algo alrededor de esta pequeña joya:

$startDateTime = ''19700101UTC''; $duration = strtotime( $startDateTime.''+1Year1Day1Second'' ) - strtotime($startDateTime); print("Duration in Seconds: $duration");

strtotime no funcionará directamente con el formato ISO 8601 (por ejemplo, P1Y1DT1S ), pero el formato que comprende ( 1Year1Day1Second ) no está demasiado lejos, sería una conversión bastante sencilla. (un poco "hacky" ... pero eso es PHP para ti).

¡buena suerte!


function parsePTTime($pt_time) { $string = str_replace(''PT'', '''', $pt_time); $string = str_replace(''H'', ''Hour'', $string); $string = str_replace(''M'', ''Minute'', $string); $string = str_replace(''S'', ''Second'', $string); $startDateTime = ''19700101UTC''; $seconds = strtotime($startDateTime . ''+'' . $string) - strtotime($startDateTime); return $seconds; }

Pruebas:

PT1H - OK PT23M - OK PT45S - OK PT1H23M - OK PT1H45S - OK PT23M45S - OK PT1H23M45S - OK