我发现 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.c,static 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/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个这样的哈希数组:[{: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
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我想获取模块中定义的所有常量的值: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
所以我开始关注ruby,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出
简而言之错误: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
为什么以下不同?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