使DateTime :: createFromFormat()返回子类而不是父类

时间:2011-03-27 15:28:05

标签: php datetime php-5.3 extend inheritance

我正在扩展DateTime添加一些有用的方法和常量。

使用new创建新对象时一切都很好但是当使用静态方法createFromFormat时,它总是返回原始的DateTime对象,当然没有任何子方法可用

我使用以下代码来规避此问题。这是最好的方法吗?

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new self();

        $ext_dt->setTimestamp(parent::createFromFormat($format, time)->getTimestamp());

        return $ext_dt;
    }
}

4 个答案:

答案 0 :(得分:12)

这是要走的路。但是,由于您想要做的是呈现DateTime类可扩展,我建议您使用static而不是self

namespace NoiseLabs\DateTime;

class DateTime extends \DateTime
{
    static public function createFromFormat($format, $time)
    {
        $ext_dt = new static();
        $parent_dt = parent::createFromFormat($format, $time);

        if (!$parent_dt) {
            return false;
        }

        $ext_dt->setTimestamp($parent_dt->getTimestamp());
        return $ext_dt;
    }
}

没有必要,如果你不打算扩展课程,但如果有人这样做,这将阻止他再次做同样的解决方法。

答案 1 :(得分:0)

我认为您的解决方案很好。另一种方法(只是重构一下)是这样的:

public static function fromDateTime(DateTime $foo)
{
  return new static($foo->format('Y-m-d H:i:s e')); 
}

public static function createFromFormat($f, $t, $tz)
{
  return static::fromDateTime(parent::createFromFormat($f, $t, $tz));
}

我不确定实施fromDateTime的最佳方法是什么。你甚至可以拿走你所拥有的东西并把它放在那里。请确保不要丢失时区。

请注意,您甚至可以实施__callStatic并使用一些反思来使其面向未来。

答案 2 :(得分:0)

         NSURL *aURL = [NSURL URLWithString:[[NSString stringWithFormat:@"%@%@",Image_BASE_URL,str] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
        //UIImage *aImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:aURL]];
        //[aImage drawInRect:CGRectMake(0, 0, 20, 20)];


        __block  NSTextAttachment *imageAttachment = [NSTextAttachment new];
        imageAttachment.bounds = CGRectMake(0, -5, 20, 20);
        NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment];
        [deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage];
        incomingMessage.messageAttributedString = deCodedString;


        SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
        imageAttachment.image = [UIImage imageNamed:@"profile_main_placeholder"];

        [downloader downloadImageWithURL:aURL
                                 options:0
                                progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                                    // progression tracking code
                                }
                               completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
                                   if (image && finished) {
                                       [image drawInRect:CGRectMake(0, 0, 20, 20)];
                                       imageAttachment.image = image;

                                       dispatch_async(dispatch_get_main_queue(), ^(void)
                                                      {

                                                          [self.tbl_Conversation reloadRowsAtIndexPaths:[self.tbl_Conversation indexPathsForVisibleRows]
                                                                                       withRowAnimation:UITableViewRowAnimationNone];
                                                          [self.tbl_Conversation reloadData];
                                                      });



                                       //                                                              NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment];
                                       //                                                              [deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage];
                                       //                                                              incomingMessage.messageAttributedString = deCodedString;
                                   }
                               }];

答案 3 :(得分:0)

以前的解决方案忽略了时区和微秒,因此我的一点改进是在这里。 我更喜欢变体1,但就性能2而言,在旧的PHP上可能要快一些。

class NDateTimeImmutable extends \DateTimeImmutable
{
    public static function createFromFormat1($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
        if (!$parent) {
            return false;
        }
        //Seting timezone like this and not by format to preserve timezone format
        $static = new static($parent->format('Y-m-d\TH:i:s.u'), $parent->getTimezone());
        return $static;
    }

    public static function createFromFormat2($format, $time)
    {
        $parent = parent::createFromFormat($format, $time);
         if (!$parent) {
            return false;
        }
        $serialized = serialize($parent);
        // numbers can be computed by strlen() 
        // eg. strlen(parent::class) = 17 but it is slow
        $serialized = strtr($serialized, ['17:"'.parent::class => '18:"'.static::class]);
        return unserialize($serialized);
    }
}