PHPackages                             ambroisemaupate/date-to-sentence - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ambroisemaupate/date-to-sentence

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ambroisemaupate/date-to-sentence
================================

A simple lexer to print human readable dates.

1.5.0(2y ago)53.8k↑564.3%[1 issues](https://github.com/ambroisemaupate/date2Sentence/issues)MITPHPPHP &gt;=7.4CI failing

Since Sep 15Pushed 2y ago1 watchersCompare

[ Source](https://github.com/ambroisemaupate/date2Sentence)[ Packagist](https://packagist.org/packages/ambroisemaupate/date-to-sentence)[ Docs](https://github.com/ambroisemaupate/date2Sentence)[ RSS](/packages/ambroisemaupate-date-to-sentence/feed)WikiDiscussions master Synced 3d ago

READMEChangelogDependencies (4)Versions (10)Used By (0)

Date2Sentence
=============

[](#date2sentence)

A simple lexer to print human readable dates.

[![Build Status](https://camo.githubusercontent.com/e5be5945cbb934d90653cd7a2ab648467e49769f438e5ff47058343d0d2086be/68747470733a2f2f6170702e7472617669732d63692e636f6d2f616d62726f6973656d6175706174652f646174653253656e74656e63652e7376673f6272616e63683d6d6173746572)](https://app.travis-ci.com/ambroisemaupate/date2Sentence)

### Requires

[](#requires)

- PHP 7.4 min.
- PHP-intl extension

### Available lexers

[](#available-lexers)

- English
- French
- German

### Usage

[](#usage)

```
composer require ambroisemaupate/date-to-sentence
```

```
use AM\Date2Sentence\EnglishDateLexer;

$lexer = new EnglishDateLexer();

$lexer->setDates([
     new DateTime('2017-06-01'),
     new DateTime('2017-06-02'),
     new DateTime('2017-06-03'),
 ]);

echo $lexer->toSentence();
// "From June 1st to June 3rd"

$lexer->setDates([
     new DateTime('2017-06-01'),
     new DateTime('2017-06-02'),
     new DateTime('2017-06-03'),
     new DateTime('2017-06-10'),
 ]);

echo $lexer->toSentence();
// "From June 1st to June 3rd and June 10th"
```

#### With wrap option

[](#with-wrap-option)

```
use AM\Date2Sentence\EnglishDateLexer;

$nonContinuousLexer = new EnglishDateLexer([
    new DateTime('2017-06-01'),
    new DateTime('2017-06-02'),
    new DateTime('2017-06-03'),
    new DateTime('2017-06-10'),
], ['wrap_format' => '%s']);

echo $nonContinuousLexer->toSentence();
// "From June 1st to June 3rd and June 10th"
```

#### With French lexer

[](#with-french-lexer)

```
use AM\Date2Sentence\FrenchDateLexer;

$lexer = new FrenchDateLexer([
    new DateTime('2017-06-01'),
    new DateTime('2017-06-02'),
    new DateTime('2017-06-03'),
]);

echo $lexer->toSentence();
// "Du 1er au 3 juin"

$nonContinuousLexer = new FrenchDateLexer([
    new DateTime('2017-06-01'),
    new DateTime('2017-06-02'),
    new DateTime('2017-06-03'),
    new DateTime('2017-06-10'),
]);

echo $nonContinuousLexer->toSentence();
// "Du 1er au 3 juin et le 10 juin"
```

#### Setting tolerance

[](#setting-tolerance)

Set tolerance **before** dates to changes how days are listed. You can force *from-to* writing even if there are some missing days (e.g. weekends).

```
use AM\Date2Sentence\EnglishDateLexer;

$nonContinuousLexer = new EnglishDateLexer();
// Tolerate 1 missing day between dates.
$nonContinuousLexer->setTolerance(1);
$nonContinuousLexer->setDates([
    new DateTime('2017-06-01'),
    // no 2nd
    new DateTime('2017-06-03'),
    // no 4th
    new DateTime('2017-06-05'),
    // no 6th
    new DateTime('2017-06-07'),
]);

echo $nonContinuousLexer->toSentence();
// "From June 1st to June 7th"
```

#### Grouping by month

[](#grouping-by-month)

*Date2Sentence* is made to group days within the same month not to repeat same month-name over and over.

```
use AM\Date2Sentence\EnglishDateLexer;

$nonContinuousLexer = new EnglishDateLexer();
$nonContinuousLexer->setDates([
    new DateTime('2017-06-01'),
    // no 2nd
    new DateTime('2017-06-03'),
    // no 4th
    new DateTime('2017-06-05'),
    // no 6th
    new DateTime('2017-06-07'),
    new DateTime('2017-07-01'),
]);

echo $nonContinuousLexer->toSentence();
// "June 1st, 3rd, 5th, 7th and July 1st"

//
// In French, it works too…
// "Les 1er, 2, 5, 7 juin et le 1er juillet"
```

#### Get hours

[](#get-hours)

*Date2Sentence* can also extract times from your given dates:

```
use AM\Date2Sentence\EnglishDateLexer;

$lexer = new EnglishDateLexer();
$lexer->setDates([
    new DateTime('2017-06-01 20:00:00'),
    new DateTime('2017-06-03 21:00:00'),
    new DateTime('2017-06-05 20:00:00'),
    new DateTime('2017-06-07 21:00:00'),
    new DateTime('2017-07-01 20:00:00'),
]);

echo json_encode(array_keys($this->getLexer()->getAvailableTimes()));
// [
//    "20:00",
//    "21:00"
// ]
```

#### Get dates as array

[](#get-dates-as-array)

If you need to render manually you date groups, you can use generic `toArray` method which will group start and end dates into arrays. Dates in same array are continuous, separate arrays mean that they’re not continuous.

```
use AM\Date2Sentence\EnglishDateLexer;

$lexer = new EnglishDateLexer();
$lexer->setDates([
    new DateTime('2017-06-01 20:00:00'),
    new DateTime('2017-06-02 21:00:00'),
    new DateTime('2017-06-03 21:00:00'),
    new DateTime('2017-07-01 20:00:00'),
    new DateTime('2017-07-02 21:00:00'),
    new DateTime('2017-07-03 21:00:00'),
]);

echo json_encode($this->getLexer()->toArray());
// [
//    [
//        {"date":"2017-06-01 20:00:00.000000","timezone_type":3,"timezone":"Europe\/Paris"},
//        {"date":"2017-06-03 21:00:00.000000","timezone_type":3,"timezone":"Europe\/Paris"}
//    ],
//    [
//        {"date":"2017-07-01 20:00:00.000000","timezone_type":3,"timezone":"Europe\/Paris"},
//        {"date":"2017-07-03 21:00:00.000000","timezone_type":3,"timezone":"Europe\/Paris"}
//    ]
// ]
```

#### Get days of week

[](#get-days-of-week)

*Date2Sentence* can also extract days of week from your given dates, day will be represented as their number (1 for Monday, 7 for Sunday) and will be ordered:

```
use AM\Date2Sentence\EnglishDateLexer;

$lexer = new EnglishDateLexer();
$lexer->setDates([
    new DateTime('2017-06-01'),
    new DateTime('2017-06-02'),
    new DateTime('2017-06-03'),
    new DateTime('2017-06-08'),
    new DateTime('2017-06-08'),
]);

echo json_encode($this->getLexer()->getAvailableDaysOfWeek());
// [
//    4,
//    5,
//    6
// ]
```

Tests
-----

[](#tests)

```
vendor/phpunit/phpunit/phpunit --bootstrap vendor/autoload.php test
```

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance16

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~305 days

Recently: every ~483 days

Total

8

Last Release

1080d ago

PHP version history (4 changes)1.0.0PHP ^7.0

1.3.0PHP ^7.2

1.4.0PHP &gt;=7.2

1.5.0PHP &gt;=7.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/380026?v=4)[Ambroise Maupate](/maintainers/ambroisemaupate)[@ambroisemaupate](https://github.com/ambroisemaupate)

---

Top Contributors

[![ambroisemaupate](https://avatars.githubusercontent.com/u/380026?v=4)](https://github.com/ambroisemaupate "ambroisemaupate (41 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ambroisemaupate-date-to-sentence/health.svg)

```
[![Health](https://phpackages.com/badges/ambroisemaupate-date-to-sentence/health.svg)](https://phpackages.com/packages/ambroisemaupate-date-to-sentence)
```

###  Alternatives

[friendsofphp/php-cs-fixer

A tool to automatically fix PHP code style

13.5k251.2M25.3k](/packages/friendsofphp-php-cs-fixer)[symfony/rate-limiter

Provides a Token Bucket implementation to rate limit input and output in your application

27054.3M291](/packages/symfony-rate-limiter)[symfony/ldap

Provides a LDAP client for PHP on top of PHP's ldap extension

1408.1M59](/packages/symfony-ldap)[symfony/ux-cropperjs

Cropper.js integration for Symfony

19346.6k3](/packages/symfony-ux-cropperjs)[php-soap/ext-soap-engine

An ext-soap engine implementation

443.5M12](/packages/php-soap-ext-soap-engine)[symfony/ux-toggle-password

Toggle visibility of password inputs for Symfony Forms

27600.4k5](/packages/symfony-ux-toggle-password)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
