<commit_before>my class Date does Dateish {

    method !formatter(--> Str:D) {
        sprintf '%s-%02d-%02d',self!year-Str,$!month,$!day
    }

#?if moar
    my constant $valid-units = nqp::hash(
#?endif
#?if !moar
    my $valid-units := nqp::hash(
#?endif
      'day',    1,
      'days',   1,
      'week',   7,
      'weeks',  7,
      'month',  0,
      'months', 0,
      'year',   0,
      'years',  0,
    );

    method !VALID-UNIT($unit) {
        nqp::existskey($valid-units,$unit)
          ?? $unit
          !! X::DateTime::InvalidDeltaUnit.new(:$unit).throw
    }

    method !SET-SELF(\year,\month,\day,\formatter,$daycount? --> Date:D) {
        nqp::bind($!year,      year);  # R#2581
        nqp::bind($!month,     month);
        nqp::bind($!day,       day);
        nqp::bind(&!formatter, formatter);
        nqp::bind($!daycount,$daycount) if nqp::isconcrete($!daycount);
        self
    }

    proto method new(|) {*}
    multi method new(Date:
      Int:D() $year, Int:D() $month, Int:D() $day, :&formatter, *%_
    --> Date:D) {
        1 <= $month <= 12
          || X::OutOfRange.new(:what<Month>,:got($month),:range<1..12>).throw;
        1 <= $day <= self!DAYS-IN-MONTH($year,$month)
          || X::OutOfRange.new(
               :what<Day>,
               :got($day),
               :range("1..{self!DAYS-IN-MONTH($year,$month)}")
             ).throw;
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter)
          !! self.bless(:$year,:$month,:$day,:&formatter,|%_)!SET-DAYCOUNT
    }
    multi method new(Date:
      Int:D() :$year!, Int:D() :$month = 1, Int:D() :$day = 1, :&formatter, *%_
    --> Date:D) {
        1 <= $month <= 12
          || X::OutOfRange.new(:what<Month>,:got($month),:range<1..12>).throw;
        1 <= $day <= self!DAYS-IN-MONTH($year,$month)
          || X::OutOfRange.new(
               :what<Day>,
               :got($day),
               :range("1..{self!DAYS-IN-MONTH($year,$month)}")
             ).throw;
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter)
          !! self.bless(:$year,:$month,:$day,:&formatter,|%_)!SET-DAYCOUNT
    }
    multi method new(Date: Str $date, :&formatter, *%_ --> Date:D) {
        X::Temporal::InvalidFormat.new(
          invalid-str => $date,
          target      => 'Date',
          format      => 'yyyy-mm-dd',
        ).throw unless $date.codes == $date.chars and $date ~~ /^
          (<[+-]>? \d**4 \d*)                            # year
          '-'
          (\d\d)                                         # month
          '-'
          (\d\d)                                         # day
        $/;
        self.new($0,$1,$2,:&formatter,|%_)
    }
    multi method new(Date: Dateish $d, :&formatter, *%_ --> Date:D) {
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($d.year,$d.month,$d.day,&formatter)
          !! self.bless(
               :year($d.year),:month($d.month),:day($d.day),:&formatter, |%_
             )!SET-DAYCOUNT
    }
    multi method new(Date: Instant $i, :&formatter, *%_ --> Date:D) {
        self.new(DateTime.new($i),:&formatter,|%_)
    }
    proto method new-from-daycount($) {*}
    multi method new-from-daycount(Date:U: $daycount,:&formatter --> Date:D) {
        self!ymd-from-daycount($daycount, my $year, my $month, my $day);
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter,$daycount)
          !! self.bless(
               :$year,:$month,:$day,:&formatter,:$daycount
             )!SET-DAYCOUNT
    }
    multi method new-from-daycount(Date:D: $daycount,:&formatter = &!formatter --> Date:D) {
        self!ymd-from-daycount($daycount, my $year, my $month, my $day);
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter,$daycount)
          !! self.bless(
               :$year,:$month,:$day,:&formatter,:$daycount
             )!SET-DAYCOUNT
    }

    method today(:&formatter --> Date:D) { self.new(DateTime.now, :&formatter) }<commit_msg>Make Date.new(Str) about 2.8x as fast<commit_after>my class Date does Dateish {

    method !formatter(--> Str:D) {
        sprintf '%s-%02d-%02d',self!year-Str,$!month,$!day
    }

#?if moar
    my constant $valid-units = nqp::hash(
#?endif
#?if !moar
    my $valid-units := nqp::hash(
#?endif
      'day',    1,
      'days',   1,
      'week',   7,
      'weeks',  7,
      'month',  0,
      'months', 0,
      'year',   0,
      'years',  0,
    );

    method !VALID-UNIT($unit) {
        nqp::existskey($valid-units,$unit)
          ?? $unit
          !! X::DateTime::InvalidDeltaUnit.new(:$unit).throw
    }

    # fast object creation with sanity check on month/day
    method !SET-SELF(\year,\month,\day,\formatter,$daycount? --> Date:D) {
        self!oor("Month",month,"1..12")
          unless 1 <= month <= 12;
        self!oor("Day",day,"1..{self!DAYS-IN-MONTH(year,month)}")
          unless 1 <= day <= self!DAYS-IN-MONTH(year,month);

        nqp::bindattr(self,Date,'$!year',year);
        nqp::bindattr(self,Date,'$!month',month);
        nqp::bindattr(self,Date,'$!day',day);
        nqp::bindattr(self,Date,'&!formatter',formatter);
        nqp::bindattr(self,Date,'$!daycount',$daycount)
          if nqp::isconcrete($daycount);
        self
    }

    # object creation for subclasses, wit sanity check on month/day
    method !bless($year, $month, $day, &formatter, %nameds) {
        self!oor("Month",$month,"1..12")
          unless 1 <= $month <= 12;
        self!oor("Day",$day,"1..{self!DAYS-IN-MONTH($year,$month)}")
          unless 1 <= $day <= self!DAYS-IN-MONTH($year,$month);

        self.bless(:$year,:$month,:$day,:&formatter,|%nameds)!SET-DAYCOUNT
    }

    proto method new(|) {*}
    multi method new(Date:
      Int:D() $year, Int:D() $month, Int:D() $day, :&formatter
    --> Date:D) {
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year, $month, $day, &formatter)
          !! self!bless($year, $month, $day, &formatter, %_)
    }
    multi method new(Date:
      Int:D() :$year!, Int:D() :$month = 1, Int:D() :$day = 1, :&formatter
    --> Date:D) {
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year, $month, $day, &formatter)
          !! self!bless($year, $month, $day, &formatter, %_)
    }
    multi method new(Date: Str $date, :&formatter --> Date:D) {
        X::Temporal::InvalidFormat.new(
          invalid-str => $date,
          target      => 'Date',
          format      => 'yyyy-mm-dd',
        ).throw unless $date.codes == $date.chars and $date ~~ /^
          (<[+-]>? \d**4 \d*)                            # year
          '-'
          (\d\d)                                         # month
          '-'
          (\d\d)                                         # day
        $/;
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($0.Int, $1.Int, $2.Int, &formatter)
          !! self!bless($0.Int, $1.Int, $2.Int, &formatter, %_)
    }
    multi method new(Date: Dateish $d, :&formatter, *%_ --> Date:D) {
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($d.year,$d.month,$d.day,&formatter)
          !! self.bless(
               :year($d.year),:month($d.month),:day($d.day),:&formatter, |%_
             )!SET-DAYCOUNT
    }
    multi method new(Date: Instant $i, :&formatter, *%_ --> Date:D) {
        self.new(DateTime.new($i),:&formatter,|%_)   # XXX could be faster
    }
    proto method new-from-daycount($) {*}
    multi method new-from-daycount(Date:U: $daycount,:&formatter --> Date:D) {
        self!ymd-from-daycount($daycount, my $year, my $month, my $day);
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter,$daycount)
          !! self.bless(
               :$year,:$month,:$day,:&formatter,:$daycount
             )!SET-DAYCOUNT
    }
    multi method new-from-daycount(Date:D: $daycount,:&formatter = &!formatter --> Date:D) {
        self!ymd-from-daycount($daycount, my $year, my $month, my $day);
        nqp::eqaddr(self.WHAT,Date)
          ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter,$daycount)
          !! self.bless(
               :$year,:$month,:$day,:&formatter,:$daycount
             )!SET-DAYCOUNT
    }

    method today(:&formatter --> Date:D) { self.new(DateTime.now, :&formatter) }
{'fraction_non_alphanumeric': 0.20681551116333724, 'fraction_numerical': 0.009048178613396005, 'mean_word_length': 2.151055164753795, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1027797', 'n_tokens_mistral': 3110, 'n_tokens_neox': 2931, 'n_words': 460}