草庐IT

PHP Datetime 构造函数现在返回奇怪的值

coder 2024-04-16 原文

我发现 PHP\Datetime 类会为一些奇怪的输入返回“现在”值。我已经在 DateTime constructor in php 看到过类似的问题-- 这解释了诸如字母表中的单个字母(它们是军事时区)之类的输入。但是我发现了一些新的奇怪的东西,我希望它们会导致错误,而不是返回值。比如……

new \Datetime( '.' )
new \Datetime( ',' )

谁能解释为什么这些不会导致错误,谁能告诉我我应该期望哪些其他奇数值返回有效日期?这是 PHP 中的错误吗?

(是的,我已经注意到 0 以及您在 timezone_abbreviations_list() 中找到的基本上所有内容)

更新:

我想与大家分享我的“将各种输入转换为 PHP 日期时间对象”功能。最初是作为条件“无论我得到什么,输出一个对象”完成的,但由于@Syscall 的输入,我已经能够稍微加强它以防止不恰本地返回“现在”日期时间的虚假输入。

对于各种时区字符串,我可以更加努力地降低它,但我认为这对我的使用来说没有必要。

/**
 * If $input is already a DateTime object, leave it alone. Otherwise convert to a DateTime object
 * If $immutable = true, converts strings OR DateTime to DateTimeImmutable
 * Can be used to convert DateTimeInterface objects to and from immutable
 *
 * @param string|\DatetimeInterface $input
 * @param bool $immutable
 * @return \DateTime|\DateTimeImmutable|\DateTimeInterface|null
 */
function ensureDateTime ( $input, $immutable = NULL ) {
    if ( ! $input instanceof \DateTimeInterface ) {
        $output = NULL;
        if( is_string( $input ) || ! $input ) {
            $trimmed = trim( $input, ".,\n\0\t " ); // Thanks https://stackoverflow.com/a/48956505/339440
            $ignore =  ( $trimmed == '' && $trimmed != $input )
              || in_array( $trimmed, ['0000-00-00', '0000-00-00 00:00:00'], true )
              || ( strlen( $trimmed ) == 1 && preg_match( '#[a-zA-Z]#', $trimmed ) == 1 );
            if ( ! $ignore ) {
                try {
                    $input = trim( $input );
                    if ( $immutable ) {
                        $output = new \DateTimeImmutable( $input );
                    } else {
                        $output = new \DateTime( $input );
                    }
                } catch( \Exception $e ) {
                    // suppress DateTime::__construct() errors.  $output remains NULL
                }
            }
        }
    } elseif ( true === $immutable && $input instanceof \DateTime ) {
        $output = new \DateTimeImmutable( $input->format(TIMESTAMPFORMAT), $input->getTimezone() );
    } elseif ( false === $immutable && $input instanceof \DateTimeImmutable ) {
        $output = new \DateTime( $input->format(TIMESTAMPFORMAT), $input->getTimezone() );
    } else {
        $output = $input;
    }
    return $output;
}

最佳答案

".,\n\0\t " 被修剪:

参见/php-7.2.2/ext/date/lib/parse_date.cstatic int scan():

switch (yych) {
case 0x00:
case '\n':  goto yy51;
case '\t':
case ' ':   goto yy48;
case ',':
case '.':   goto yy50;

其他字符如(+-@、字母、数字,需要其他验证。

示例:

new Datetime("\0 \n\t,."); // works

但是:

new Datetime('@') ; // fails

关于PHP Datetime 构造函数现在返回奇怪的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48956453/

有关PHP Datetime 构造函数现在返回奇怪的值的更多相关文章

  1. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  4. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  5. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  8. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  9. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  10. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

随机推荐