- # Date Duration Calculation
-
- This Laravel application calculates the duration between two provided dates,
- and outputs the number of days, week days, and weeks.
-
- A conversion parameter can also be provided to the endpoint to convert the
- result to seconds, minutes, hours, or years.
-
- ## General Decisions made
-
- - I've used Laravel for this, as its PHP, and something I am familiar with.
-
- - The endpoint is a POST request to `/calculate-duration`, this was done in
- order to leverage Laravel's validation rules. This also allows the end user to
- specify their data in JSON, which can be easier than managing query parameters.
-
- - Due to the specifications detailing that the duration should be initially
- calculated in days, week days, and weeks, and then convert it to the another
- value, the timezone requirement seemed redundant. This is because the most
- granular interval the specifications allows is a day. If, after more
- discussion, the requirement changed to needing the seconds between two
- _datetimes_, I would have changed the CalculateDuration service class to
- calculate the duration with the granularity of a second.
-
- - The weeks are calculated using `$start->diff($end)`, as opposed to using the
- PHP `DateInterval` and `DatePeriod` classes. This is primarily due to the
- rounding issues I experienced during dev, i.e 2024-08-01 2024-08-17 equals 4
- weeks, as the duration exists _over_ 3 weeks, but does not span the _whole_ of
- the 3 weeks. The duration of the interval is then also added `$this->end`
- property during the calculation (in order to include the final day in the
- calculation when using P1D for the `DateInterval`).
-
-
- ## General Code Structure
-
- 1. `routes/web.php`
- - Defines the POST request route
-
- 2. `app/Http/Controllers/CalculateDurationController.php`
- - Handles the POST request
-
- 3. `app/Http/Requests/CalculateDurationRequest.php`
- - Performs validation on the POST request data
-
- 4. `app/Http/Resources/CalculateDurationResource.php`
- - Returns the calculated durations
-
- 5. `app/Services/CalculateDuration.php`
- - Calculates the duration, and converts to the `DurationModifier` if required
-
- 6. `app/Enums/DurationModifier.php`
- - Enum for the possible conversions, also used to validated the `convert_to`
- POST request parameter
-
- 7. `app/DTO/DurationResult.php`
- - Data transfer object, so we aren't parsing
- around arrays, and needing to assume the array keys exist.
-
- 8. `tests/*`
- Unit and integration tests.
-
- ## Room for improvement
-
- There are two things I would probably improve, if this was intended for production
-
- 1. I'd like to avoid the ternary on CalculateDuration.php:56, although I
- couldn't think of a quick way to simplify it. Its been a long day.
-
- 2. Tests relating to timezones are lacking, due to the aforementioned redundancy.
-
- ## Running the code
-
- All is well, as all is dockerized.
-
- ```sh
- composer install
-
- ./vendor/bin/sail up
- ```
-
- ```sh
- ./vendor/bin/sail test
- ```
-
- ## Testing manually
-
- You can the convert_to value to `second`, `minute`, `hour`, `year`, or omit the key entirely.
-
- ```sh
- read -r -d '' VAR << EOM
- {
- "start": {
- "date": "2024-08-01"
- },
- "end": {
- "date": "2024-08-21"
- },
- "convert_to": null
- }
- EOM
-
- curl -v \
- --data "${VAR}" \
- -H "Content-Type: application/json" \
- -H "Accept: application/json" \
- "http://localhost:80/calculate-duration"
- ```
-
|