承接 petrknap/zoned-datetime-persistence 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

petrknap/zoned-datetime-persistence

Composer 安装命令:

composer require petrknap/zoned-datetime-persistence

包简介

Timezone aware date-time persistence

README 文档

README

GitHub JitPack Packagist

Many data storage systems (like MySQL) do not natively support storing timezone information alongside date-time values. This limitation introduces ambiguity when handling zoned date-times — particularly in applications operating across multiple timezones or even within a single timezone that observes multiple offsets (e.g. due to daylight saving time).

This package addresses the issue by providing tools that treat zoned date-time as a pair consisting of:

  • the UTC date-time value, and
  • a companion value that explicitly captures the corresponding timezone information.

Implemented

UTC with local date-time

UtcWithLocal

The most useful approach is to store the UTC date-time together with its local counterpart. This dual representation enables seamless manipulation of date-time values directly within storage system. The local date-time is ideal for grouping and filtering based on user or business context, while the UTC value ensures consistent and accurate sorting across timezones.

How to use it

There is built-in support for the Jakarta Persistence API (see Note.java and JpaTest.java), the Doctrine ORM (see Note.php and DoctrineTest.php), the Eloquent (see NoteModel.php and EloquentTest.php), and, of course, it can be integrated manually into any project, giving you full flexibility to adapt it to your specific needs.

namespace PetrKnap\Persistence\ZonedDateTime;

$em = DoctrineTest::prepareEntityManager();

# persist entity
$em->persist(new Some\Note(
    createdAt: new \DateTimeImmutable('2025-10-30 23:52'),
    content: "It's dark outside...",
));
$em->flush();

# insert data manually (static call)
$now = new \DateTimeImmutable('2025-10-26 02:45', new \DateTimeZone('CEST'));
$em->getConnection()->insert('notes', [
    'created_at__utc' => ZonedDateTimePersistence::computeUtcDateTime($now)->format('Y-m-d H:i:s'),
    'created_at__local' => $now->format('Y-m-d H:i:s'),
    'content' => 'We still have summer time',
]);

# insert data manually (object instance)
$now = new UtcWithLocal(new \DateTimeImmutable('2025-10-26 02:15', new \DateTimeZone('CET')));
$em->getConnection()->insert('notes', [
    'created_at__utc' => $now->getUtcDateTime('Y-m-d H:i:s'),
    'created_at__local' => $now->getLocalDateTime('Y-m-d H:i:s'),
    'content' => 'Now we have winter time',
]);

# select entities
$notes = $em->createQueryBuilder()
    ->select('note')
    ->from(Some\Note::class, 'note')
    ->where('note.createdAt.local BETWEEN :from AND :to')
    ->orderBy('note.createdAt.utc')
    ->getQuery()
    ->execute(['from' => '2025-10-26 00:00', 'to' => '2025-10-26 23:59']);
foreach($notes as $note) {
    echo $note->getCreatedAt()->format('Y-m-d H:i T') . ': '. $note->getContent() . PHP_EOL;
}
2025-10-26 02:45 GMT+0200: We still have summer time
2025-10-26 02:15 GMT+0100: Now we have winter time

UTC with timezone

UtcWithTimezone

If you want to preserve the original timezone as is, you cannot use UtcWithLocal, because it works over fixed offsets. In this case, you need to use this implementation.

namespace PetrKnap\Persistence\ZonedDateTime;

$now = (new \DateTime('2025-03-30 01:45', new \DateTimeZone('Europe/Prague')));

echo 'UtcWithTimezone: ' . (new UtcWithTimezone($now))
    ->toZonedDateTime()
    ->modify('+1 hour')
    ->format('Y-m-d H:i T' . PHP_EOL);
echo 'UtcWithLocal:    ' . (new UtcWithLocal($now))
    ->toZonedDateTime()
    ->modify('+1 hour')
    ->format('Y-m-d H:i T' . PHP_EOL);
UtcWithTimezone: 2025-03-30 03:45 CEST
UtcWithLocal:    2025-03-30 02:45 GMT+0100

UTC with system timezone

UtcWithSystemTimezone

The most compact approach is to store only the UTC date-time. This serves as an alternative to MySQL's TIMESTAMP, Postgres's TIMESTAMP WITH TIMEZONE, and custom ORM types. It offers full range of DateTime, avoids normalization on connection, adds .utc into your queries for better readability and didn't need special configuration.

UTC date-time converter / type / cast

UtcDateTimeConverter Jakarta Persistence API

This converter transparently manages conversions of ZonedDateTime, including JPQL parameters. That means you no longer need to worry about manual timezone adjustments.

For examples, see the attributes Note.createdAtUtc and Note.deletedAtUtc and the JpaTest.

UtcDateTimeType Doctrine ORM

In contrast to UtcDateTimeConverter, this type does not automatically adjust the timezone of DQL parameters. You must therefore provide the type when you are calling setParameter on your queries. Also, you have to register the type in your Doctrine configuration manually.

For examples, see the attributes Note.createdAtUtc and Note.deletedAtUtc and the DoctrineTest.

AsUtcDateTime Eloquent

In contrast to UtcDateTimeConverter and UtcDateTimeType, this cast may or may not adjust the timezone of any input. You should therefore handle timezone conversions explicitly everytime you are providing date-time into Eloquent. But the conversion after hydration works well.

For examples, see the attributes NoteModel.created_at_utc and NoteModel.deleted_at_utc and the EloquentTest.

You can support this project via donation. The project is licensed under the terms of the LGPL-3.0-or-later.

petrknap/zoned-datetime-persistence 适用场景与选型建议

petrknap/zoned-datetime-persistence 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.74k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 06 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「orm」 「persistence」 「sql」 「doctrine」 「helper」 「dql」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 petrknap/zoned-datetime-persistence 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 petrknap/zoned-datetime-persistence 我们能提供哪些服务?
定制开发 / 二次开发

基于 petrknap/zoned-datetime-persistence 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.74k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 42
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: LGPL-3.0-or-later
  • 更新时间: 2025-11-06