timezones now datetimezone php datetime time timezone

now - set timezone php



¿Cómo se muestran las zonas horarias convertidas en una "semana genérica" ​​(de domingo a sábado)? (3)

Estamos construyendo una aplicación de programación en la que un usuario puede establecer su "disponibilidad general" para todas las semanas como la siguiente:

Sunday | Monday | ... | Friday | Saturday

Cuando le pedimos a una persona A en la India que indique su "disponibilidad", le pedimos que seleccione de una lista desplegable de valores algo como esto:

12:00am 12:30am 01:00am ... 11:30pm

Le pedimos que seleccione AMBOS el tiempo "Desde" (inicio) y el tiempo "Hasta" (final).

Lo que GUARDAMOS en la base de datos es SÓLO estos valores (vea el siguiente ejemplo):

user_id avail_day from to 1 Sunday 12:00:00 12:15:00 2 Monday 12:00:00 12:15:00

Entonces, en esencia, se ve como lo siguiente (en su zona horaria LOCAL)

(A) Sunday | Monday | ... | Friday | Saturday ----------------------------------------- | | | | 8:30am to 10:30am

Como información separada, sabemos que ha seleccionado trabajar en el IST (Indian Standard Time), que actualmente es GMT + 5:30 horas, por lo que podemos suponer que los valores que elige son PARA la zona horaria en la que se encuentra actualmente. en.

Ahora, para una persona B en la costa este, que actualmente es GMT - 4 horas (EDT), esta vez sería en realidad

Friday, 23:00:00 to Saturday, 01:00:00

Necesitamos ayuda para descubrir cómo:
(a) convierta el "valor de texto" anterior de la persona A en IST al valor local de la persona EST (tenga en cuenta que solo conocemos el día y las horas de disponibilidad como valores TEXT)
(b) Y, entonces, tenemos que descubrir cómo mostrarlo en una "Semana estándar" que comienza un domingo y termina un sábado. Lo que queremos mostrar debería ser algo como esto:

(B) Sunday | Monday | ... | Friday | Saturday -------------------------------------------------------------- | | | 11:00pm to 12:00am | 12:00am to 1:00am

¿Alguna forma inteligente de convertir (A) en (B)?

El código de Artefacto se convierte en una función genérica (Revisión 2)

// This function should be used relative to a "from_date" // The $from_timebegin and $from_timeend MUST be for the same day, not rolling over to the next function shift_timezones_onweek3($from_timezone, $from_date, $from_timebegin, $from_timeend, $to_timezone) { $tz1 = new DateTimezone($from_timezone); $datetime1 = new DateTime("$from_date $from_timebegin", $tz1); $datetime2 = new DateTime("$from_date $from_timeend", $tz1); $interval = $datetime1->diff($datetime2); $indiaAvail = array( array($datetime1, $datetime2) ); $tz2 = new DateTimezone($to_timezone); //convert periods: $times = array_map( function (array $p) use ($tz2) { $res = array(); foreach ($p as $d) { $res[] = $d->setTimezone($tz2); } return $res; }, $indiaAvail ); $res = array(); foreach ($times as $t) { $t1 = reset($t); $t2 = next($t); if ($t1->format("d") == $t2->format("d")) { $res[$t1->format("l")][] = $t1->format("g:ia") . " to ". $t2->format("g:ia"); } else { $res[$t1->format("l")][] = $t1->format("g:ia") . " to 11:59pm"; $res[$t2->format("l")][] = "12:00am to ". $t2->format("g:ia"); } } return $res; }


Qué tal esto:

  • Pida al usuario que proporcione su zona horaria (tal vez incluso pueda detectarla obteniendo la ubicación del usuario según la dirección IP, pero el usuario aún puede querer cambiarla)
  • Convierta el tiempo proporcionado al tiempo de su servidor web y guárdelo.
  • Al mostrar la hora, convertir a la zona horaria del usuario de visualización.

El paquete Pear :: Date puede ayudarlo a hacer esto:
http://www.go4expert.com/forums/showthread.php?t=3494

Espero que esto ayude, Manuel


Tu pregunta no tiene sentido teniendo en cuenta los días de semana en el vacío. Estos días de la semana deben ser días reales, porque las reglas de conversión de tiempo cambian a lo largo del año (DST) y a través de los años (los políticos a veces cambian las zonas horarias y / o la fecha en que comienza / finaliza el horario de verano).

Dicho esto, supongamos que tiene un plan de disponibilidad semanal para la primera semana de agosto, definido aquí como la semana del 1 de agosto al 7 de agosto de 2010:

<?php $tz1 = new DateTimezone("Asia/Calcutta"); $indiaAvail = array( new DatePeriod(new DateTime("2010-08-01 10:00:00", $tz1), new DateInterval("PT2H15M"), 1), new DatePeriod(new DateTime("2010-08-07 03:00:00", $tz1), new DateInterval("PT8H"), 1), ); $tz2 = new DateTimezone("America/New_York"); //convert periods: $times = array_map( function (DatePeriod $p) use ($tz2) { $res = array(); foreach ($p as $d) { $res[] = $d->setTimezone($tz2); } return $res; }, $indiaAvail ); $res = array(); foreach ($times as $t) { $t1 = reset($t); $t2 = next($t); if ($t1->format("d") == $t2->format("d")) { $res[$t1->format("l")][] = $t1->format("g:ia") . " to ". $t2->format("g:ia"); } else { $res[$t1->format("l")][] = $t1->format("g:ia") . " to 11:59pm"; $res[$t2->format("l")][] = "12:00am to ". $t2->format("g:ia"); } } print_r($res);

da

Array ( [Sunday] => Array ( [0] => 12:30am to 2:45am ) [Friday] => Array ( [0] => 5:30pm to 11:59pm ) [Saturday] => Array ( [0] => 12:00am to 1:30am ) )

Esto puede colocar en la misma canasta los días de la semana que son días diferentes, pero obviamente no hay forma de evitarlo sin indicar explícitamente el día (o agregar algo como "Sábado (semana después)" y "Sábado (semana anterior)". Esto aparece para ser lo que quieras, sin embargo.


Use la clase DateTime incorporada de PHP para hacer conversiones de zona horaria. Guarde los datos en UTC en la base de datos. Cuando muestre su horario de semana estándar, use la zona horaria local. Para manejar ± 23 horas de diferencias de zona horaria, tendrá que consultar 9 días (± 1 días) desde el DB antes de la conversión.

Editar: para convertir las horas a la hora local del usuario actual, necesita obtener la zona horaria de cada evento. Únase a los eventos programados a la información del usuario para el usuario que realizó el evento. De esta forma, tendrás la zona horaria desde la que convertir a la zona horaria del usuario.

El siguiente pseudoish PHP mostrará:

$usersTZ = new DateTimeZone(''EDT''); $now = new DateTime("now", $usersTZ); $today = $now->format("Y-m-d"); $sql = "SELECT A.date, A.start, A.end, B.tz FROM schedule A JOIN users B ON (schedule.user_id = users.user_id) WHERE A.date BETWEEN ''$sunday_minus_1_day'' AND ''$saturday_plus_1_day'' ORDER BY A.date, A.start"; foreach ($db->dothequery($sql) as $event) { $eventTZ = new DateTimeZone($event[''tz'']); $eventStartDate = new DateTime("$today {$event[''start'']}", $eventTZ); $eventStartDate->setTimeZone($usersTZ); $eventEndDate = /* do the same for the end date */ if ($eventStartDate->format("Y-m-d") != $eventEndDate->format("Y-m-d")) { /* create 2 events */ } else { /* save the event to list of events with the new start and end times */ } } /* sort events, their order may be different now */

Por supuesto, todo sería mucho más simple si pudieras guardar los tiempos de inicio y finalización con TZ en el DB y dejar que DB haga todo el trabajo por ti.