【问题标题】:php DateTime before 0 (Historical ACN dates)php DateTime before 0(历史 ACN 日期)
【发布时间】:2021-04-16 06:48:05
【问题描述】:

我在 stackoverflow 中搜索了 ACN 日期,但我得到的唯一结果是 0 之后、0 到 1000 之间或 0 到 1970 之间的日期。

我需要处理人的生日,但我有很多人在 0 年之前出生。 \juliantojd 和 \jdtojulian 对我没有帮助,因为该方法应该返回一个 DateTime 对象。

如何在第 0 年之前构建一个有效的 DateTime 实例?

如果我使用 \DateTime::createFromFormat,第一个参数如 'c' 或 \DateTime::ISO8601,则返回值为 false。

PS:

  1. 我在这里发现了同样的问题:PHP Datetime fail to convert negative ISO8601 date 但答案不需要负年份。

  2. 我还发现https://bugs.php.net/bug.php?id=76785,可能是答案的一部分(但我需要将分隔符从 / 转换为 -)

谢谢。

【问题讨论】:

  • 忘记旧的生日日期。当有一个非常不同的日历(以及描述日子的方式)时,谈论生日日期是没有意义的。你的意思是:罗马历、希腊历、希伯来历等?如果你想这样做,你应该发明你的虚构日历,然后使用它(并实现它)。顺便说一句,“ACN”是什么?你的意思是 AC / BCE?
  • new DateTime('-9999-01-01') 在 64 位系统上对我来说似乎工作正常? 3v4l.org/fgfPE
  • 确实,new DateTime('-9999-01-01') 有效,但 createFromFormat 无效。并且 new DateTime('-9999/01/01') 不起作用。我通过查找日期之前是否存在减号来解决这个问题。它有效,但并不优雅。
  • 您从哪里收到-9999/01/01 格式的日期?这是你存储的吗?它在你的控制之下吗?
  • @El_Vanja :这不在我的控制之下,因为我们使用共享数据库,主要由 java 应用程序填充。 [-]?Y/m/d 是存储到数据库中的格式,因为它们不能将很多日期存储为日期。

标签: php datetime


【解决方案1】:

对于高达 -9999 的负数年,DateTime 仅接受格式 -yyyy-mm-dd。像“-1234-8-9”或“-1234/08/09”这样的格式会产生错误。不允许使用诸如“-3 Days 2021/08/01”之类的相对表达式进行操作。因此,在一般情况下,仅检查第一个字符是否为“-”是不够的。我为 -Y-m-d 和 -Y/m/d 格式选择了正则表达式进行测试。

  $input = preg_replace_callback(
    '~^(-\d{1,4})([\-/])(\d{1,2})\2(\d{1,2})( |$)~',
    function($m){
      return sprintf('%05d-%02d-%02d%s',$m[1],$m[3],$m[4],$m[5]);
    },
    $input
  );

一个简单的测试:

$tests = [
  "-1234-01-01","-34/4/5","2021-04-05 09:45","-3056-01-01","-9999/1/1",
  "-35 Days 00:00","-35-8/2"
];

foreach($tests as $input){
  $inputMod = preg_replace_callback(
    '~^(-\d{1,4})([\-/])(\d{1,2})\2(\d{1,2})( |$)~',
    function($m){
      return sprintf('%05d-%02d-%02d%s',$m[1],$m[3],$m[4],$m[5]);
    },
    $input
  );
  $dt = date_create($inputMod);
  if($dt){
    echo $input.' ==> '.$dt->format('Y-m-d H:i:s')."<br>\n";
  }
  else echo $input." ==> Error<br>\n";
}

今天的结果:

-1234-01-01 ==> -1234-01-01 00:00:00
-34/4/5 ==> -0034-04-05 00:00:00
2021-04-05 09:45 ==> 2021-04-05 09:45:00
-3056-01-01 ==> -3056-01-01 00:00:00
-9999/1/1 ==> -9999-01-01 00:00:00
-35 Days 00:00 ==> 2021-03-17 00:00:00
-35-8/2 ==> Error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2015-06-29
    相关资源
    最近更新 更多