【问题标题】:Remove optional time component from datetime stamp string从日期时间戳字符串中删除可选的时间组件
【发布时间】:2013-08-29 15:40:03
【问题描述】:

我正在处理 PHP 脚本中的一些字符串,这些字符串可能采用 Y-m-d H:i:sY-m-d 格式。我需要从日期时间字符串中删除 H:i:s 部分,以便始终处理Y-m-d 日期字符串。

我如何删除这个尾随字符串(及其前导空格)如果它存在?

我的字符串可能看起来像 2003-11-24 23:52:182009-01-25

我对这些字符串的预期结果是2003-11-242009-01-25

我不需要验证这些字符串是否代表真正的“日期”或“日期时间”值。

【问题讨论】:

  • 假设日期总是被填充。为什么不对它做一个 substr 呢?
  • 你从哪里得到这个字符串?可能有更简单的方法。
  • 通过 whois 结果。这是查找域年龄,并且由于每个域列出它的方式不同,这可能很困难。这是一种格式 - 大多数不包括这样的时间戳。
  • 我们只能涵盖您提供给我们的案例。因此,如果它必须更加灵活,请告诉我们应该涵盖哪些内容。
  • 如果操作员无法写出合理的问题,那不是我的问题。

标签: php timestamp date-format substr strip


【解决方案1】:

您可以使用简单的explode 或在 cmets 中注明的substr,但如果您不知道如何根据您更新的帖子格式化字符串,则使用更复杂的date('Y-m-d', strtotime($mytime))...

$newdate = substr($olddate,0,10);

【讨论】:

  • @Bailey 给我们一个真实的例子然后......“2003-01-2800:00:00”?
  • 等等,传入的数据中没有空格?或者你希望空间随着时间一起被移除?
  • str_replace 并修剪另一个选项
  • @Dagon 如果您不知道要替换的字符串,str_replace 会做什么?
【解决方案2】:

由于日期的长度始终是固定的。你可以使用substr

// With 00:00:00
$date = '2003-01-2800:00:00';
echo substr($date, 0, 10) . '<br>';

// Without 00:00:00
$date = '2003-01-28';
echo substr($date, 0, 10) . '<br>'; 

// With other time part
$date = '2003-01-2812:00:11';
echo substr($date, 0, 10);          

【讨论】:

  • @Bailey 这并不要求它是 00:00:00 - 它只是取前 10 个字符。那行得通吗?你知道日期总是 10 个字符吗?
  • 我很抱歉,这是正确的。我的解释完全不同,我显然没有阅读乔纳森的评论。谢谢。大声笑
【解决方案3】:

编辑 #2(使用 str_replace)

在这种情况下,00:00:00 的位置无关紧要,即使日期之间没有空格。

适用于 00:00:00 2003-01-282003-01-28 00:00:002003-01-2800:00:00

<?php

$if_date_null = "00:00:00";
 
$replace = ""; // replace with nothing

// doesn't matter the position of 00:00:00
$dates = "00:00:00 2003-01-28";
// $dates = "2003-01-28 00:00:00";
 
$result = str_replace($if_date_null,$replace,$dates);
 
echo $result;

?>

编辑#1

<?php

$date = "2003-01-28";

$date_null = "00:00:00";

if (strpos($date_null,'00:00:00') !== false) {
    echo '00:00:00 found ';
}

else {

echo "No ZEROS found ";

}


?>

原答案

这将回显 2003-01-28 并且不包括 2003-01-28 和 00:00:00 之间的空格

<?php

echo substr("2003-01-28 00:00:00",0,-9);

?>

您也可以像这样将日期分配为变量:(将产生相同的结果)并在需要时在其他地方使用该变量。

<?php

$date = "2003-01-28";
echo substr("$date 00:00:00",0,-9);

?>

【讨论】:

  • 但是如果字符串中没有“00:00:00”怎么办?然后日期被切断。如前所述,它并不总是在那里。
  • @Bailey 我的印象是00:00:00 是最后一个字符串。
  • 有时。它因输入的域名而异。这就是为什么这很难 - 在删除之前必须先检测到它。
  • @Bailey 好的,所以这是一个“如果存在”。那将需要一个if 条件。代码需要更庞大一些。
  • @Bailey 不过,没关系,因为如果您左边的日期是您需要的日期,而右边的日期是未知的,只要有 8 位数字加上空格,您' 仍然会在左边得到你需要的字符串,对吗?
【解决方案4】:

也许你可以使用函数“date()”来格式化时间戳

<?php
$my_date = "2003-01-28 00:00:00";
$new_date = date("Y-m-d", time($my_date));
var_dump($new_date);

【讨论】:

  • Fatal error: Uncaught ArgumentCountError: time() expects exactly 0 arguments
【解决方案5】:

您的传入数据是一个日期字符串,因此请按此处理并使用DateTime 对其进行操作。您的解决方案可能很简单:-

$dateString = (new \DateTime('2003-01-28 00:00:00'))->format('Y-m-d');
//$dateString now === '2003-01-28'

即使时间部分 (00:00:00) 丢失,这也能正常工作。即使日期和时间之间没有空格。

As you can see 这应该涵盖您所有可能的输入。

【讨论】:

    【解决方案6】:

    首先,如果您从您控制的较早层(例如 sql 结果集)接收此输入数据,那么您可能应该在您的 php 接触它之前标准化字符串格式。如果这些数据来自某种 sql,如COALESCE(my_datetime, my_date) AS datetime_or_date,那么您可以省去您的 php 必须对结果集的每一行执行潜在的迭代调用。在您的合并过程中,可以很容易地利用一些函数,例如 CAST()DATE()DATE_FORMAT()CONVERT()STR_TO_DATE(),具体取决于场景。

    现在,这项任务的范围似乎相当狭窄。输入数据是Y-m-d H:i:sY-m-d。这与验证无关——只是文本提取。在这种情况下,有几种 php 技术是可以信任的(有些则不能)。对于可能没有有效日期/日期时间值或者这些值可能是空字符串甚至null 的研究人员,您应该小心您使用的函数/技术可能产生的副作用。

    考虑以下测试字符串和技术表,并谨慎选择:(Demo)

    "2003-01-28 01:23:45"
    (valid datetime)
    "2007-04-04"
    (valid date)
    substr($datetime, 0, 10) "2003-01-28" "2007-04-04"
    explode(' ', $datetime, 2)[0] "2003-01-28" "2007-04-04"
    sscanf($datetime, '%s', $sscanf); $sscanf "2003-01-28" "2007-04-04"
    preg_replace('/ .+/', '', $datetime) "2003-01-28" "2007-04-04"
    (new \DateTime($datetime))-&gt;format('Y-m-d') "2003-01-28" "2007-04-04"
    date("Y-m-d", strtotime($datetime)) "2003-01-28" "2007-04-04"
    strtok($datetime, ' ') "2003-01-28" "2007-04-04"
    strstr($datetime . ' ', ' ', true) "2003-01-28" "2003-04-04"
    "0000-00-00 00:00:00"
    (invalid datetime)
    "0000-00-00"
    (invalid date)
    substr($datetime, 0, 10) "0000-00-00" "0000-00-00"
    explode(' ', $datetime, 2)[0] "0000-00-00" "0000-00-00"
    sscanf($datetime, '%s', $sscanf); $sscanf "0000-00-00" "0000-00-00"
    preg_replace('/ .+/', '', $datetime) "0000-00-00" "0000-00-00"
    (new \DateTime($datetime))-&gt;format('Y-m-d') "-0001-11-30" "-0001-11-30"
    date("Y-m-d", strtotime($datetime)) "-0001-11-30" "-0001-11-30"
    strtok($datetime, ' ') "0000-00-00" "0000-00-00"
    strstr($datetime . ' ', ' ', true) "0000-00-00" "0000-00-00"
    ""
    (empty string)
    null
    (null value)
    substr($datetime, 0, 10) "" ""
    explode(' ', $datetime, 2)[0] "" ""
    sscanf($datetime, '%s', $sscanf); $sscanf null null
    preg_replace('/ .+/', '', $datetime) "" ""
    (new \DateTime($datetime))-&gt;format('Y-m-d') "2021-08-21" (current date) "2021-08-21" (current date)
    date("Y-m-d", strtotime($datetime)) "1970-01-01" "1970-01-01"
    strtok($datetime, ' ') false false
    strstr($datetime . ' ', ' ', true) "" ""

    一些明确的注释:

    1. substr() 是这个工作的好工具,在上述情况下返回一个稳定的值。
    2. explode() 是稳定的,但不是直接的,因为它需要在过程中创建一个数组。
    3. sscanf()%s 搜索前导子字符串,直到遇到空白字符。这是直接的,但有些人可能会争辩说它鲜为人知且不直观。此外,它还提供了一个引用变量,在某些情况下可能需要为 unset()。这种确切的技术仅对这种特定情况有用。根据输入字符串和分隔符的不同,sscanf() 可能可行,也可能不可行。
    4. preg_replace() 提供了稳定的结果,但它永远不会在速度上取胜。坦率地说,当有非正则表达式技术可以做完全相同的事情时,推出正则表达式引擎没有任何好处。不推荐。
    5. format() 可能会在提供无效或缺失值时提供一些不需要的结果。我会争辩说,因为这仅仅是一个文本提取任务,所以没有必要实例化一个 datetime 对象并调用一个格式化方法。不推荐。
    6. strtotime() & date() 在提供无效或缺失值时会提供一些不需要的结果。当任务可以在一个函数调用中完成时,我看不出有任何理由调用两个函数。不推荐。
    7. strtok() 可能是最理想的技术,也是保证值有长度时最简洁的技术。但是,当输入没有长度时,请注意布尔返回值。
    8. strstr() 可用于此任务,但为确保返回值稳定,分隔字符必须无条件附加到正在搜索的字符串。换句话说,必须找到分隔符。考虑到其他技术不需要改变输入字符串,这种技术只是感觉不必要的hacky。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 2021-04-09
      • 1970-01-01
      • 2012-10-25
      相关资源
      最近更新 更多