Laravel aplicación de procesamiento para resolver el problema de las ideas a través de zonas horarias

Los lectores de

  • Nos laravel tenemos algunos desarrolladores experimentados

fondo

En muchos escenarios de aplicación, tales como información de vuelo, campo transfronteriza de comercio electrónico, a través de zonas horarias es un problema en el desarrollo se puedan encontrar. Para proveedor transfronterizo de electricidad, por ejemplo, el escenario más común es cuando las empresas de acceso a los conocimientos previos de gestión de datos fin, espero que por las órdenes hora GMT, los clientes de Estados Unidos y el Reino Unido cuándo se muestra el cliente podrá comprar también le gustaría ver en su próximo pedido hora local. Otro escenario común es que el fondo de gestión de usuarios no sólo de China, sino también en otros países puede estar en diferentes zonas horarias, la conmutación dinámica zona horaria fondo de gestión también necesita apoyo. Con el fin de proporcionar una solución más general a este pensamiento problema en distintas zonas horarias, el campo transfronteriza papel del comercio electrónico, por ejemplo, una lista de varios escenarios comunes, y discutir el diseño y la implementación de diferentes escenarios específicos para cubrir todos estos escenarios.

escenarios

  • Gestión fondo - un pre-set administrador de zona horaria, soportes zona de conmutación
  • Mall - el navegador del usuario para mostrar localizada en función del tiempo
  • la zona horaria del usuario registrado - cuando se juzga de acuerdo con el navegador cuando un área de registro de usuarios
  • Tiempo contenido del mensaje de zona

apoyo de fondo zona de conmutación dinámica de gestión

referencia efecto
referencia efecto

Laravel se apoya mediante la modificación config('app.timezone')cambiantes zonas de tiempo, el acceso a toda la gama de aplicaciones dentro del período de tiempo se considera que es la zona horaria. Sin embargo, esta práctica función no resuelve nuestros problemas, sino el tiempo es la base de datos, hora local, cuando los cambios de configuración, para obtener la hora local es incorrecta. Por ejemplo, la zona horaria Asia/Shanghai, en 2020-04-01 08:00:00la creación de un registro, created_atel valor de 2020-04-01 08:00:00la cambio de zona horaria Asia/Tokyo, created_atel valor no cambiará, aún así obtener 2020-04-01 08:00:00el derecho debe ser 2020-04-01 09:00:00. Por lo tanto, la función propia configuración de zona horaria laravel es adecuado para aplicaciones no sólo el caso cuando la zona de conmutación dinámica, una vez que empiece a usar no al cambio, de lo contrario el tiempo es malo.

Para apoyar la zona de conmutación dinámica, hay que hacer los siguientes tres aspectos de la reforma:

  1. El tiempo siempre se almacena en la base de datos como la hora UTC;
  2. El laravel Modelcuando la obtención de la hora local, de acuerdo con el tiempo UTC debe ser config('app.timezone')calculado dinámicamente;
  3. información de zona horaria lee de la base de datos de configuración, dispuestas config('app.timezone')para soportar la zona de conmutación dinámica;

El tiempo siempre se almacena en la base de datos como la hora UTC

En general, siempre y cuando el acuerdo created_at, updated_atsalvo que la hora UTC en la línea, pero el uso de muchos sistemas created_at, updated_atson hora local, con el fin de evitar confusiones en la semántica. El uso original del campo de tiempo aún conservan la semántica, hora local, el aumento solos created_at_gmt, updated_at_gmtutilizado para representar la hora UTC y aceptado todas las necesidades expresadas como campo de hora UTC debe terminar con _gmt .

campo de hora en MySQL se almacena como un formato de fecha y hora, o se almacena como una marca de tiempo, que es un problema que requiere atención, fecha y hora recomendada de 2038 para evitar el problema de la marca de tiempo.

capa del modelo a utilizar el siguiente rasgo puede abordar directamente el problema de conseguir el sistema GMT creación y actualización de la hora /:

<?php
namespace App\Models\Traits;

trait CustomTimestamps {
    /**
     * @param mixed $value
     * @return mixed
     */
    public function setCreatedAt($value)
    {
        $gmt_field = static::CREATED_AT . '_gmt';
        $this->{$gmt_field} = $value;
        return parent::setCreatedAt($value);
    }
    /**
     * @param mixed $value
     * @return mixed
     */
    public function setUpdatedAt($value)
    {
        $gmt_field = static::UPDATED_AT . '_gmt';
        $this->{$gmt_field} = $value;
        return parent::setUpdatedAt($value);
    }
    /**
     * 直接返回原始数据。
     *
     * @remark 如果套一层Carbon,默认使用的是本地时区
     * 就算明确改成UTC,在toArray的时候会出现Carbon对象转换成JSON的问题,需要定义一个toArray返回正确的数据
     * 这里直接简单处理,返回原始数据,可考虑用toArray优化。
     *
     * https://github.com/laravel/framework/issues/16083
     */
    public function getCreatedAtGmtAttribute()
    {
        return $this->attributes['created_at_gmt'];
    }
    /**
     * *_gmt字段存储到数据库固定使用UTC时间
     */
    public function setCreatedAtGmtAttribute($value)
    {
        $this->attributes['created_at_gmt'] = (new Carbon($value))->timezone('UTC')->toDateTimeString();
    }
    public function getUpdatedAtGmtAttribute()
    {
        return $this->attributes['updated_at_gmt'];
    }
    /**
     * *_gmt字段存储到数据库固定使用UTC时间
     */
    public function setUpdatedAtGmtAttribute($value)
    {
        $this->attributes['updated_at_gmt'] = (new Carbon($value))->timezone('UTC')->toDateTimeString();
    }
}

Modelo en la adquisición de la hora local, la hora UTC y debe estar de acuerdo con config('app.timezone')cálculo dinámico

created_atY updated_atsi bien preservados, pero en realidad menos de la hora local, según las necesidades created_at_gmty updated_at_gmtcalcula con la zona horaria actual. Directamente a CustomTimestampsaumentar el atributo dinámico correspondiente a lograr esto:

    /**
     * 实际的本地时间,根据时区动态计算,不使用直接存储的时间
     */
    public function getCreatedAtAttribute()
    {
        $postDate = new Carbon($this->attributes['created_at_gmt'], 'UTC');
        return $postDate->tz(config('app.timezone'))->toDateTimeString();
    }
    public function getUpdatedAtAttribute()
    {  
        $postModified = new Carbon($this->attributes['updated_at_gmt'], 'UTC');
        return $postModified->tz(config('app.timezone'))->toDateTimeString();
    }

información de zona horaria lee de la base de datos de configuración, dispuestas config('app.timezone')para soportar la zona de conmutación dinámica;

configuración de zona horaria predeterminada laravel es manual. Para apoyar la zona de conmutación dinámica, es necesario configurar la tabla de base de datos (suponiendo que la tabla de configuración elementos con nombre options, correspondiente Modela Option) el aumento timezonedel elemento de configuración. En la fase de inicialización, se lee en el elemento de configuración, para poner config('app.timezone')valores y por el date_default_timezone_setcambio de zona.

Hay un punto importante de la nota: bootel escenario y no debe leerse desde la tabla de configuración de caché generada directamente de la base de datos, con el fin de evitar una situación - Laravelpor la inicialización de php artisan migratela migración cuadro de ejecución, esta tabla el tiempo no ha creado los elementos de configuración, bootvaya a leer la configuración de base de datos debe ser comunicado a la tabla de la base no se puede encontrar y hacer que la aplicación se bloquee.

es la siguiente AppServiceProviderrealiza boot, la zona de tiempo de la muestra código de inicialización:

// app/Providers/AppServiceProvider.php 
<?php
        
namespace App\Providers;
use App\Models\Option;
class AppServiceProvider extends ServiceProvider
{ 
    public function boot() 
    {
        // 一定要从从缓存中读取配置,1个是性能问题,1个是防止php artisan migrate的问题
        // Option::fromPreCache()为自定义函数,见Option的代码
        $store = Option::fromPreCache();
        if ($store->get('timezone', null)) {
            $timeZone = $store->get('timezone');
            config(['app.timezone' => $timeZone]);
            // 防止$timeZone值无效导致应用挂掉
            @date_default_timezone_set($timeZone);
        }
    }
}

El código de tecla Opción Modelo:

// app/Models/Option.php
<?php  
        
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Schema;
use Cache;
use Log;

class Option extends Model {
    //...省略其他代码
     const PRE_CACHE_KEY = 'options-pre-cache';
    /**
     * 从预生成的缓存读取配置
     *
     * @warning 注意没有缓存的话,在生成缓存之前,要判断表是否存在,否则创建新应用时,使用php artisan migrate会有问题
     */
    public static function fromPreCache()
    {
        if (!Cache::has(static::PRE_CACHE_KEY)) {
            static::savePreCache();
        }
        return collect(Cache::get(static::PRE_CACHE_KEY, []));
    }
    /**
     * 保存配置到预生成的缓存
     */
    public static function savePreCache()
    {
        // 判断表存在是必要的
        if (!Schema::hasTable('options')) {
            Log::warning('options table is not found in wordpress');
            return;
        }
        Cache::forever(static::PRE_CACHE_KEY, Option::where('name', 'timezone')->get());
    }
}

Después de estos tratamientos posteriores, cuando el fondo de gestión puede soportar la conmutación dinámica de la zona.

Mall - el navegador del usuario para mostrar localizada en función del tiempo

Podemos utilizar el momento de abordar esta cuestión de manera sucinta:

   <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.14/moment-timezone-with-data.min.js">

Cabe señalar tres puntos: el primer punto es el paquete momento-zona horaria-con-datos con referencia a los datos localizados, la realización de moment.tz.guess () puede ser dado cuando hay datos no localizada; segundo es este paquete de dos un poco de espacio ocupado por una grande (casi 50 mil), para examinar el tamaño de la operación sensible directamente con los nativos JS.

entrada directa hora UTC en la prueba de la consola del navegador, hora local de salida:

moment.utc('2020-04-01 00:00:02').tz(moment.tz.guess()).format('YYYY-MM-DD HH:mm:ss')

exportación

"2020-04-01 08:00:02"

la zona horaria del usuario registrado

Adquiere la zona de registro de usuario, hay dos métodos, uno es a través de los jueces de navegador, uno está determinado por IP. A juzgar por el navegador más fácil y precisa. El método que aquí se presenta única sentencia navegador.
Para los usuarios registrados para agregar un campos de formulario ocultos:

<input type="hidden" name="timezone" value="UTC" id="tz"/>

Entonces, como un ídem, en el momento de su presentación, usando el momento obtener paquete de información de zona horaria, rellene los campos ocultos

var tz = moment.tz.guess();
$('#tz').val(tz);

Laravel almacenado correspondiente a la parte trasera del campo de la base de datos puede ser, porque es relativamente contenidos básicos comunes aquí no se ha iniciado.

Tiempo contenido del mensaje de zona

Al enviar un mensaje, sobre todo a los usuarios no registrados cuando, de hecho, es la falta de información se utiliza para determinar la zona horaria. Por lo tanto, para mostrar la hora, tenga en cuenta las siguientes estrategias

  1. La identificación automática almacenado cuando el usuario opera la zona de zona de tiempo de usuario
  2. Utilizar el fondo ordenación de las zonas mismo tiempo
  3. El uso directo de tiempo UTC

Además, no es el tipo de servicio que se juzga de acuerdo a la zona horaria del destinatario del correo electrónico, pero para uso general, no hay necesidad de uso.

material de referencia

La gestión de la zona horaria del usuario
Almacenamiento de una Fecha Hora una Base de datos
laravel cómo hacer frente a una zona horaria diferente es
la razón por la base de datos de WordPress guarda post_date y post_date_gmt dos veces
Auto Detect una zona horaria con JavaScript
laravel cómo configurar la zona horaria de carbono
cómo actualizar laravel Modelo en el tiempo en el campo de zona horaria
formato momento fecha en una zona horaria específica

Supongo que te gusta

Origin www.cnblogs.com/pheye/p/12650934.html
Recomendado
Clasificación