使用 i18n 支持在 PHP 中解析、验证、操作和显示日期。受 moment.js 启发。

2.0.5 2017-12-04 14:39 UTC

README

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

Build Status Total Downloads

变更日志

简介

注意

此版本是 fightbulc/moment.php 的分支,仅在更改被维护者接受之前临时使用。

什么是 moment.php?

解析、操作和格式化日期的国际化日期库。

有任何依赖项吗?

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

安装

通过 composer 轻松安装。还不知道 composer 是什么?请在此处了解信息 这里

composer require northern-lights/moment

或者手动添加到 composer.json

{
    "require": {
        "northern-lights/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

另一种以 OOP 风格设置区域设置的方法(依赖注入)

// set Norwegian locale - at this very moment, few locales are supported for this way
\Moment\Moment::setLocale(new \Moment\Locales\no_NB());

// You can also override locale definitions on the fly:
\Moment\Moment::setLocale(new \Moment\Locales\no_NB([
    'relativeTime' => [
        'future' => 'in %s'
    ]
]));

(...)

目前支持的语言

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
pl_PL 波兰语
pt_BR 葡萄牙语(巴西)
pt_PT 葡萄牙语(葡萄牙)
ru_RU 俄语(基本版本)
es_ES 西班牙语(欧洲)
se_SV 瑞典语
no_NB 挪威语 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 的一部分。如果您的区域设置尚不存在,请添加它。请参阅 法语区域设置 的示例。

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相同的过程:通过将原始时刻设置为时间单位的开头/结尾来修改原始时刻。

$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的周期。

获取未来几周指定星期的日期

对于我的一个客户,我需要通过选定的星期几获取时刻。任务如下:给我下三个星期中星期二和星期四的日期。因此,我添加了一个小型处理器,正好能完成这个任务。结果您将收到一个填充有Moment Objects的数组。

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

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

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

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

路线图

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

变更日志

2.0.0

  • 修复
    • en_GB OOP
    • sv_SE OOP
    • pt_BR OOP
    • pt_PT OOP
    • fr_FR
  • 其他
    • 本地化使用新的数组语法,因此杀死了对PHP5.4的支持(PHP5.3)

1.27.0

  • 添加
    • OOP方式设置本地化(依赖注入)
      • 允许通过单独的composer模块打包本地化
      • 允许动态覆盖本地化的定义
    • 挪威本地化(no_NB)

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中的token是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格式化的组合)
      • 例如,对于年份中的21周WS现在显示正确的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

本软件及其相关文档文件(以下简称“软件”)的使用权,在此免费授予任何获得副本的个人,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许获得软件的个人进行此类操作,但需遵守以下条件:

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

软件按“原样”提供,不提供任何形式的保证,无论是明示的、默示的,包括但不限于适销性、特定目的适用性和非侵权性保证。在任何情况下,作者或版权所有者不对任何索赔、损害或其他责任承担责任,无论该责任源于合同、侵权或其他方式,与软件本身、使用或以其他方式与软件相关的活动有关。