bermudaphp/duration
Composer 安装命令:
composer require bermudaphp/duration
包简介
An immutable PHP library for handling time durations with ISO 8601 support
README 文档
README
Read this in other languages: Русский
Overview
Duration is an immutable wrapper class for working with time durations with ISO 8601 support. It provides a comprehensive API for creating, manipulating, formatting, and comparing time durations in a type-safe and consistent manner.
Table of Contents
- Features
- Installation
- Basic Usage
- Factory Methods
- ISO 8601 Support
- Conversion Methods
- Arithmetic Operations
- Comparison Operations
- Increment and Decrement Operations
- Formatting Methods
- Serialization
- DateInterval Conversion
- Examples
- Testing
- Contributing
- License
Features
- Immutable Design: All operations return new instances, preserving the original
- Fluent Interface: Method chaining for cleaner code
- ISO 8601 Support: Parse and generate ISO 8601 duration strings (e.g.,
P1Y2M3DT4H5M6S) - Comprehensive Time Units: Convert between seconds, minutes, hours, days, weeks, months, and years
- Advanced Comparison: Compare durations with support for ALL/ANY modes when working with arrays
- Increment/Decrement: Convenient methods for increasing or decreasing durations
- Multiple Formatting Options: Human-readable, custom format templates, and component arrays
- Serialization Support: JSON serialization built-in
- DateInterval Integration: Convert to and from PHP's DateInterval class
Installation
composer require bermudaphp/duration
Basic Usage
use Bermuda\Stdlib\Duration; // Create a duration of 1 hour and 30 minutes $duration = new Duration(5400); // Get total seconds echo $duration->toSeconds(); // 5400 // Convert to minutes echo $duration->toMinutes(); // 90 // Convert to hours echo $duration->toHours(); // 1 // Get the ISO 8601 representation echo $duration->toISO8601(); // "PT1H30M" // Get a human-readable representation echo $duration->toHumanReadable(); // "01:30:00"
Factory Methods
Duration provides multiple factory methods for creating instances:
// From specific time units $fromSeconds = Duration::fromSeconds(60); // 60 seconds $fromMinutes = Duration::fromMinutes(5); // 5 minutes $fromHours = Duration::fromHours(2); // 2 hours $fromDays = Duration::fromDays(1); // 1 day $fromWeeks = Duration::fromWeeks(2); // 2 weeks $fromMonths = Duration::fromMonths(3); // 3 months $fromYears = Duration::fromYears(1); // 1 year // From ISO 8601 string $fromISO = Duration::fromISO8601('P1Y2M3DT4H5M6S'); // From DateInterval $interval = new \DateInterval('P1DT6H'); $fromInterval = Duration::fromDateInterval($interval);
ISO 8601 Support
Duration fully supports the ISO 8601 duration format:
// Validate ISO 8601 strings $isValid = Duration::validate('P1Y2M3DT4H5M6S'); // true $isInvalid = Duration::validate('P1X'); // false // Create from ISO 8601 string $duration = Duration::fromISO8601('P1Y2M3DT4H5M6S'); // Convert to ISO 8601 string echo $duration->toISO8601(); // "P1Y2M3DT4H5M6S"
ISO 8601 Format Rules
- Format:
P[n]Y[n]M[n]DT[n]H[n]M[n]S Pis the duration designator (for period) placed at the startYis the year designatorMis the month designatorDis the day designatorTis the time designator (required if any time components are used)His the hour designatorMis the minute designatorSis the second designator
Example: P3Y6M4DT12H30M5S represents a duration of 3 years, 6 months, 4 days, 12 hours, 30 minutes, and 5 seconds.
Conversion Methods
Convert a duration to different time units:
$duration = Duration::fromISO8601('P1Y2M3DT4H5M6S'); echo $duration->toSeconds(); // Total seconds echo $duration->toMinutes(); // Total minutes (rounded down) echo $duration->toHours(); // Total hours (rounded down) echo $duration->toDays(); // Total days (rounded down) echo $duration->toWeeks(); // Total weeks (rounded down) echo $duration->toMonths(); // Total months (rounded down) echo $duration->toYears(); // Total years (rounded down)
Arithmetic Operations
Perform arithmetic operations on durations:
$duration1 = new Duration(3600); // 1 hour $duration2 = new Duration(1800); // 30 minutes // Addition $sum = $duration1->add($duration2); // 1 hour 30 minutes // Adding specific time units $plusOneHour = $duration1->addHours(1); // Add 1 hour $plusTenMinutes = $duration1->addMinutes(10); // Add 10 minutes $plusYear = $duration1->addYears(1); // Add 1 year // Subtraction (throws exception if result would be negative) $difference = $duration1->strictSubtract($duration2); // 30 minutes // Safe subtraction (returns zero if result would be negative) $safeDifference = $duration1->subtract($duration2); // 30 minutes // Subtracting specific time units (throws exception if result would be negative) $minusOneHour = $duration2->subtractHours(1); // Exception! $minusTenMinutes = $duration2->subtractMinutes(10); // 20 minutes // Multiplication $doubled = $duration1->multiply(2); // 2 hours // Division $halved = $duration1->divide(2); // 30 minutes
Comparison Operations
Compare durations with various methods:
$duration1 = new Duration(3600); // 1 hour $duration2 = new Duration(7200); // 2 hours $duration3 = new Duration(3600); // 1 hour // Compare two durations $comparisonResult = $duration1->compareTo($duration2); // -1 (less than) // Equality $isEqual = $duration1->equals($duration3); // true $isNotEqual = $duration1->equals($duration2); // false // Greater/less than $isLess = $duration1->lessThan($duration2); // true $isLessOrEqual = $duration1->lessThanOrEqual($duration3); // true $isGreater = $duration2->greaterThan($duration1); // true $isGreaterOrEqual = $duration1->greaterThanOrEqual($duration3); // true // Check if between two durations $isBetween = $duration1->between( new Duration(1800), // 30 minutes new Duration(10800), // 3 hours true // inclusive (default) ); // true
Comparing with Arrays of Durations
Compare a duration against multiple durations using ALL or ANY modes:
$duration = new Duration(3600); // 1 hour $durations = [ new Duration(1800), // 30 minutes new Duration(7200), // 2 hours new Duration(10800) // 3 hours ]; // ALL mode (default) - the condition must be true for ALL durations in the array $isLessThanAll = $duration->lessThan($durations, Duration::COMPARE_ALL); // false $isGreaterThanAll = $duration->greaterThan($durations, Duration::COMPARE_ALL); // false // ANY mode - the condition must be true for AT LEAST ONE duration in the array $isLessThanAny = $duration->lessThan($durations, Duration::COMPARE_ANY); // false $isGreaterThanAny = $duration->greaterThan($durations, Duration::COMPARE_ANY); // true
Increment and Decrement Operations
Increment or decrement durations:
$duration = Duration::fromMinutes(5); // 5 minutes // Increment by 1 second $incremented = $duration->increment(); // 5 minutes 1 second // Increment by specific amount $incrementedByMinute = $duration->incrementBy(60); // 6 minutes // Increment by another duration $anotherDuration = Duration::fromMinutes(10); $combined = $duration->incrementByDuration($anotherDuration); // 15 minutes // Decrement (throws exception if result would be negative) $decremented = $duration->decrement(); // 4 minutes 59 seconds // Decrement by specific amount (throws exception if result would be negative) $decrementedByMinute = $duration->decrementBy(60); // 4 minutes // Safe decrement (returns zero if result would be negative) $safeDecremented = $duration->safeDecrement(); // 4 minutes 59 seconds // Safe decrement by specific amount (returns zero if result would be negative) $safeDecrementedByTooMuch = $duration->safeDecrementBy(600); // 0 seconds
Formatting Methods
Format durations in different ways:
$duration = Duration::fromISO8601('P1Y2M3DT4H5M6S'); // Convert to array of components $array = $duration->toArray(); /* [ 'years' => 1, 'months' => 2, 'days' => 3, 'hours' => 4, 'minutes' => 5, 'seconds' => 6 ] */ // Format using a custom template $formatted = $duration->format('Years: %Y, Months: %M, Days: %D, Time: %H:%I:%S'); // "Years: 01, Months: 02, Days: 03, Time: 04:05:06" // Human-readable format $readable = $duration->toHumanReadable(); // "01:02:03:04:05:06"
Format Placeholders
The format() method supports the following placeholders:
| Placeholder | Description |
|---|---|
%Y |
Years (zero-padded) |
%M |
Months (zero-padded) |
%D |
Days (zero-padded) |
%H |
Hours (zero-padded) |
%I |
Minutes (zero-padded) |
%S |
Seconds (zero-padded) |
%T |
Total seconds |
Serialization
The Duration class implements JsonSerializable and Stringable interfaces:
$duration = Duration::fromISO8601('P1Y2M3DT4H5M6S'); // Convert to string (ISO 8601 format) echo (string)$duration; // "P1Y2M3DT4H5M6S" // JSON serialization $json = json_encode($duration); /* { "seconds": 37090998, "iso8601": "P1Y2M3DT4H5M6S", "components": { "years": 1, "months": 2, "days": 3, "hours": 4, "minutes": 5, "seconds": 6 } } */
DateInterval Conversion
Convert between Duration and PHP's DateInterval:
// Create from DateInterval $interval = new \DateInterval('P1YT6H'); $duration = Duration::fromDateInterval($interval); // Convert to DateInterval $newInterval = $duration->toDateInterval(); echo $newInterval->format('%y years, %h hours'); // "1 years, 6 hours"
Examples
Creating a Countdown Timer
// Create a 5-minute countdown timer $countdownDuration = Duration::fromMinutes(5); // Simulate countdown (in a real application, this would be in a loop with sleep) for ($i = 0; $i < 5; $i++) { echo "Remaining: " . $countdownDuration->toHumanReadable() . PHP_EOL; $countdownDuration = $countdownDuration->decrementBy(60); // Decrease by 1 minute } echo "Time's up!";
Working with Events
// Event duration $eventDuration = Duration::fromHours(2); // Check if event is longer than 1 hour but shorter than 3 hours $isReasonableLength = $eventDuration->between( Duration::fromHours(1), Duration::fromHours(3) ); // Create a 15-minute break $breakDuration = Duration::fromMinutes(15); // Add 15-minute break at the end $totalDuration = $eventDuration->add($breakDuration); echo "Total event duration: " . $totalDuration->toHumanReadable();
Tracking Task Time
// Start time stored in database as seconds $taskTimeSeconds = 3600; // 1 hour already tracked $taskDuration = new Duration($taskTimeSeconds); // User works for 45 more minutes $additionalTime = Duration::fromMinutes(45); $updatedTaskDuration = $taskDuration->add($additionalTime); // Get task time components for display $components = $updatedTaskDuration->toArray(); $hours = $components['hours'] ?? 0; $minutes = $components['minutes'] ?? 0; echo "Task time: {$hours}h {$minutes}m";
Testing
Run the PHPUnit tests:
composer test
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
bermudaphp/duration 适用场景与选型建议
bermudaphp/duration 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 05 月 09 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「iso8601」 「duration」 「immutable」 「value-object」 「php84」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 bermudaphp/duration 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 bermudaphp/duration 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 bermudaphp/duration 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Immutable, timezone-aware date and time types with Duration, Period, and Interval
Convert a value in seconds into a human-readable convenience duration
Convert durations into human-readable timestamps.
Classes for manipulate dates and intervals with microseconds precision
laravel iso8601 date validation package
Converts between colon formatted time, human-readable time and seconds
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 25
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-05-09