【问题标题】:Codeigniter, timezone_menu and date_default_timezone_setCodeigniter、timezone_menu 和 date_default_timezone_set
【发布时间】:2011-07-09 21:59:30
【问题描述】:

我使用 Codeigniters timezone_menu,它给出了时区的 drop down box,我想知道我们应该如何通过 PHP 使用这些时区 date_default_timezone_set

codeigniters 时区的一个例子是UP1。但是,您不能将它与 PHP date_default_timezone_set 一起使用,因为它接收的字符串应该类似于 Europe/Berlin

问题是,有没有办法将 codeigniter 时区字符串转换为 date_default_timezone_set 可以接受的 PHP 字符串?

【问题讨论】:

  • 问题是,如果 codeigniter 的日期助手在预期上下文中没有用处,为什么还要提供该组值?
  • 根据文档,Codeigniter 不建议设置date_default_timezone_set()。这正是我的问题。我认为最好在 php 的原生日期函数或 Codeigniter 之间进行选择。我正在做出决定(虽然到目前为止我一直使用 Codeigniter)

标签: php codeigniter timezone


【解决方案1】:

您可以在 gmt_to_local() 函数中使用时区偏移的值,例如:

//set the time offset based on the users timezone settings
$timezone = 'UM7';

$offset = timezones($timezone);
$servertime = time();

$mytime = gmt_to_local($servertime,$offset);

$time = date("M d, Y h:i A", $mytime);

//example result
//Dec 22, 2011 04:18 PM

【讨论】:

    【解决方案2】:

    Codeigniter 会返回时区参考,可与 timezones() 一起使用以获取时间差异,并从中计算时间。

    【讨论】:

      【解决方案3】:

      以下对我有用:

      // Example - timezones is part of the date helper function
      // You obviously wouldn't echo it out, you would pass it in to 
      // set default timezone function in PHP based on the posted data from 
      // the dropdown
      echo timezone_by_offset(timezones('UM5')); // ouputs 'America/Porto_Acre' which is (-5)
      
      // And the function
      function timezone_by_offset($offset) {
          $offset = ($offset+1) * 60 * 60;
          $abbrarray = timezone_abbreviations_list();
      
          foreach ($abbrarray as $abbr) {
              foreach ($abbr as $city) {
                  if ($city['offset'] == $offset) { 
                      echo($city['timezone_id']);
                      return true;
                  }
              }
          }
          echo "UTC";
          return false;
      } 
      

      编辑 原始函数不排除 DST 偏移量。 timezone_abbreviations_list() 为 DST 标记为 true 的时区列出 2x,例如 Tasmania 出现在 +11 和 +10 之下。因此,如果 DST == TRUE,请忽略它作为退货清单的一部分。

      //-- Function -------------------------------------------------------------------
      function timezone_by_offset($offset) {
          $abbrarray = timezone_abbreviations_list();
          $offset = $offset * 60 * 60;
      
          foreach ($abbrarray as $abbr) {
              foreach ($abbr as $city) {
                  if ($city['offset'] == $offset && $city['dst'] == FALSE) { 
                      return $city['timezone_id'];                                
                  }
              }
          }
          return 'UTC'; // any default value you wish
      }
      

      一些例子:

      //-- Test Cases -------------------------------------------------------------------
      echo timezone_by_offset(-12) . '<br/>';  
      echo (date_default_timezone_set(timezone_by_offset(-12)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
      // Etc/GMT+12
      // Valid 
      
      echo timezone_by_offset(-10) . '<br/>';  
      echo (date_default_timezone_set(timezone_by_offset(-10)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
      // America/Anchorage
      // Valid
      
      echo timezone_by_offset(-8) . '<br/>';  
      echo (date_default_timezone_set(timezone_by_offset(-8)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
      // Etc/GMT+8
      // Valid        
      
      echo timezone_by_offset(6) . '<br/>';  
      echo (date_default_timezone_set(timezone_by_offset(6)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
      // Asia/Aqtobe
      // Valid        
      
      echo timezone_by_offset(7) . '<br/>';  
      echo (date_default_timezone_set(timezone_by_offset(7)) == TRUE ? 'Valid' : 'Not Valid'). '<br/>'; 
      // Indian/Christmas
      // Valid
      

      【讨论】:

      • 好功能-好像可以用,为什么开头默认加1到$offset?
      • 我应该提到,我是手动输入日光差异。如果 DST = 1,+1 * 60^2 应该针对 $city 偏移量。如果需要,我可以将该函数重写为另一个答案。
      • @Chirs - 我很想知道您将如何处理 DST。这是我必须将 DST 传递给函数的手动操作,还是可以通过 timezone_abbreviations_list 以某种方式解决?
      • @Chris - 太棒了。谢谢!我不知道timezone_abbreviations_list 为有夏令时的时区存储了两次。
      • @Abs 没问题,希望对您有所帮助。
      【解决方案4】:

      您可以使用timezones() 获取U(M|P)x 值之一的UTC 偏移量。

      $offset = timezones('UP1'); // don't know the exact format returned but should be something like 1 or '+01:00'
      

      从这一点开始,我认为唯一的方法是在偏移量和 PHP 时区之间进行某种自定义映射。您可以使用Etc/GMT(+|-)x 时区,但问题在于它们不包含任何 DST 转换信息。

      一般的问题是,UTC 偏移量实际上映射到许多不同的时区,例如UP1 ((UTC + 1:00) 柏林、布鲁塞尔、哥本哈根、马德里、巴黎、罗马) 映射到 Europe/BerlinEurope/BrusselsEurope/CopenhagenEurope/Madrid、@987654330 @, Europe/Rome 也可以以 Africa/Luanda 为例。由于在这些时区中的某些时区可能不会发生 DST 转换,事情现在变得任意复杂。

      如果你不需要 DST 东西,timezones() 函数的返回值和Etc/GMT(+|-)x 时区之间的映射应该没问题,否则你根本不能使用 Codeigniter 时区处理,因为映射是不明确。

      【讨论】:

      • 这是一个绝妙的主意,斯特凡!它反过来给了我一个想法。我想我可以使用timezone_name_from_abbr。它还支持夏令时!我认为这可能是正确的用法timezone_name_from_abbr('', $offset * 3600, true) - 你觉得怎么样 - 它似乎对我有用?
      • 直到现在我才知道timezone_name_from_abbr() 功能,但这似乎是一个可行的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 2013-02-12
      • 2016-08-04
      • 1970-01-01
      相关资源
      最近更新 更多