<commit_before>package thx;

/**
`Dates` provides additional extension methods on top of the `Date` type.

```
using Dates;
```

@author <NAME>
@author <NAME>
**/
class Dates {
/**
It compares two dates.
**/
  public static function compare(a : Date, b : Date) : Int
    return Floats.compare(a.getTime(), b.getTime());

/**
Creates a Date by using the passed year, month, day, hour, minute, second.

Note that each argument can overflow its normal boundaries (e.g. a month value of `-33` is perfectly valid)
and the method will normalize that value by offsetting the other arguments by the right amount.
**/
  @:noUsing
  public static function create(year : Int, ?month : Int = 0, ?day : Int = 1, ?hour : Int = 0, ?minute : Int = 0, ?second : Int = 0) : Date {
    // Wrap values that are too large or negative
    minute += Math.floor(second / 60);
    second = second % 60;
    if(second < 0) second += 60;

    hour += Math.floor(minute / 60);
    minute = minute % 60;
    if(minute < 0) minute += 60;

    day += Math.floor(hour / 24);
    hour = hour % 24;
    if(hour < 0) hour += 24;

    if(day == 0) {
      month -=1;
      if(month < 0) {
        month = 11;
        year -=1;
      }
      day = numDaysInMonth(month, year);
    }

    year += Math.floor(month / 12);
    month = month % 12;
    if(month < 0) month += 12;

    var daysInMonth = numDaysInMonth(month,year);
    while (day > daysInMonth) {
        if (day > daysInMonth) {
            day -= daysInMonth;
            month++;
        }
        if (month > 11) {
            month -= 12;
            year++;
        }
        daysInMonth = numDaysInMonth(month,year);
    }

    return new Date(year, month, day, hour, minute, second);
  }

/**
Creates an array of dates that begin at `start` and end at `end` included.

Time values are pick from the `start` value except for the last value that will
match `end`. No interpolation is made.
**/
  public static function daysRange(start : Date, end : Date) {
    if(less(end, start)) return [];
    var days = [];
    while(!sameDay(start, end)) {
      days.push(start);
      start = nextDay(start);
    }
    days.push(end);
    return days;
  }

/**
Returns `true` if the passed dates are the same.
**/
  inline public static function equals(self : Date, other : Date) : Bool
    return self.getTime() == other.getTime();

/**
Returns `true` if the dates are approximately equals. The amount of delta
allowed is determined by `units` and it spans that amount equally before and
after the `self` date. The default `unit` value is `1`.

The default `period` range is `Second`.
**/
  public static function nearEquals(self : Date, other : Date, ?units : Int = 1, ?period : TimePeriod) {
    if(null == period)
      period = Second;
    if(units < 0)
      units = -units;
    var min = jump(self, period, -units),
        max = jump(self, period, units);
    return lessEquals(min, other) && greaterEquals(max, other);
  }

/**
Returns `true` if the `self` date is greater than `other`.
**/
  inline public static function greater(self : Date, other : Date) : Bool
    return compare(self, other) > 0;

  @:deprecated("more is deprecated, use greater instead")
  inline public static function more(self : Date, other : Date) : Bool
    return greater(self, other);

/**
Returns `true` if the `self` date is lesser than `other`.
**/
  inline public static function less(self : Date, other : Date) : Bool
    return compare(self, other) < 0;

/**
Returns `true` if the `self` date is greater than or equal to `other`.
**/
  inline public static function greaterEquals(self : Date, other : Date) : Bool
    return compare(self, other) >= 0;

  @:deprecated("moreEqual is deprecated, use greaterEquals instead")
  inline public static function moreEqual(self : Date, other : Date) : Bool
    return greaterEquals(self, other);

/**
Returns `true` if the `self` date is lesser than or equal to `other`.
**/
  inline public static function lessEquals(self : Date, other : Date) : Bool
    return compare(self, other) <= 0;

  @:deprecated("lessEqual is deprecated, use lessEquals instead")
  inline public static function lessEqual(self : Date, other : Date) : Bool
    return lessEquals(self, other);

/**
Tells if a year is a leap year.

@param year The year, represented as a 4 digit integer
@return True if a leap year, false otherwise.
**/
  public static function isLeapYear(year : Int) {
    // Only every 4th year
    if ((year % 4) != 0) return false;
    // Except every 100, unless it's the 400th year
    if ((year % 100) == 0)
      return ((year % 400) == 0);
    // It's divisible by 4, and it's not divisible by 100 - it's leap
    return true;
  }

/**
Tells if the given date is inside a leap year.

@param date The date object to check.
@return True if it is in a leap year, false otherwise.
**/
  inline public static function isInLeapYear(d : Date) return isLeapYear(d.getFullYear());

/**
Returns the number of days in a month.

@param month An integer representing the month. (Jan=0, Dec=11)
@param year An 4 digit integer representing the year.
@return Int, the number of days in the month.
@throws Error if the month is not between 0 and 11.
**/
  public static function numDaysInMonth(month : Int, year : Int)
    // 31: Jan, Mar, May, Jul, Aug, Oct, Dec
    // 30: Apr, Jun, Sep, Nov
    // 28or29 Feb
    return switch month {
      case 0, 2, 4, 6, 7, 9, 11: 31;
      case 3, 5, 8, 10: 30;
      case 1: isLeapYear(year) ? 29 : 28;
      default: throw 'Invalid month "$month".  Month should be a number, Jan=0, Dec=11';
    };

/**
Tells how many days in the month of the given date.

@param date The date representing the month we are checking.
@return Int, the number of days in the month.
@throws Error if the month is not between 0 and 11.
**/
  public static function numDaysInThisMonth(d : Date)
    return numDaysInMonth(d.getMonth(), d.getFullYear());

/**
Returns true if the 2 dates share the same year.
**/
  public static function sameYear(self : Date, other : Date)
      return self.getFullYear() == other.getFullYear();

/**
Returns true if the 2 dates share the same year and month.
**/
  public static function sameMonth(self : Date, other : Date)
      return sameYear(self, other) && self.getMonth() == other.getMonth();

/**
Returns true if the 2 dates share the same year, month and day.
**/
  public static function sameDay(self : Date, other : Date)
    return sameMonth(self, other) && self.getDate() == other.getDate();

/**
Returns true if the 2 dates share the same year, month, day and hour.
**/
  public static function sameHour(self : Date, other : Date)
    return sameDay(self, other) && self.getHours() == other.getHours();

/**
Returns true if the 2 dates share the same year, month, day, hour and minute.
**/
  public static function sameMinute(self : Date, other : Date)
    return sameHour(self, other) && self.getMinutes() == other.getMinutes();
<commit_msg>updated class to use daysInMonth<commit_after>package thx;

/**
`Dates` provides additional extension methods on top of the `Date` type.

```
using Dates;
```

@author <NAME>
@author <NAME>
**/
class Dates {
/**
It compares two dates.
**/
  public static function compare(a : Date, b : Date) : Int
    return Floats.compare(a.getTime(), b.getTime());

/**
Creates a Date by using the passed year, month, day, hour, minute, second.

Note that each argument can overflow its normal boundaries (e.g. a month value of `-33` is perfectly valid)
and the method will normalize that value by offsetting the other arguments by the right amount.
**/
  @:noUsing
  public static function create(year : Int, ?month : Int = 0, ?day : Int = 1, ?hour : Int = 0, ?minute : Int = 0, ?second : Int = 0) : Date {
    // Wrap values that are too large or negative
    minute += Math.floor(second / 60);
    second = second % 60;
    if(second < 0) second += 60;

    hour += Math.floor(minute / 60);
    minute = minute % 60;
    if(minute < 0) minute += 60;

    day += Math.floor(hour / 24);
    hour = hour % 24;
    if(hour < 0) hour += 24;

    if(day == 0) {
      month -=1;
      if(month < 0) {
        month = 11;
        year -=1;
      }
      day = daysInMonth(year, month);
    }

    year += Math.floor(month / 12);
    month = month % 12;
    if(month < 0) month += 12;

    var days = daysInMonth(year, month);
    while (day > days) {
        if (day > days) {
            day -= days;
            month++;
        }
        if (month > 11) {
            month -= 12;
            year++;
        }
        days = daysInMonth(year, month);
    }

    return new Date(year, month, day, hour, minute, second);
  }

/**
Creates an array of dates that begin at `start` and end at `end` included.

Time values are pick from the `start` value except for the last value that will
match `end`. No interpolation is made.
**/
  public static function daysRange(start : Date, end : Date) {
    if(less(end, start)) return [];
    var days = [];
    while(!sameDay(start, end)) {
      days.push(start);
      start = nextDay(start);
    }
    days.push(end);
    return days;
  }

/**
Returns `true` if the passed dates are the same.
**/
  inline public static function equals(self : Date, other : Date) : Bool
    return self.getTime() == other.getTime();

/**
Returns `true` if the dates are approximately equals. The amount of delta
allowed is determined by `units` and it spans that amount equally before and
after the `self` date. The default `unit` value is `1`.

The default `period` range is `Second`.
**/
  public static function nearEquals(self : Date, other : Date, ?units : Int = 1, ?period : TimePeriod) {
    if(null == period)
      period = Second;
    if(units < 0)
      units = -units;
    var min = jump(self, period, -units),
        max = jump(self, period, units);
    return lessEquals(min, other) && greaterEquals(max, other);
  }

/**
Returns `true` if the `self` date is greater than `other`.
**/
  inline public static function greater(self : Date, other : Date) : Bool
    return compare(self, other) > 0;

  @:deprecated("more is deprecated, use greater instead")
  inline public static function more(self : Date, other : Date) : Bool
    return greater(self, other);

/**
Returns `true` if the `self` date is lesser than `other`.
**/
  inline public static function less(self : Date, other : Date) : Bool
    return compare(self, other) < 0;

/**
Returns `true` if the `self` date is greater than or equal to `other`.
**/
  inline public static function greaterEquals(self : Date, other : Date) : Bool
    return compare(self, other) >= 0;

  @:deprecated("moreEqual is deprecated, use greaterEquals instead")
  inline public static function moreEqual(self : Date, other : Date) : Bool
    return greaterEquals(self, other);

/**
Returns `true` if the `self` date is lesser than or equal to `other`.
**/
  inline public static function lessEquals(self : Date, other : Date) : Bool
    return compare(self, other) <= 0;

  @:deprecated("lessEqual is deprecated, use lessEquals instead")
  inline public static function lessEqual(self : Date, other : Date) : Bool
    return lessEquals(self, other);

/**
Tells if a year is a leap year.

@param year The year, represented as a 4 digit integer
@return True if a leap year, false otherwise.
**/
  public static function isLeapYear(year : Int) {
    // Only every 4th year
    if ((year % 4) != 0) return false;
    // Except every 100, unless it's the 400th year
    if ((year % 100) == 0)
      return ((year % 400) == 0);
    // It's divisible by 4, and it's not divisible by 100 - it's leap
    return true;
  }

/**
Tells if the given date is inside a leap year.

@param date The date object to check.
@return True if it is in a leap year, false otherwise.
**/
  inline public static function isInLeapYear(d : Date) return isLeapYear(d.getFullYear());

/**
Returns the number of days in a month.

@param month An integer representing the month. (Jan=0, Dec=11)
@param year An 4 digit integer representing the year.
@return Int, the number of days in the month.
@throws Error if the month is not between 0 and 11.
**/
  public static function daysInMonth(year : Int, month : Int)
    // 31: Jan, Mar, May, Jul, Aug, Oct, Dec
    // 30: Apr, Jun, Sep, Nov
    // 28or29 Feb
    return switch month {
      case 0, 2, 4, 6, 7, 9, 11: 31;
      case 3, 5, 8, 10: 30;
      case 1: isLeapYear(year) ? 29 : 28;
      default: throw 'Invalid month "$month".  Month should be a number, Jan=0, Dec=11';
    };

  @:deprecated("Use daysIntMonth instead. Also notice that arguments are inverted now")
  public static function numDaysInMonth(month : Int, year : Int)
    return daysInMonth(year, month);

/**
Tells how many days in the month of the given date.

@param date The date representing the month we are checking.
@return Int, the number of days in the month.
@throws Error if the month is not between 0 and 11.
**/
  public static function numDaysInThisMonth(d : Date)
    return daysInMonth(d.getFullYear(), d.getMonth());

/**
Returns true if the 2 dates share the same year.
**/
  public static function sameYear(self : Date, other : Date)
      return self.getFullYear() == other.getFullYear();

/**
Returns true if the 2 dates share the same year and month.
**/
  public static function sameMonth(self : Date, other : Date)
      return sameYear(self, other) && self.getMonth() == other.getMonth();

/**
Returns true if the 2 dates share the same year, month and day.
**/
  public static function sameDay(self : Date, other : Date)
    return sameMonth(self, other) && self.getDate() == other.getDate();

/**
Returns true if the 2 dates share the same year, month, day and hour.
**/
  public static function sameHour(self : Date, other : Date)
    return sameDay(self, other) && self.getHours() == other.getHours();

/**
Returns true if the 2 dates share the same year, month, day, hour and minute.
**/
  public static function sameMinute(self : Date, other : Date)
    return sameHour(self, other) && self.getMinutes() == other.getMinutes();

{'fraction_non_alphanumeric': 0.1217292377701934, 'fraction_numerical': 0.017349260523321957, 'mean_word_length': 3.059163059163059, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6565120', 'n_tokens_mistral': 4485, 'n_tokens_neox': 4233, 'n_words': 1782}