dcarbone/gotime
Go-inspired time utilities for PHP 8.1+: a Duration type (parse/format like 5s, JSON as nanoseconds) plus helpers to generate DateInterval specs for DateTime add/sub. Includes a Time wrapper around DateTime aiming for Go time.Time-style APIs.
Installation (updated for v1.0.1):
composer require dcarbone/gotime:^1.0
Requires PHP 8.1+ (compatible with Laravel 9+). Breaking: Removed dcarbone/gotime namespace alias; use DCarbone\Go\Time directly.
First Use Case (updated API):
use DCarbone\Go\Time\Duration;
// Parse a duration string (e.g., from API input)
$duration = Duration::parse('1h30m');
// Add to a DateTime (via DateInterval bridge)
$dateTime = new \DateTime();
$dateTime->add($duration->toDateInterval());
// Output: "1h30m" (string cast)
echo $duration->format(); // New method in v1.0.1
Key Entry Points (updated):
Duration::parse('5s') → Parse strings like "5s", "2h45m" (replaces Time::ParseDuration).new Duration(5, 'second') → Construct from numeric values + unit (replaces Time\Duration constructor).$duration->toDateInterval() → Convert to PHP’s DateInterval (replaces DateInterval()).$duration->format() → New! Human-readable string output (e.g., "1h30m").$duration = Duration::parse('1.5h'); // 5400 seconds (1h30m)
$total = Duration::parse('1h')->add(Duration::parse('30m'));
$json = json_encode($duration->nanoseconds()); // 5400000000000
$string = $duration->format(); // "1h30m" (new!)
Time class)use DCarbone\Go\Time\Time;
$now = Time::now(); // Returns Time instance (replaces `Time::Now()`)
$future = $now->add(Duration::parse('2h'));
$past = $now->subtract(Duration::parse('30m'));
$diff = $now->until($future); // Returns Duration
DateTime:
$dateTime = new \DateTime();
$dateTime->add($duration->toDateInterval()); // Modifies in-place
Time class):
$result = Time::now()
->add(Duration::parse('1h'))
->subtract(Duration::parse('15m'));
// Incoming request (e.g., "timeout": "5s")
$timeout = Duration::parse(request('timeout'));
// Outgoing response (e.g., "duration_nanos": 5000000000)
return ['duration_nanos' => $timeout->nanoseconds()];
Register facade for global access (optional):
// app/Providers/AppServiceProvider.php
use DCarbone\Go\Time\Facades\Duration;
use DCarbone\Go\Time\Facades\Time;
public function boot()
{
if (! class_exists(Duration::class)) {
\Facade\Ignition::warning('gotime facade not found. Install via composer.');
}
}
Handle Duration fields in Eloquent:
// app/Models/Job.php
protected $casts = [
'duration' => \DCarbone\Go\Time\Duration::class,
];
// Parse from DB (e.g., "1h")
public function getDurationAttribute($value) {
return Duration::parse($value);
}
// Serialize to DB (e.g., "1h")
public function setDurationAttribute($value) {
$this->attributes['duration'] = $value instanceof Duration
? $value->format()
: $value;
}
Use gotime for scheduled tasks:
// app/Console/Commands/ProcessQueue.php
public function handle()
{
$timeout = Duration::parse('10s');
$this->processJobsUntil($timeout);
}
Enforce time-based constraints:
// app/Http/Middleware/RateLimit.php
public function handle($request, Closure $next)
{
$window = Duration::parse('1m');
// ... rate limiting logic using $window
}
Assert durations in tests:
use DCarbone\Go\Time\Duration;
public function testDurationParsing()
{
$duration = Duration::parse('1h30m');
$this->assertEquals('1h30m', $duration->format());
$this->assertEquals(5400, $duration->seconds());
}
Explicitly set timezone on Time operations:
$time = Time::now()->inTimezone('UTC');
$future = $time->add(Duration::parse('1h'));
Time::ParseDuration() and Time\Duration are removed. Use Duration::parse() and DCarbone\Go\Time\Duration instead.- use DCarbone\Go\Time;
+ use DCarbone\Go\Time\Duration;
- $duration = Time::ParseDuration('1h');
+ $duration = Duration::parse('1h');
Duration::parse('0.05s') may return 0s due to internal conversion.$duration = Duration::parse('50ms'); // Safe
Time is timezone-aware but defaults to system timezone. Operations like add() use the Time instance’s timezone.$time = Time::now()->inTimezone('America/New_York');
json_encode() requires explicit conversion to nanoseconds or use format() for strings.$json = json_encode($duration->nanoseconds()); // Integer
$string = $duration->format(); // Human-readable
DateInterval may not handle all edge cases (e.g., 24h + 1s).if ($duration->hours() > 24) {
throw new \InvalidArgumentException('Duration too large');
}
Time::Now(), Time\Duration, and DateInterval() are deprecated. Use Time::now(), Duration::parse(), and toDateInterval().DurationDuration objects are now immutable. Methods like add() return a new Duration instead of modifying in-place.$newDuration = $duration->add(Duration::parse('1h')); // Returns new Duration
How can I help you explore Laravel packages today?