Looking to hire Laravel developers? Try LaraJobs

laravel-user-timezone maintained by anjan-talukdar

Description
Seamless user timezone handling and dynamic Eloquent timestamp conversion for Laravel applications.
Author
Anjan Talukdar
Last update
2026/07/29 08:19 (dev-main)
License
Links
Downloads
1

Comments
comments powered by Disqus

Laravel User Timezone

Latest Version on Packagist Total Downloads License PHP Version Laravel Version

A lightweight, zero-boilerplate Laravel package that automatically displays timestamps and custom datetime columns in the user's local timezone—without cluttering your Blade views, API resources, or controllers.


🚀 Key Features

  • Automatic Timezone Resolution Hierarchy:
    1. Authenticated User model setting ($user->timezone)
    2. Browser cookie (user_timezone) auto-set via lightweight JS snippet
    3. Session value (session('user_timezone'))
    4. Configured default fallback (Asia/Kolkata or your custom default)
  • Single Unified Trait (HasUserTimezone):
    • Automatically converts standard timestamps (created_at, updated_at, deleted_at).
    • Automatically converts any custom attribute declared in Eloquent $casts as 'datetime'.
  • Database Persistence Safety:
    • Ensures dates are always stored in UTC in your database, while presenting them in local time upon retrieval and JSON serialization.
  • Global Helper Function: user_timezone() available anywhere in your application.
  • API & Serialization Ready: Automatically formats dates in JSON responses for REST APIs, Filament, Inertia.js, and Blade templates.

📋 Requirements

  • PHP ^8.2
  • Laravel ^10.0 | ^11.0 | ^12.0

📦 Installation

Install the package via Composer:

composer require anjan-talukdar/laravel-user-timezone

Publish Configuration & Migrations

Publish the configuration file and database migration:

php artisan vendor:publish --tag="user-timezone-config"
php artisan vendor:publish --tag="user-timezone-migrations"

Run the migration to add the timezone column to your users table:

php artisan migrate

⚙️ Configuration

The published configuration file config/user-timezone.php allows you to customize the default fallback timezone and cookie name:

return [
    /*
    |--------------------------------------------------------------------------
    | Default Timezone
    |--------------------------------------------------------------------------
    |
    | Fallback timezone when no user or client browser timezone is detected.
    |
    */
    'default' => env('APP_TIMEZONE', 'Asia/Kolkata'),

    /*
    |--------------------------------------------------------------------------
    | Cookie Name
    |--------------------------------------------------------------------------
    |
    | The HTTP cookie key used by the frontend JS auto-detection script.
    |
    */
    'cookie_name' => 'user_timezone',
];

💻 Usage

1. Eloquent Model Integration

Simply add the HasUserTimezone trait to your Eloquent models:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use AnjanTalukdar\UserTimezone\Traits\HasUserTimezone;

class Post extends Model
{
    use HasUserTimezone;

    protected $casts = [
        'published_at' => 'datetime',
        'event_date' => 'datetime',
    ];
}

That's it! When accessing dates, they are automatically returned as Illuminate\Support\Carbon instances converted to the active user's local timezone:

$post = Post::find(1);

// Standard timestamps automatically in user's timezone
echo $post->created_at->format('Y-m-d H:i:s'); 

// Cast datetime attributes automatically in user's timezone
echo $post->published_at->format('M j, Y g:i A'); 

// Access active timezone name
echo $post->created_at->timezoneName; // e.g. "Asia/Kolkata" or "America/New_York"

2. Custom Formatting Helper Method

You can also use the model method formatUserDate() for inline formatting with custom fallback handling:

echo $post->formatUserDate('published_at', 'F j, Y, g:i a');
// Output: "July 29, 2026, 3:30 pm"

3. Global Helper Function

Access the resolved user timezone anywhere in controllers, Blade files, or services:

$currentTz = user_timezone(); 
// Returns e.g. "Asia/Kolkata" or "America/New_York"

4. Client-side Browser Auto-Detection

To automatically detect guest and logged-in user timezones via the browser, import the package JS snippet into your main JavaScript bundle (resources/js/app.js):

import 'path/to/packages/anjan-talukdar/laravel-user-timezone/resources/js/user-timezone.js';

Or add the standalone snippet directly in your HTML <head> or main layout:

<script>
    if (!document.cookie.includes('user_timezone=')) {
        const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
        if (tz) {
            document.cookie = "user_timezone=" + encodeURIComponent(tz) + ";path=/;max-age=31536000;SameSite=Lax";
        }
    }
</script>

🔍 How It Works Under the Hood

   ┌────────────────────────────────────────────────────────┐
   │ 1. User Timezone Resolution                            │
   │    Auth User -> Browser Cookie -> Session -> Default   │
   └───────────────────────────┬────────────────────────────┘
                               │
   ┌───────────────────────────▼────────────────────────────┐
   │ 2. Attribute Access ($model->created_at / $casts)      │
   │    DB stores UTC  ──►  Carbon instance in User TZ     │
   └───────────────────────────┬────────────────────────────┘
                               │
   ┌───────────────────────────▼────────────────────────────┐
   │ 3. Database Storage ($model->save())                   │
   │    Carbon in User TZ  ──► Converted back to UTC in DB  │
   └────────────────────────────────────────────────────────┘
  1. Retrieval: When an attribute is retrieved (created_at, updated_at, deleted_at, or any attribute cast as 'datetime'), HasUserTimezone intercepts the Carbon instance creation and applies .setTimezone(user_timezone()).
  2. Serialization: When converting models to Array or JSON (toArray(), toJson()), dates are formatted in the user's local timezone for API consumers.
  3. Database Safety: When saving models, dates are converted back to UTC (or app default timezone) so your database records remain strictly synchronized and standardized in UTC.

🧪 Testing

Run package tests with PHPUnit:

vendor/bin/phpunit

📜 License

The MIT License (MIT). Please see License File for more information.


👨‍💻 Author

Anjan Talukdar