anjan-talukdar/laravel-user-timezone

Seamless user timezone handling and dynamic Eloquent timestamp conversion for Laravel applications.

Maintainers

Package info

github.com/anjan-talukdar/laravel-user-timezone

pkg:composer/anjan-talukdar/laravel-user-timezone

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-29 05:41 UTC

This package is auto-updated.

Last update: 2026-07-29 06:20:09 UTC


README

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