共享办公室编辑 - 使用 i18n 支持解析、验证、操作和显示 PHP 中的日期。受 moment.js 启发

1.27 2018-10-11 06:13 UTC

README

                                      _           _           
 _ __ ___   ___  _ __ ___   ___ _ __ | |_   _ __ | |__  _ __  
| '_ ` _ \ / _ \| '_ ` _ \ / _ \ '_ \| __| | '_ \| '_ \| '_ \
| | | | | | (_) | | | | | |  __/ | | | |_ _| |_) | | | | |_) |
|_| |_| |_|\___/|_| |_| |_|\___|_| |_|\__(_) .__/|_| |_| .__/
                                           |_|         |_|    

Build Status Total Downloads

变更日志

简介

什么是 moment.php?

日期库,用于解析、操作和格式化带有 i18n 的日期。

有依赖关系吗?

PHP 5.3 或更高版本,因为 moment.php 基于 php 的 DateTime 类

安装

通过 composer 简单安装。还不知道 composer 是什么?请在此处了解 这里

{
    "require": {
        "fightbulc/moment": "*"
    }
}

快速示例

获取一个时刻

$m = new \Moment\Moment(); // default is "now" UTC
echo $m->format(); // e.g. 2012-10-03T10:00:00+0000

$m = new \Moment\Moment('now', 'Europe/Berlin');
echo $m->format(); // e.g. 2012-10-03T12:00:00+0200

$m = new \Moment\Moment('2017-06-06T10:00:00', 'Europe/Berlin');
echo $m->format(); // e.g. 2012-10-03T12:00:00+0200

$m = new \Moment\Moment(1499366585);
echo $m->format(); // e.g. 2017-07-06T18:43:05+0000

接受的日期格式

Moment 可以解析以下日期格式作为输入

const ATOM = 'Y-m-d\TH:i:sP'; // 2005-08-15T15:52:01+00:00
const COOKIE = 'l, d-M-y H:i:s T'; // Monday, 15-Aug-2005 15:52:01 UTC
const ISO8601 = 'Y-m-d\TH:i:sO'; // 2005-08-15T15:52:01+0000
const RFC822 = 'D, d M y H:i:s O'; // Mon, 15 Aug 05 15:52:01 +0000
const RFC850 = 'l, d-M-y H:i:s T'; // Monday, 15-Aug-05 15:52:01 UTC
const RFC1036 = 'D, d M y H:i:s O'; // Mon, 15 Aug 05 15:52:01 +0000
const RFC1123 = 'D, d M Y H:i:s O'; // Mon, 15 Aug 2005 15:52:01 +0000
const RFC2822 = 'D, d M Y H:i:s O'; // Mon, 15 Aug 2005 15:52:01 +0000
const RSS = 'D, d M Y H:i:s O'; // Mon, 15 Aug 2005 15:52:01 +0000
const W3C = 'Y-m-d\TH:i:sP'; // 2005-08-15T15:52:01+00:00

// Moment also tries to parse dates without timezone or without seconds

const NO_TZ_MYSQL = 'Y-m-d H:i:s'; // 2005-08-15 15:52:01
const NO_TZ_NO_SECS = 'Y-m-d H:i'; // 2005-08-15 15:52
const NO_TIME = 'Y-m-d'; // 2005-08-15

// time fractions ".000" will be automatically removed
$timeWithFraction = '2016-05-04T10:00:00.000';

切换区域设置

查看 Locales 文件夹以查看所有支持的语言。默认区域设置为 en_GB

$m = new \Moment\Moment();
echo $m->format('[Weekday:] l'); // e.g. Weekday: Wednesday

// set german locale
\Moment\Moment::setLocale('de_DE');

$m = new \Moment\Moment();
echo $m->format('[Wochentag:] l'); // e.g. Wochentag: Mittwoch

目前支持的语言

ar_TN 阿拉伯(突尼斯)
ca_ES 加泰罗尼亚语
zh_CN 中文
zh_TW 繁体中文
cs_CZ 捷克语
da_DK 丹麦语
nl_NL 荷兰语
en_GB 英语(英国)
en_US 英语(美国)
fr_FR 法语(欧洲)
de_DE 德语(德国)
hu_HU 匈牙利语
in_ID 印度尼西亚语
it_IT 意大利语
ja_JP 日语
oc_LNC Lengadocian lv_LV 拉脱维亚语(拉脱维亚语) pl_PL 波兰语
pt_BR 葡萄牙语(巴西)
pt_PT 葡萄牙语(葡萄牙)
ru_RU 俄语(基本版本)
es_ES 西班牙语(欧洲)
se_SV 瑞典语
uk_UA 乌克兰语
th_TH 泰语
tr_TR 土耳其语
vi_VN 越南语

切换时区

$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
echo $m->setTimezone('UTC')->format(); // 2012-04-25T01:00:00+0000

更改默认时区

\Moment\Moment::setDefaultTimezone('CET');

$m = new \Moment\Moment('2016-09-13T14:32:06');
echo $m->format(); // 2016-09-13T14:32:06+0100

自定义格式

I. PHP 仅(标准)

$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
echo $m->format('l, dS F Y / H:i (e)'); // Wednesday, 25th April 2012 / 03:00 (Europe/Berlin)

格式基于 PHP 的 Date 函数DateTime 类

II. 非PHP格式

您现在可以通过传递一个实现 FormatsInterface 的类来注入不同的格式处理。您可以在测试文件夹中找到实现所有格式的 moment.js 示例。感谢 Ashish 花时间将 moment.js 格式与 PHP 格式匹配。请查看 测试脚本 以查看示例操作。

每个人都可以以相同的方式编写格式类。它既简单又可扩展。

// get  desired formats class
// create a moment
$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');

// format with moment.js definitions
echo $m->format('LLLL', new \Moment\CustomFormats\MomentJs()); // Wednesday, April 25th 2012 3:00 AM

每个 Locale 也可以有 Custom formats。如果您的区域设置还没有,请添加它。请参阅 法语区域设置 的示例。

III. 简单文本转义

只需将所有文本包裹在 [] 中,所有字符都将自动为您转义。

$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
echo $m->format('[We are in the month of:] F'); // We are in the month of: April

IV. 固定的序数表示

PHP 的内部序数计算似乎有bug。我添加了一个快速修复来处理这个问题。

以下示例打印给定日期的年份中的周。它应该打印 22nd

// internal function
date('WS', mktime(12, 22, 0, 5, 27, 2014)); // 22th

// moment.php
$m = new \Moment\Moment('2014-05-27T12:22:00', 'CET');
$m->format('WS'); // 22nd

创建自定义时刻并操作它

I. 过去/未来时刻

$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
echo $m->addHours(2)->format(); // 2012-05-15T14:30:00+0200

$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
echo $m->subtractDays(7)->subtractMinutes(15)->format(); // 2012-05-08T12:15:00+0200

$m = new \Moment\Moment('@1401443979', 'CET'); // unix time
echo $m->subtractDays(7)->subtractMinutes(15)->format(); // 2014-05-23T09:44:39+0000

II. 复制一个给定的时刻

有时,使用 cloning() 不更改原始时刻并对其操作是有用的。

$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
$c = $m->cloning()->addDays(1);

echo $m->getDay(); // 15
echo $c->getDay(); // 16

或者,您可以在源处启用不可变模式。

$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET', true);
$c = $m->addDays(1);

echo $m->getDay(); // 15
echo $c->getDay(); // 16

// You can also change the immutable mode after creation:
$m->setImmutableMode(false)->subtractDays(1);

echo $m->getDay(); // 14

不可变模式会在应用修改之前,隐式地调用所有修改方法中的 cloning()

III. 日期/时间操作方法

IV. 设置器/获取器

日期之间的差异

$m = new \Moment\Moment('2013-02-01T07:00:00');
$momentFromVo = $m->fromNow();

// or from a specific moment
$m = new \Moment\Moment('2013-02-01T07:00:00');
$momentFromVo = $m->from('2011-09-25T10:00:00');

// result comes as a value object class
echo $momentFromVo->getDirection()  // "future"
echo $momentFromVo->getSeconds()    // -42411600
echo $momentFromVo->getMinutes()    // -706860
echo $momentFromVo->getHours()      // -11781
echo $momentFromVo->getDays()       // -490.88
echo $momentFromVo->getWeeks()      // -70.13
echo $momentFromVo->getMonths()     // -17.53
echo $momentFromVo->getYears()      // -1.42
echo $momentFromVo->getRelative()   // in a year

获取日期周期(周、月、季度)

有时获取给定日期的周期界限很有用。例如,如果今天是星期三,我需要从今天开始这一周的起始/结束日期。允许的周期为 weekmonthquarter

$m = new \Moment\Moment('2013-10-23T10:00:00');
$momentPeriodVo = $m->getPeriod('week');

// results comes as well as a value object class
echo $momentPeriodVo
    ->getStartDate()
    ->format('Y-m-d'); // 2013-10-21

echo $momentPeriodVo
    ->getEndDate()
    ->format('Y-m-d'); // 2013-10-27

echo $momentPeriodVo
    ->getRefDate()
    ->format('Y-m-d'); // 2013-10-23

echo $momentPeriodVo->getInterval(); // 43 = week of year

对于月度和季度周期,采用相同的程序。

$momentPeriodVo = $m->getPeriod('month');
$momentPeriodVo = $m->getPeriod('quarter');

日历时间

日历时间显示相对于 now 的时间,但与 Moment::fromNow() 稍有不同。Moment::calendar() 将根据日期与今天的接近程度使用不同的字符串格式化日期。

(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->subtractDays(6)->calendar(); // last week
(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->subtractDays(1)->calendar(); // yesterday
(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->calendar(); // today
(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->addDays(1)->calendar(); // tomorrow
(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->addDays(3)->calendar(); // next week
(new \Moment\Moment('2014-03-30T16:58:00', 'CET'))->addDays(10)->calendar(); // everything else

注意:使用 $moment->calendar(false) 可以省略时间 at 00:00

startOf / endOf

与 moment.js 相同的过程:通过将原始 moment 设置为时间单位的开头/结尾来修改原始 moment。

$m = new \Moment\Moment('20140515T10:15:23', 'CET');

$m->startOf('year');    // set to January 1st, 00:00 this year
$m->startOf('quarter');  // set to the beginning of the current quarter, 1st day of months, 00:00
$m->startOf('month');   // set to the first of this month, 00:00
$m->startOf('week');    // set to the first day of this week, 00:00
$m->startOf('day');     // set to 00:00 today
$m->startOf('hour');    // set to now, but with 0 mins, 0 secs
$m->startOf('minute');  // set to now, but with 0 seconds

$m->endOf('year');    // set to December 31st, 23:59 this year
$m->endOf('quarter');  // set to the end of the current quarter, last day of month, 23:59
$m->endOf('month');   // set to the last of this month, 23:59
$m->endOf('week');    // set to the last day of this week, 23:59
$m->endOf('day');     // set to 23:59 today
$m->endOf('hour');    // set to now, but with 59 mins, 59 secs
$m->endOf('minute');  // set to now, but with 59 seconds

注意:我忽略了 second 的周期,因为我们不处理毫秒。

获取未来几周指定工作日的日期

对于我的一个客户,我需要通过选定的工作日获取 moments。任务如下:给我接下来的三周内 星期二星期四 的日期。所以我添加了一个小处理程序,它正好能完成这个任务。结果您将收到一个填充有 Moment 对象 的数组。

// 1 - 7 = Mon - Sun
$weekdayNumbers = [
    2, // tuesday
    4, // thursday
];

$m = new \Moment\Moment();
$dates = $m->getMomentsByWeekdays($weekdayNumbers, 3);

// $dates = [Moment, Moment, Moment ...]

现在您可以遍历结果,并将其格式化为下拉字段或您可能需要的任何其他格式。

路线图

  • 尝试移植 moment.js 中的有用方法
  • 添加单元测试

变更日志

1.26.10

  • 修复
    • 奥克西塔尼亚语区域

1.26.9

1.26.8

  • 添加
    • 葡萄牙语 (pt_PT)

1.26.7

  • 修复
    • 匈牙利语区域工作日顺序

1.26.6

  • 添加
    • 允许使用不带前导 @ 的 Unix 时间戳初始化 Moment

1.26.5

  • 修复
    • 修复自定义格式中的 'LLL' 格式

1.26.4

  • 修复
    • 移除了 php5.4+ 专用语法

1.26.3

  • 修复
    • 丹麦语中的日期和月份名称正确的大小写
    • 法语区域
    • PHPDocs
  • 添加
    • 在解析日期时,为 NO_TZ_MYSQLNO_TZ_NO_SECSNO_TIME 添加了常量

1.26.2

  • 添加
    • 荷兰语自定义格式

1.26.1

  • 修复
    • 俄语区域

1.26.0

  • 添加
    • 土耳其语区域
  • 修复
    • 朗格多克语区域

1.25.1

  • 修复
    • PHP7.1 setTime 需要 $microseconds

1.25

  • 添加
    • 乌克兰语区域

1.24

  • 添加
    • 匈牙利语区域

1.23.1

  • 修复
    • 朗格多克语区域

1.23.0

  • 添加
    • 越南语区域
    • 朗格多克语区域

1.22.0

  • 添加
    • 更改默认时区
  • 修复
    • FormatsInterface 文档

1.21.0

  • 添加
    • 阿拉伯语区域
    • 在区域级别上自定义格式

1.20.9

  • 修复
    • 俄语区域
  • 添加
    • 俄语区域测试

1.20.8

  • 修复
    • 波兰语区域
    • 秒的计算

1.20.7

  • 修复
    • 俄语:更多相对时间修复

1.20.6

  • 修复
    • 俄语区域相对时间:处理天

1.20.5

  • 修复
    • 缺少不可变处理

1.20.4

  • 修复
    • 改进波兰语区域(添加 Nominativ)

1.20.3

  • 修复
    • 中文区域

1.20.2

  • 添加了接受格式到 README

1.20.1

  • 修复
    • 泰语区域

1.20.0

  • 添加
    • 加泰罗尼亚语区域
  • 修复
    • 波兰语区域测试

1.19.0

  • 添加
    • 俄语区域
  • 修复
    • 波兰语区域测试

1.18.0

  • 添加
    • 不可变模式
  • 修复
    • 波兰语区域

1.17.0

  • 添加
    • 波兰语区域

1.16.0

  • 添加
    • 印度尼西亚语区域

1.15.0

  • 添加
    • 日语区域

1.14.1

  • 修复
    • 荷兰语区域中的错误

1.14.0

  • 添加
    • 荷兰语区域

1.13.0

  • 添加
    • 瑞典语区域

1.12.0

  • 添加
    • 丹麦语区域

1.11.4

  • 修复
    • 修复了罗马尼亚语区域的起始/结束工作日

1.11.3

  • 修复
    • 为意大利语区域添加分隔符字符

1.11.1

  • 修复
    • 对于周、月、季度,startOf/endOf 返回新实例

1.11.0

  • 添加
    • 捷克语区域

1.10.4

  • 添加
    • calendar 区域接收以下参数的闭包:function(Moment $m) {}
    • relativeTime 区域接收以下参数的闭包:function($count, $direction, Moment $m) {}

1.10.3

  • 添加
    • 修复了传递闭包到区域(calendar、relativeTime)的问题
    • 设置正确的德语区域信息

1.10.2

  • 添加
    • 修复了泰语区域字符串

1.10.1

  • 添加
    • 传统中文区域

1.10.0

  • 添加
    • 中文区域
    • 序数格式化器现在接收 token,例如 dS 中的 d

1.9.1

  • 修复:11至13之间的数字的英语序数问题

1.9.0

  • 添加:意大利语区域

1.8.1

  • 修复:英语序数问题

1.8.0

  • 添加:葡萄牙语区域

1.7.2

  • 修复
    • 显示的区域中月份名称错误 (#34)
    • 更改了区域文件中星期的顺序

1.7.1

  • 添加
    • getWeekdayNameLong()
    • getWeekdayNameShort()
    • getMonthNameLong()
    • getMonthNameShort()

1.7.0

  • 添加
    • 区域:泰语

1.6.0

  • 添加
    • 区域
    • MomentFromVo
      • getMonths()
      • getYears()
      • getRelative()
  • 修复
    • MomentFromVo
      • getSeconds() 同时显示现在方向

1.5.3

  • 修复
    • 仅对 unixtime 日期发生的时区问题
  • 其他
    • MomentFromVo
      • 方向返回现在: "未来" (-) / "过去" (+)
      • 时间值现在是浮点类型

1.5.2

  • 修复
    • 在构建 Moment 时识别不出时区

1.5.1

  • 添加
    • getMomentsByWeekdays()
    • getWeekday()
    • getWeekOfYear()
  • 其他
    • 转义文本

1.5.0

  • 添加

    • startOf 和 endOf,如 moment.js 实现的那样
    • 获取给定日期的季度周期
    • setDay()
    • getDay()
    • setMonth()
    • getMonth()
    • setYear()
    • getYear()
    • getQuarter()
    • setSecond()
    • getSecond()
    • setMinute()
    • getMinute()
    • setHour()
    • getHour()
    • 添加 cloning()
      • 根据给定实例创建一个新的可变 Moment
    • MomentPeriodVo 添加了 getInterval() 以指示给定周期的间隔
      • week = 年份中的周
      • month = 年份中的月
      • quarter = 年份中的季度
    • 添加了一个静态类 MomentHelper
      • 获取给定年份给定季度的周期
    • 修复了 PHP 的内部序数计算(包括与 moment.js 格式的组合)
      • 例如,WS 表示年份的第 21 周,现在显示为正确的 21th 等。
    • 现在可以通过将文本包裹在 [] 中来转义文本
      • 例如,[Hello World] 将自动转换为 \H\e\l\l\o \W\o\r\l\d
  • 删除

    • add()
    • subtract()

1.4.0

  • 添加
    • 日历格式,如 moment.js 实现的那样

1.3.0

  • 修复

    • 与 PHP 5.3 不兼容
  • 添加

    • 异常作为 MomentException 抛出
    • 实例化时的日期验证
      • 测试格式为 YYYY-mm-ddYYYY-mm-ddTHH:ii:ss 的日期
      • 在无效日期上抛出 MomentException
    • addSeconds()
    • addMinutes()
    • addHours()
    • addDays()
    • addWeeks()
    • addMonths()
    • addYears()
    • subtractSeconds()
    • subtractMinutes()
    • subtractHours()
    • subtractDays()
    • subtractWeeks()
    • subtractMonths()
    • subtractYears()
  • 已弃用

    • add()
    • subtract()

许可

Moment.php 可以在 MIT 许可证的条款下自由分发。

版权 (c) 2017 Tino Ehrich

特此授予任何获得此软件和相关文档副本(“软件”)的人免费处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许向获得软件的人提供软件,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和侵权不保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论这些责任是基于合同、侵权或其他方式产生,是否与软件或其使用或其他交易有关。