<commit_before>Yii2 Fuzzydate
============

Often, when working with dates, data are incomplete. For instance, one might know that a person is born in 1980, or in April, 1980, but not on which day exactly.

I call these dates *fuzzy dates*. Here are a few classes to work with them in the Yii 2.x PHP framework.

## Fuzzy date representation ##

### In the database ###

In the database each fuzzy date is represented by **two** 'normal' dates. The field names of the two dates are derived from the attribute name of the fuzzy date, by appending `'1'` and `'2'` respectively. 


So, if the attribute name of the fuzzy date is `'born'`, the fields representing is in the database would be `'born1'` and `'born2'`.

- If we know the date exactly, the value of both date fields is equal.
- If we know the date with a 'granularity' of one month, the value of the first field is the first day of the month, the value of the second field is the last day of the month.
- If we only know the year, the value of the first field is the first day of the year, the value of the second field is the last day of the year.

In other words, given a fuzzy date `'xyz'`, the range of possible 'real' dates is given by `'xyz1'` and `'xyz2'`.

For instance, the exact date of December 3, 2008 (the day Yii was launched, by the way) would be represented by (assuming MySQL format):

    born1 = "2008-12-03"
    born2 = "2008-12-03"

If the date was December, 2008, we would have:

    born1 = "2008-12-01"
    born2 = "2008-12-31"

And, lastly, if the date was 2008:

    born1 = "2008-01-01"
    born2 = "2008-12-31"

### In PHP ###

In PHP, a fuzzy date is represented by a three member array, where the unknown values are set to `null`. Like so:

    <?php
		
		// December 3, 2008
		$born = [
			'y' => 2008,
			'm' => 12,
			'd' => 3
		];
		
		// December, 2008
		$born = [
			'y' => 2008,
			'm' => 12,
			'd' => null
		];
		
		// 2008
		$born = [
			'y' => 2008,
			'm' => null,
			'd' => null
		];

## Yii2 Fuzzydate classes ##

**Yii2 Fuzzydate** consists of three classes to work with fuzzy dates:

- **FuzzyDateBehavior** Model/ActiveRecord behavior that converts from database to PHP format, and vice versa;
- **DatePicker** Input widget for a fuzzy date;
- **Formatter** Extends from `yii\i18n\Formatter`, and adds a fuzzy date formatting function.

**DatePickerAsset** is a helper class for **DatePicker**.

A demonstration of the **Yii2 Fuzzydate** suit is [here](http://www.sjaakpriester.nl/software/fuzzydate).

## Installation ##

The preferred way to install **Yii2 Fuzzydate** is through [Composer](https://getcomposer.org/). Either add the following to the require section of your `composer.json` file:

`"sjaakp/yii2-fuzzydate": "*"` 

Or run:

`composer require sjaakp/yii2-fuzzydate "*"` 

You can manually install **Yii2 Fuzzydate** by [downloading the source in ZIP-format](https://github.com/sjaakp/yii2-fuzzydate/archive/master.zip).

## FuzzyDateBehavior ##

A class `Hero` with fuzzy date attributes `'born'` and `'died'` should have database fields `'born1'`, `'born2'`, `'died1'`, and `'died2'`. It should be set up like this:

	<?php

	namespace app\models;

	use sjaakp\fuzzydate\FuzzyDateBehavior;

	class Hero extends ActiveRecord    {

        public function rules()    {
	        return [
	            [['born', 'died'], 'safe'],
				// ...
	        ];
	    }

    	public function behaviors()
    	{
	        return [
	            'fuzzydate' => [
	                'class' => FuzzyDateBehavior::className(),
					'attributes'=> [
						'born',
						'died'
					]
	            ]
	        ];
	    }
		// ...
	}

After that, class `Hero` has two 'virtual attributes', `'born'`, and `'died'`.

**Notice:** Don't forget to declare the attributes *safe* in the method `rules()`.

The behavior adds virtual fuzzy date attributes to the model class, which can be read from and written to like normal attributes. The underlying attributes (like `'born1'`, `'born2'`) are accessible as well.

### Attributes ###

#### $attributes ####

Array of names of the fuzzy date attributes.

#### $format ####

Format string to format the underlying 'real' dates with PHP DateTime.<commit_msg>Small edit<commit_after>Yii2 Fuzzydate
============

Often, when working with dates, data are incomplete. For instance, one might know that a person is born in 1980, or in April, 1980, but not on which day exactly.

I call these dates *fuzzy dates*. Here are a few classes to work with them in the Yii 2.x PHP framework.

## Fuzzy date representation ##

### In the database ###

In the database each fuzzy date is represented by **two** 'normal' dates. The field names of the two dates are derived from the attribute name of the fuzzy date, by appending `'1'` and `'2'` respectively. 


So, if the attribute name of the fuzzy date is `'born'`, the fields representing is in the database would be `'born1'` and `'born2'`.

- If we know the date exactly, the value of both date fields is equal.
- If we know the date with a 'granularity' of one month, the value of the first field is the first day of the month, the value of the second field is the last day of the month.
- If we only know the year, the value of the first field is the first day of the year, the value of the second field is the last day of the year.

In other words, given a fuzzy date `'xyz'`, the range of possible 'real' dates is given by `'xyz1'` and `'xyz2'`.

For instance, the exact date of December 3, 2008 (the day Yii was launched, by the way) would be represented by (assuming MySQL format):

    born1 = "2008-12-03"
    born2 = "2008-12-03"

If the date was December, 2008, we would have:

    born1 = "2008-12-01"
    born2 = "2008-12-31"

And, lastly, if the date was 2008:

    born1 = "2008-01-01"
    born2 = "2008-12-31"

### In PHP ###

In PHP, a fuzzy date is represented by a three member array, where the unknown values are set to `null`. Like so:

    <?php
		
		// December 3, 2008
		$born = [
			'y' => 2008,
			'm' => 12,
			'd' => 3
		];
		
		// December, 2008
		$born = [
			'y' => 2008,
			'm' => 12,
			'd' => null
		];
		
		// 2008
		$born = [
			'y' => 2008,
			'm' => null,
			'd' => null
		];

## Yii2 Fuzzydate classes ##

**Yii2 Fuzzydate** consists of three classes to work with fuzzy dates:

- **FuzzyDateBehavior** Model/ActiveRecord behavior that converts from database to PHP format, and vice versa;
- **DatePicker** Input widget for a fuzzy date;
- **Formatter** Extends from `yii\i18n\Formatter`, and adds a fuzzy date formatting function.

**DatePickerAsset** is a helper class for **DatePicker**.

A demonstration of the **Yii2 Fuzzydate** suit is [here](http://www.sjaakpriester.nl/software/fuzzydate).

## Installation ##

The preferred way to install **Yii2 Fuzzydate** is through [Composer](https://getcomposer.org/). Either add the following to the require section of your `composer.json` file:

`"sjaakp/yii2-fuzzydate": "*"` 

Or run:

`composer require sjaakp/yii2-fuzzydate "*"` 

You can manually install **Yii2 Fuzzydate** by [downloading the source in ZIP-format](https://github.com/sjaakp/yii2-fuzzydate/archive/master.zip).

## FuzzyDateBehavior ##

A class `Hero` with fuzzy date attributes `'born'` and `'died'` should have database fields `'born1'`, `'born2'`, `'died1'`, and `'died2'`. It should be set up like this:

	<?php

	namespace app\models;

	use sjaakp\fuzzydate\FuzzyDateBehavior;

	class Hero extends ActiveRecord    {

        public function rules()    {
	        return [
	            [['born', 'died'], 'safe'],
				// ...
	        ];
	    }

    	public function behaviors()
    	{
	        return [
	            'fuzzydate' => [
	                'class' => FuzzyDateBehavior::class,
					'attributes'=> [
						'born',
						'died'
					]
	            ]
	        ];
	    }
		// ...
	}

After that, class `Hero` has two 'virtual attributes', `'born'`, and `'died'`.

**Notice:** Don't forget to declare the attributes *safe* in the method `rules()`.

The behavior adds virtual fuzzy date attributes to the model class, which can be read from and written to like normal attributes. The underlying attributes (like `'born1'`, `'born2'`) are accessible as well.

### Attributes ###

#### $attributes ####

Array of names of the fuzzy date attributes.

#### $format ####

Format string to format the underlying 'real' dates with PHP DateTime.
{'fraction_non_alphanumeric': 0.12388113139992839, 'fraction_numerical': 0.03079126387397064, 'mean_word_length': 3.1526263627353814, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 27, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7498035', 'n_tokens_mistral': 2999, 'n_tokens_neox': 2544, 'n_words': 1112}