Feature/new layout (#59)

* go minimal!
* cleanup style
* more whitespace, more awesome
* done with new layout. Moved buttons inside message, to avoid problems with <a> containing another <a> (which is invalid).
* added support for local date. and updated libs.
* new layout
This commit is contained in:
Aravindo Wingeier 2018-06-24 19:31:04 +02:00 committed by GitHub
parent e4652ff62d
commit 567459626d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 6839 additions and 335 deletions

View file

@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
## [Unreleased]
### Breaking Changes
- added $config['locale']. See config.sample.php - you have to set it.
### Changed
- new layout & design with more whitespace and more explanations.
## [0.2.0] - 2018-06-16
### Changed

View file

@ -2,7 +2,8 @@
"require": {
"php-imap/php-imap": "~2.0",
"gnugat/PronounceableWord": "*",
"ezyang/htmlpurifier": "^4.9"
"ezyang/htmlpurifier": "^4.9",
"fightbulc/moment": "*"
},
"config": {
"vendor-dir": "src/backend-libs"

77
composer.lock generated
View file

@ -4,21 +4,21 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "c071b40be7f9bdf56a06a9e52d220684",
"content-hash": "31df20b392f8545dda12635a78572bf7",
"hash": "1175b971ed4569a8c9f93646384529e7",
"content-hash": "4b2136dccba636ec0370e8547b0a738e",
"packages": [
{
"name": "ezyang/htmlpurifier",
"version": "v4.9.3",
"version": "v4.10.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "95e1bae3182efc0f3422896a3236e991049dac69"
"reference": "d85d39da4576a6934b72480be6978fb10c860021"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69",
"reference": "95e1bae3182efc0f3422896a3236e991049dac69",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
"reference": "d85d39da4576a6934b72480be6978fb10c860021",
"shasum": ""
},
"require": {
@ -52,7 +52,70 @@
"keywords": [
"html"
],
"time": "2017-06-03 02:28:16"
"time": "2018-02-23 01:58:20"
},
{
"name": "fightbulc/moment",
"version": "1.26.10",
"source": {
"type": "git",
"url": "https://github.com/fightbulc/moment.php.git",
"reference": "2fe6607fdbbd45b48708f539c70fde89ca9d10e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fightbulc/moment.php/zipball/2fe6607fdbbd45b48708f539c70fde89ca9d10e6",
"reference": "2fe6607fdbbd45b48708f539c70fde89ca9d10e6",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.2.*"
},
"type": "library",
"autoload": {
"psr-4": {
"Moment\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ashish Tilara",
"email": "ashish@itcutives.com",
"role": "developer"
},
{
"name": "Jaroslaw Kozak",
"email": "jaroslaw.kozak68@gmail.com",
"role": "developer"
},
{
"name": "Tino Ehrich",
"email": "tino@bigpun.me",
"role": "developer"
}
],
"description": "Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js",
"keywords": [
"date",
"display",
"format",
"i18n",
"locale",
"manipulate",
"moment",
"parse",
"time",
"translation",
"validate"
],
"time": "2017-08-14 05:06:04"
},
{
"name": "gnugat/PronounceableWord",

View file

@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
return array(
'Moment\\' => array($vendorDir . '/fightbulc/moment/src'),
);

View file

@ -10,6 +10,20 @@ class ComposerStaticInit125dddd280a32cf75b181166154246ec
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
);
public static $prefixLengthsPsr4 = array (
'M' =>
array (
'Moment\\' => 7,
),
);
public static $prefixDirsPsr4 = array (
'Moment\\' =>
array (
0 => __DIR__ . '/..' . '/fightbulc/moment/src',
),
);
public static $prefixesPsr0 = array (
'P' =>
array (
@ -34,6 +48,8 @@ class ComposerStaticInit125dddd280a32cf75b181166154246ec
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit125dddd280a32cf75b181166154246ec::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit125dddd280a32cf75b181166154246ec::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit125dddd280a32cf75b181166154246ec::$prefixesPsr0;
}, null, ClassLoader::class);

View file

@ -90,17 +90,17 @@
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.9.3",
"version_normalized": "4.9.3.0",
"version": "v4.10.0",
"version_normalized": "4.10.0.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "95e1bae3182efc0f3422896a3236e991049dac69"
"reference": "d85d39da4576a6934b72480be6978fb10c860021"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/95e1bae3182efc0f3422896a3236e991049dac69",
"reference": "95e1bae3182efc0f3422896a3236e991049dac69",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
"reference": "d85d39da4576a6934b72480be6978fb10c860021",
"shasum": ""
},
"require": {
@ -109,7 +109,7 @@
"require-dev": {
"simpletest/simpletest": "^1.1"
},
"time": "2017-06-03 02:28:16",
"time": "2018-02-23 01:58:20",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -136,5 +136,70 @@
"keywords": [
"html"
]
},
{
"name": "fightbulc/moment",
"version": "1.26.10",
"version_normalized": "1.26.10.0",
"source": {
"type": "git",
"url": "https://github.com/fightbulc/moment.php.git",
"reference": "2fe6607fdbbd45b48708f539c70fde89ca9d10e6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fightbulc/moment.php/zipball/2fe6607fdbbd45b48708f539c70fde89ca9d10e6",
"reference": "2fe6607fdbbd45b48708f539c70fde89ca9d10e6",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.2.*"
},
"time": "2017-08-14 05:06:04",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Moment\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ashish Tilara",
"email": "ashish@itcutives.com",
"role": "developer"
},
{
"name": "Jaroslaw Kozak",
"email": "jaroslaw.kozak68@gmail.com",
"role": "developer"
},
{
"name": "Tino Ehrich",
"email": "tino@bigpun.me",
"role": "developer"
}
],
"description": "Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js",
"keywords": [
"date",
"display",
"format",
"i18n",
"locale",
"manipulate",
"moment",
"parse",
"time",
"translation",
"validate"
]
}
]

View file

@ -9,6 +9,20 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. Internal change
==========================
4.10.0, released 2018-02-22
# PHP 5.3 is no longer officially supported by HTML Purifier
(we did not specifically break support, but we are no longer
testing on PHP 5.3)
! Relative CSS length units are now supported
- A few PHP 7.2 compatibility fixes, thanks John Flatness
<john@zerocrates.org>
- Improve portability with old versions of libxml which don't
support accessing the data of a node
- IDNA2008 is now used for converting domains to ASCII, fixing
some rather strange bugs with international domains
- Fix race condition resulting in E_WARNING when creating
directories with Serializer
4.9.3, released 2017-06-02
- Workaround PHP 7.1 infinite loop when opcode cache is enabled.
Thanks @Xiphin (#134, #135)

View file

@ -2,7 +2,7 @@ HTML Purifier [![Build Status](https://secure.travis-ci.org/ezyang/htmlpurifier.
=============
HTML Purifier is an HTML filtering solution that uses a unique combination
of robust whitelists and agressive parsing to ensure that not only are
of robust whitelists and aggressive parsing to ensure that not only are
XSS attacks thwarted, but the resulting HTML is standards compliant.
HTML Purifier is oriented towards richly formatted documents from
@ -26,4 +26,4 @@ Package available on [Composer](https://packagist.org/packages/ezyang/htmlpurifi
If you're using Composer to manage dependencies, you can use
$ composer require "ezyang/htmlpurifier": "dev-master"
$ composer require "ezyang/htmlpurifier":"dev-master"

View file

@ -1 +1 @@
4.9.3
4.10.0

View file

@ -0,0 +1,15 @@
<?php
/**
* @file
* Legacy autoloader for systems lacking spl_autoload_register
*
* Must be separate to prevent deprecation warning on PHP 7.2
*/
function __autoload($class)
{
return HTMLPurifierExtras::autoload($class);
}
// vim: et sw=4 sts=4

View file

@ -17,10 +17,7 @@ if (function_exists('spl_autoload_register')) {
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class)
{
return HTMLPurifierExtras::autoload($class);
}
require dirname(__FILE__) . '/HTMLPurifierExtras.autoload-legacy.php';
}
// vim: et sw=4 sts=4

View file

@ -0,0 +1,15 @@
<?php
/**
* @file
* Legacy autoloader for systems lacking spl_autoload_register
*
* Must be separate to prevent deprecation warning on PHP 7.2
*/
function __autoload($class)
{
return HTMLPurifier_Bootstrap::autoload($class);
}
// vim: et sw=4 sts=4

View file

@ -14,10 +14,7 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class)
{
return HTMLPurifier_Bootstrap::autoload($class);
}
require dirname(__FILE__) . '/HTMLPurifier.autoload-legacy.php';
}
if (ini_get('zend.ze1_compatibility_mode')) {

View file

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.9.3
* @version 4.10.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,

View file

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.9.3 - Standards Compliant HTML Filtering
HTML Purifier 4.10.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.9.3';
public $version = '4.10.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.9.3';
const VERSION = '4.10.0';
/**
* Global configuration object.

View file

@ -97,7 +97,7 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// PHP 5.3 and later support this functionality natively
if (function_exists('idn_to_ascii')) {
$string = idn_to_ascii($string);
$string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
// If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do,

View file

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.9.3';
public $version = '4.10.0';
/**
* Whether or not to automatically finalize

View file

@ -217,9 +217,14 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
$directory = $this->generateDirectoryPath($config);
$chmod = $config->get('Cache.SerializerPermissions');
if ($chmod === null) {
// TODO: This races
if (is_dir($directory)) return true;
return mkdir($directory);
if (!@mkdir($directory) && !is_dir($directory)) {
trigger_error(
'Could not create directory ' . $directory . '',
E_USER_WARNING
);
return false;
}
return true;
}
if (!is_dir($directory)) {
$base = $this->generateBaseDirectoryPath($config);
@ -233,7 +238,7 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (!$this->_testPermissions($base, $chmod)) {
return false;
}
if (!mkdir($directory, $chmod)) {
if (!@mkdir($directory, $chmod) && !is_dir($directory)) {
trigger_error(
'Could not create directory ' . $directory . '',
E_USER_WARNING

View file

@ -157,11 +157,13 @@ abstract class HTMLPurifier_Injector
return false;
}
// check for exclusion
for ($i = count($this->currentNesting) - 2; $i >= 0; $i--) {
$node = $this->currentNesting[$i];
$def = $this->htmlDefinition->info[$node->name];
if (isset($def->excludes[$name])) {
return false;
if (!empty($this->currentNesting)) {
for ($i = count($this->currentNesting) - 2; $i >= 0; $i--) {
$node = $this->currentNesting[$i];
$def = $this->htmlDefinition->info[$node->name];
if (isset($def->excludes[$name])) {
return false;
}
}
}
return true;

View file

@ -26,12 +26,14 @@ class HTMLPurifier_Length
protected $isValid;
/**
* Array Lookup array of units recognized by CSS 2.1
* Array Lookup array of units recognized by CSS 3
* @type array
*/
protected static $allowedUnits = array(
'em' => true, 'ex' => true, 'px' => true, 'in' => true,
'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true
'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true,
'ch' => true, 'rem' => true, 'vw' => true, 'vh' => true,
'vmin' => true, 'vmax' => true
);
/**

View file

@ -126,6 +126,41 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
} while ($level > 0);
}
/**
* Portably retrieve the tag name of a node; deals with older versions
* of libxml like 2.7.6
* @param DOMNode $node
*/
protected function getTagName($node)
{
if (property_exists($node, 'tagName')) {
return $node->tagName;
} else if (property_exists($node, 'nodeName')) {
return $node->nodeName;
} else if (property_exists($node, 'localName')) {
return $node->localName;
}
return null;
}
/**
* Portably retrieve the data of a node; deals with older versions
* of libxml like 2.7.6
* @param DOMNode $node
*/
protected function getData($node)
{
if (property_exists($node, 'data')) {
return $node->data;
} else if (property_exists($node, 'nodeValue')) {
return $node->nodeValue;
} else if (property_exists($node, 'textContent')) {
return $node->textContent;
}
return null;
}
/**
* @param DOMNode $node DOMNode to be tokenized.
* @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens.
@ -141,7 +176,10 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
// but we're not getting the character reference nodes because
// those should have been preprocessed
if ($node->nodeType === XML_TEXT_NODE) {
$tokens[] = $this->factory->createText($node->data);
$data = $this->getData($node); // Handle variable data property
if ($data !== null) {
$tokens[] = $this->factory->createText($data);
}
return false;
} elseif ($node->nodeType === XML_CDATA_SECTION_NODE) {
// undo libxml's special treatment of <script> and <style> tags
@ -171,21 +209,20 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
// not-well tested: there may be other nodes we have to grab
return false;
}
$attr = $node->hasAttributes() ? $this->transformAttrToAssoc($node->attributes) : array();
$tag_name = $this->getTagName($node); // Handle variable tagName property
if (empty($tag_name)) {
return (bool) $node->childNodes->length;
}
// We still have to make sure that the element actually IS empty
if (!$node->childNodes->length) {
if ($collect) {
$tokens[] = $this->factory->createEmpty($node->tagName, $attr);
$tokens[] = $this->factory->createEmpty($tag_name, $attr);
}
return false;
} else {
if ($collect) {
$tokens[] = $this->factory->createStart(
$tag_name = $node->tagName, // somehow, it get's dropped
$attr
);
$tokens[] = $this->factory->createStart($tag_name, $attr);
}
return true;
}
@ -197,10 +234,10 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
*/
protected function createEndNode($node, &$tokens)
{
$tokens[] = $this->factory->createEnd($node->tagName);
$tag_name = $this->getTagName($node); // Handle variable tagName property
$tokens[] = $this->factory->createEnd($tag_name);
}
/**
* Converts a DOMNamedNodeMap of DOMAttr objects into an assoc array.
*

View file

@ -1507,7 +1507,7 @@ class HTML5
$entity = $this->character($start, $this->char);
$cond = strlen($e_name) > 0;
// The rest of the parsing happens bellow.
// The rest of the parsing happens below.
break;
// Anything else
@ -1535,7 +1535,7 @@ class HTML5
}
$cond = isset($entity);
// The rest of the parsing happens bellow.
// The rest of the parsing happens below.
break;
}

View file

@ -1080,7 +1080,7 @@ class HTML5
$entity = $this->character($start, $this->char);
$cond = strlen($e_name) > 0;
// The rest of the parsing happens bellow.
// The rest of the parsing happens below.
break;
// Anything else
@ -1102,7 +1102,7 @@ class HTML5
}
$cond = isset($entity);
// The rest of the parsing happens bellow.
// The rest of the parsing happens below.
break;
}

View file

@ -0,0 +1,4 @@
.DS_Store
.idea
vendor
composer.lock

View file

@ -0,0 +1,26 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
matrix:
allow_failures:
- php: hhvm
before_install:
- composer self-update
install:
- travis_retry composer install --no-interaction --prefer-source
script:
- phpunit -c tests/build.xml
notifications:
on_success: never
on_failure: always

View file

@ -0,0 +1,21 @@
Moment.php is freely distributable under the terms of the MIT license.
Copyright (c) 2074 Tino Ehrich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,773 @@
<pre>
_ _
_ __ ___ ___ _ __ ___ ___ _ __ | |_ _ __ | |__ _ __
| '_ ` _ \ / _ \| '_ ` _ \ / _ \ '_ \| __| | '_ \| '_ \| '_ \
| | | | | | (_) | | | | | | __/ | | | |_ _| |_) | | | | |_) |
|_| |_| |_|\___/|_| |_| |_|\___|_| |_|\__(_) .__/|_| |_| .__/
|_| |_|
</pre>
[![Build Status](https://travis-ci.org/fightbulc/moment.php.svg?branch=master)](https://travis-ci.org/fightbulc/moment.php)
[![Total Downloads](https://img.shields.io/packagist/dt/fightbulc/moment.svg?style=flat-square)](https://packagist.org/packages/fightbulc/moment)
[Change log](#changelog)
# Intro
### What is moment.php?
Date library for parsing, manipulating and formatting dates w/ i18n.
### Any dependencies?
PHP 5.3 or later since moment.php is based on php's [DateTime Class](http://php.net/manual/en/class.datetime.php).
-------------------------------------------------
# Install
Easy install via composer. Still no idea what composer is? Inform yourself [here](http://getcomposer.org).
```json
{
"require": {
"fightbulc/moment": "*"
}
}
```
-------------------------------------------------
# Quick examples
### Get a moment
```php
$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
```
-------------------------------------------------
### Accepted date formats
Moment parses the following date formats as input:
```php
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';
```
-------------------------------------------------
### Switch locale
Have a look at the ```Locales``` folder to see all supported languages. Default locale is ```en_GB```.
```php
$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
```
__Supported languages so far:__
```ar_TN``` Arabic (Tunisia)
```ca_ES``` Catalan
```zh_CN``` Chinese
```zh_TW``` Chinese (traditional)
```cs_CZ``` Czech
```da_DK``` Danish
```nl_NL``` Dutch
```en_GB``` English (British)
```en_US``` English (American)
```fr_FR``` French (Europe)
```de_DE``` German (Germany)
```hu_HU``` Hungarian
```in_ID``` Indonesian
```it_IT``` Italian
```ja_JP``` Japanese
```oc_LNC``` Lengadocian
```pl_PL``` Polish
```pt_BR``` Portuguese (Brazil)
```pt_PT``` Portuguese (Portugal)
```ru_RU``` Russian (Basic version)
```es_ES``` Spanish (Europe)
```se_SV``` Swedish
```uk_UA``` Ukrainian
```th_TH``` Thai
```tr_TR``` Turkish
```vi_VN``` Vietnamese
-------------------------------------------------
### Switch timezones
```php
$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
echo $m->setTimezone('UTC')->format(); // 2012-04-25T01:00:00+0000
```
#### Change default timezone
```php
\Moment\Moment::setDefaultTimezone('CET');
$m = new \Moment\Moment('2016-09-13T14:32:06');
echo $m->format(); // 2016-09-13T14:32:06+0100
```
-------------------------------------------------
### Custom format
#### I. PHP only (Standard)
```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)
```
Formats are based on PHP's [Date function](http://php.net/manual/en/function.date.php) and [DateTime class](http://www.php.net/manual/en/datetime.formats.php).
#### II. Non-php formats
You can now inject different format handling by passing along a class which implements the ```FormatsInterface```. You can find an example within the test folder for implementing all formats from [moment.js](http://momentjs.com/docs/#/displaying/format/). Thanks to [Ashish](https://github.com/ashishtilara) for taking the time to match ```moment.js``` formats to those of PHP. Have a look at the [test script](https://github.com/fightbulc/moment.php/blob/master/test/test.php) to see the example in action.
Everybody can write format classes in the same manner. Its easy and scalable.
```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
```
`Custom formats` can also come as part of every `Locale`. If it does not exist for your locale yet go ahead and add it. See an example for the [French locale](https://github.com/fightbulc/moment.php/blob/master/src/Locales/fr_FR.php).
#### III. Easy text escaping
Just wrap all your text within ```[]``` and all characters will be automatically escaped for you.
```php
$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. Fixed ordinal representations
PHP's interal ordinal calculation seems to be buggy. I added a quick fix to handle this issue.
The following example prints the week of the year of the given date. It should print ```22nd```:
```php
// 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
```
-------------------------------------------------
### Create custom moments and manipulate it
#### I. Past/Future moments
```php
$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. Clone a given moment
Sometimes its useful to take a given moment and work with it without changing the origin. For that use ```cloning()```.
```php
$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
$c = $m->cloning()->addDays(1);
echo $m->getDay(); // 15
echo $c->getDay(); // 16
```
Alternately, you can enable immutable mode on the origin.
```php
$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
```
Immutable mode makes all modification methods call `cloning()` implicitly before applying their modifications.
#### III. Methods for manipulating the date/time
Add | Subtract
--- | ---
addSeconds($s) | subtractSeconds($s)
addMinutes($i) | subtractMinutes($i)
addHours($h) | subtractHours($h)
addDays($d) | subtractDays($d)
addWeeks($w) | subtractWeeks($w)
addMonths($m) | subtractMonths($m)
addYears($y) | subtractYears($y)
#### IV. Setter/Getter
Setter | Getter
--- | ---
setSecond($s) | getSecond()
setMinute($m) | getMinute()
setHour($h) | getHour()
setDay($d) | getDay()
setMonth($m) | getMonth()
setYear($y) | getYear()
-- | getQuarter()
-------------------------------------------------
### Difference between dates
```php
$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
```
-------------------------------------------------
### Get date periods (week, month, quarter)
Sometimes its helpful to get the period boundaries of a given date. For instance in case that today is Wednesday and I need the starting-/end dates from today's week. Allowed periods are ```week```, ```month``` and ```quarter```.
```php
$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
```
Same procedure for monthly and quarterly periods:
```php
$momentPeriodVo = $m->getPeriod('month');
$momentPeriodVo = $m->getPeriod('quarter');
```
-------------------------------------------------
### Calendar Times
Calendar time displays time relative to ```now```, but slightly differently than ```Moment::fromNow()```. ```Moment::calendar()``` will format a date with different strings depending on how close to today the date is.
```php
(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
```
Time | Display
--- | ---
Last week | Last Monday at 15:54
The day before | Yesterday at 15:54
The same day | Today at 15:54
The next day | Tomorrow at 15:54
The next week | Wednesday at 15:54
Everything else | 04/09/2014
__Note:__ Use ```$moment->calendar(false)``` to leave out the time ```at 00:00```.
-------------------------------------------------
### startOf / endOf
Same process as for moment.js: mutates the original moment by setting it to the start/end of a unit of time.
```php
$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
```
__Note:__ I ignored the period of ```second``` since we are not dealing with milliseconds.
-------------------------------------------------
### Get dates for given weekdays for upcoming weeks
For one of my customers I needed to get moments by selected weekdays. __The task was:__ give me the dates for
```Tuesdays``` and ```Thursdays``` for the next three weeks. So I added a small handler which does exactly this.
As result you will receive an array filled with ```Moment Objects```.
```php
// 1 - 7 = Mon - Sun
$weekdayNumbers = [
2, // tuesday
4, // thursday
];
$m = new \Moment\Moment();
$dates = $m->getMomentsByWeekdays($weekdayNumbers, 3);
// $dates = [Moment, Moment, Moment ...]
```
You can now run through the result and put it formatted into a drop-down field or for whatever you might need it.
-------------------------------------------------
# Roadmap
- Try to port useful methods from moment.js
- Add unit tests
-------------------------------------------------
# Changelog
### 1.26.10
- fixed:
- Occitan locale
### 1.26.9
- fixed:
- Russian locale [issue](https://github.com/fightbulc/moment.php/issues/68#issuecomment-264890181)
### 1.26.8
- added:
- Portuguese (pt_PT)
### 1.26.7
- fixed:
- Hungarian locale weekdays order
### 1.26.6
- added:
- allow initialising Moment with unix timestamp without leading @
### 1.26.5
- fixed:
- Fix format of 'LLL' in Custom Formats
### 1.26.4
- fixed:
- removed php5.4+ only syntax
### 1.26.3
- fixed:
- Danish day- and monthnames correct case
- French locale
- PHPDocs
- added:
- consts for `NO_TZ_MYSQL`, `NO_TZ_NO_SECS` and `NO_TIME` when parsing dates
### 1.26.2
- added:
- Dutch customFormat
### 1.26.1
- fixed:
- Russian locale
### 1.26.0
- added:
- Turkish locale
- fixed:
- Lengadocian locale
### 1.25.1
- fixed:
- PHP7.1 setTime requires `$microseconds`
### 1.25
- added:
- Ukrainian locale
### 1.24
- added:
- Hungarian locale
### 1.23.1
- fixed:
- Lengadocian locale
### 1.23.0
- added:
- Vietnamese locale
- Lengadocian locale
### 1.22.0
- added:
- Change default timezone
- fixed:
- FormatsInterface docs
### 1.21.0
- added:
- Arabic locale
- Custom format on locale level
### 1.20.9
- fixed:
- Russian locale
- added:
- Russian locale tests
### 1.20.8
- fixed:
- Polish locale
- Calculation of seconds
### 1.20.7
- fixed:
- Russian: more relative time fixes
### 1.20.6
- fixed:
- Russian locale relative time: day handling
### 1.20.5
- fixed:
- missing immutable handling
### 1.20.4
- fixed:
- Improved Polish locale (added Nominativ)
### 1.20.3
- fixed:
- Chinese locale
### 1.20.2
- added accepted formats to README
### 1.20.1
- fixed:
- Thai locale
### 1.20.0
- added:
- Catalan locale
- fixed:
- Polish locale test
### 1.19.0
- added:
- Russian locale
- fixed:
- Polish locale test
### 1.18.0
- added:
- Immutable mode
- fixed:
- Polish locale
### 1.17.0
- added:
- Polish locale
### 1.16.0
- added:
- Indonesian locale
### 1.15.0
- added:
- Japanese locale
### 1.14.1
- fixed:
- typo in Dutch locale
### 1.14.0
- added:
- Dutch locale
### 1.13.0
- added:
- Swedish locale
### 1.12.0
- added:
- Danish locale
### 1.11.4
- fixed:
- fixed starting/ending weekday for Romanian locale
### 1.11.3
- fixed:
- adding delimiter character to Italian locale
### 1.11.1
- fixed:
- passing back new instance for startOf/endOf for week, month, quarter
### 1.11.0
- added:
- locale Czech
### 1.10.4
- added:
- ```calendar``` locale receives as \Closure the following params ```function(Moment $m) {}```
- ```relativeTime``` locale receives as \Closure the following params ```function($count, $direction, Moment $m) {}```
### 1.10.3
- added:
- fixed passing closures to locale (calendar, relativeTime)
- set correct german locale information
### 1.10.2
- added:
- fixed Thai locale strings
### 1.10.1
- added:
- locale traditional Chinese
### 1.10.0
- added:
- locale Chinese
- ordinal formatter receives now the ```token``` e.g. the token within ```dS``` is ```d```
### 1.9.1
- fixed: english ordinal issue for numbers between 11 - 13
### 1.9.0
- added: locale Italian
### 1.8.1
- fixed: english ordinal issue
### 1.8.0
- added: locale Portuguese
### 1.7.2
- fixed:
- Locale displayed wrong month name (#34)
- Changed the order of weekdays within locale files
### 1.7.1
- added:
- getWeekdayNameLong()
- getWeekdayNameShort()
- getMonthNameLong()
- getMonthNameShort()
### 1.7.0
- added:
- Locale: Thai
### 1.6.0
- added:
- Locale
- MomentFromVo:
- getMonths()
- getYears()
- getRelative()
- fixed:
- MomentFromVo:
- getSeconds() shows now direction as well
### 1.5.3
- fixed:
- timezone issue which occured only for unixtime dates
- other:
- MomentFromVo:
- direction returns now: "future" (-) / "past" (+)
- time values are now type casted as floats
### 1.5.2
- fixed:
- unrecognised timezone when constructing a Moment
### 1.5.1
- added:
- getMomentsByWeekdays()
- getWeekday()
- getWeekOfYear()
- other:
- escaped text
### 1.5.0
- added:
- startOf and endOf as implemented by [moment.js](http://momentjs.com/docs/#/manipulating/start-of/)
- get the quarter period of a given date
- setDay()
- getDay()
- setMonth()
- getMonth()
- setYear()
- getYear()
- getQuarter()
- setSecond()
- getSecond()
- setMinute()
- getMinute()
- setHour()
- getHour()
- added cloning()
- create a new mutable moment based of the given instance
- added ```getInterval()``` to ```MomentPeriodVo``` to indicate the interval of the given period
- ```week``` = week of the year
- ```month``` = month of the year
- ```quarter``` = quarter of the year
- added a static class ```MomentHelper```
- get the period for a given quarter in a given year
- fixed PHP's internal ordinal calculation (also in combination with moment.js formatting)
- e.g. ```WS``` for 21th week of the year shows now correct ```21th``` etc.
- you can now escape text by wrapping it in ```[]```
- e.g. ```[Hello World]``` will be automatically transformed into ```\H\e\l\l\o \W\o\r\l\d```
- removed:
- add()
- subtract()
### 1.4.0
- added:
- calendar format as implemented by [moment.js](http://momentjs.com/docs/#/displaying/calendar-time/)
### 1.3.0
- fixed:
- incompatibility w/ PHP 5.3
- added:
- Exception throw as ```MomentException```
- Date validation on instantiation:
- test for dates w/ format ```YYYY-mm-dd``` and ```YYYY-mm-ddTHH:ii:ss```
- throws MomentException on invalid dates
- addSeconds()
- addMinutes()
- addHours()
- addDays()
- addWeeks()
- addMonths()
- addYears()
- subtractSeconds()
- subtractMinutes()
- subtractHours()
- subtractDays()
- subtractWeeks()
- subtractMonths()
- subtractYears()
- deprecated:
- add()
- subtract()
-------------------------------------------------
# License
Moment.php is freely distributable under the terms of the MIT license.
Copyright (c) 2017 Tino Ehrich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,47 @@
{
"name": "fightbulc/moment",
"description": "Parse, validate, manipulate, and display dates in PHP w/ i18n support. Inspired by moment.js",
"type": "library",
"keywords": [
"date",
"time",
"parse",
"validate",
"manipulate",
"display",
"format",
"i18n",
"translation",
"locale",
"moment"
],
"license": "MIT",
"authors": [
{
"name": "Tino Ehrich",
"email": "tino@bigpun.me",
"role": "developer"
},
{
"name": "Ashish Tilara",
"email": "ashish@itcutives.com",
"role": "developer"
},
{
"name": "Jaroslaw Kozak",
"email": "jaroslaw.kozak68@gmail.com",
"role": "developer"
}
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.2.*"
},
"autoload": {
"psr-4": {
"Moment\\": "src/"
}
}
}

View file

@ -0,0 +1,151 @@
<?php
namespace Moment\CustomFormats;
use Moment\FormatsInterface;
/**
* Class MomentJs
* @package Moment\CustomFormats
*/
class MomentJs implements FormatsInterface
{
/**
* @var array
*/
protected $tokens = array(
"M" => "n", // 1 2 ... 11 12
"Mo" => "nS", // month: 1st 2nd ... 11th 12th
"MM" => "m", // 01 02 ... 11 12
"MMM" => "M", // Jan Feb ... Nov Dec
"MMMM" => "F", // January February ... November December
"D" => "j", // 1 2 ... 30 30
"Do" => "jS", // day: 1st 2nd ... 30th 31st
"DD" => "d", // 01 02 ... 30 31
"DDD" => "z", // 1 2 ... 364 365
"DDDo" => "zS", // day of year: 1st 2nd ... 364th 365th
"DDDD" => "zS", // day of year: 1st 2nd ... 364th 365th
"d" => "w", // 0 1 ... 5 6
"do" => "wS", // day of week: 0th 1st ... 5th 6th
"dd" => "D", // ***Su Mo ... Fr Sa
"ddd" => "D", // Sun Mon ... Fri Sat
"dddd" => "l", // Sunday Monday ... Friday Saturday
"e" => "w", // 0 1 ... 5 6
"E" => "N", // 1 2 ... 6 7
"w" => "W", // 1 2 ... 52 53
"wo" => "WS", // week of year: 1st 2nd ... 52nd 53rd
"ww" => "W", // ***01 02 ... 52 53
"W" => "W", // 1 2 ... 52 53
"Wo" => "WS", // week of year: 1st 2nd ... 52nd 53rd
"WW" => "W", // ***01 02 ... 52 53
"YY" => "y", // 70 71 ... 29 30
"YYYY" => "Y", // 1970 1971 ... 2029 2030
"gg" => "o", // 70 71 ... 29 30
"gggg" => "o", // ***1970 1971 ... 2029 2030
"GG" => "o", // 70 71 ... 29 30
"GGGG" => "o", // ***1970 1971 ... 2029 2030
"A" => "A", // AM PM
"a" => "a", // am pm
"H" => "G", // 0 1 ... 22 23
"HH" => "H", // 00 01 ... 22 23
"h" => "g", // 1 2 ... 11 12
"hh" => "h", // 01 02 ... 11 12
"m" => "i", // 0 1 ... 58 59
"mm" => "i", // ***00 01 ... 58 59
"s" => "s", // 0 1 ... 58 59
"ss" => "s", // ***00 01 ... 58 59
"S" => "", // 0 1 ... 8 9
"SS" => "", // 0 1 ... 98 99
"SSS" => "", // 0 1 ... 998 999
"z or zz" => "T", // EST CST ... MST PST 
"Z" => "P", // -07:00 -06:00 ... +06:00 +07:00
"ZZ" => "O", // -0700 -0600 ... +0600 +0700
"X" => "U", // 1360013296
"LT" => "g:i A", // 8:30 PM
"L" => "m/d/Y", // 09/04/1986
"l" => "n/j/Y", // 9/4/1986
"LL" => "F jS Y", // September 4th 1986
"ll" => "M j Y", // Sep 4 1986
"LLL" => "F jS Y g:i A", // September 4th 1986 8:30 PM
"lll" => "M j Y g:i A", // Sep 4 1986 8:30 PM
"LLLL" => "l, F jS Y g:i A", // Thursday, September 4th 1986 8:30 PM
"llll" => "D, M j Y g:i A", // Thu, Sep 4 1986 8:30 PM
);
/**
* @param $format
*
* @return string
*/
public function format($format)
{
return $this->momentJsToPhp($format);
}
/**
* @return array
*/
public function getTokens()
{
return (array)$this->tokens;
}
/**
* @param array $options
*
* @return MomentJs
*/
public function setTokens(array $options)
{
$this->tokens = array_merge($this->tokens, $options);
return $this;
}
/**
* @param String $format
*
* @return string
*/
protected function momentJsToPhp($format)
{
$tokens = $this->getTokens();
// find all tokens from string, using regular expression
$regExp = "/(\[[^\[]*\])|(\\\\)?(LT|LL?L?L?|l{1,4}|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/";
$matches = array();
preg_match_all($regExp, $format, $matches);
// if there is no match found then return the string as it is
// TODO: might return escaped string
if (empty($matches) || is_array($matches) === false)
{
return $format;
}
// to match with extracted tokens
$momentTokens = array_keys($tokens);
$phpMatches = array();
// ----------------------------------
foreach ($matches[0] as $id => $match)
{
// if there is a matching php token in token list
if (in_array($match, $momentTokens))
{
// use the php token instead
$string = $tokens[$match];
}
else
{
$string = $match;
}
$phpMatches[$id] = $string;
}
// join and return php specific tokens
return implode("", $phpMatches);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Moment;
/**
* Interface FormatsInterface
* @package Moment
*/
interface FormatsInterface
{
/**
* @param string $format
*
* @return FormatsInterface
*/
public function format($format);
/**
* @param array $customFormats
*
* @return FormatsInterface
*/
public function setTokens(array $customFormats);
}

View file

@ -0,0 +1,43 @@
<?php
// locale: arabic (tn)
// author: Tarek Morgéne https://www.satoripop.com/
return array(
"months" => explode('_', انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'),
"monthsShort" => explode('_', انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'),
"weekdays" => explode('_', 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'),
"weekdaysShort" => explode('_', 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'),
"calendar" => array(
"sameDay" => '[اليوم]',
"nextDay" => '[غدا ]',
"lastDay" => '[أمس ]',
"lastWeek" => 'l [الماضي]',
"sameElse" => 'l',
"withTime" => '[على الساعة] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'في %s',
"past" => 'منذ %s',
"s" => 'ثوان',
"m" => 'دقيقة',
"mm" => '%d دقائق',
"h" => 'ساعة',
"hh" => '%d ساعات',
"d" => 'يوم',
"dd" => '%d أيام',
"M" => 'شهر',
"MM" => '%d أشهر',
"y" => 'سنة',
"yy" => '%d سنوات',
),
"ordinal" => function ($number)
{
return $number . ($number === 1 ? '[er]' : '');
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,62 @@
<?php
// locale: Catalan (ca_ES)
// author: CROWD Studio https://github.com/crowd-studio
return array(
"months" => explode('_', 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'),
"monthsShort" => explode('_', 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'),
"weekdays" => explode('_', 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'),
"weekdaysShort" => explode('_', 'dg._dl._dt._dc._dj._dv._ds.'),
"calendar" => array(
"sameDay" => '[avui]',
"nextDay" => '[demà]',
"lastDay" => '[ahir]',
"lastWeek" => '[el] l',
"sameElse" => 'l',
"withTime" => function (Moment $moment) { return '[a' . ($moment->getHour() !== 1 ? ' les' : null) . '] H:i'; },
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'en %s',
"past" => 'fa %s',
"s" => 'uns segons',
"m" => 'un minut',
"mm" => '%d minuts',
"h" => 'una hora',
"hh" => '%d hores',
"d" => 'un dia',
"dd" => '%d dies',
"M" => 'un mes',
"MM" => '%d mesos',
"y" => 'un any',
"yy" => '%d anys',
),
"ordinal" => function ($number)
{
switch ($number) {
case 1:
$ouput = 'r';
break;
case 2:
$ouput = 'n';
break;
case 3:
$ouput = 'r';
break;
case 4:
$ouput = 't';
break;
default:
$ouput = 'è';
break;
}
return $number . '[' . $output . ']';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,92 @@
<?php
// locale: Czech (Czech Republic) (cs_CZ)
// author: Jan Ptacek https://github.com/ptica
use Moment\Moment;
/**
* @param string $direction
* @param string $trueString
* @param string $falseString
*
* @return string
*/
$ifPast = function ($direction, $trueString, $falseString)
{
return $direction === 'past' ? $trueString : $falseString;
};
/**
* @param int $count
* @param int $countSmallerThan
* @param string $trueString
* @param string $falseString
*
* @return string
*/
$ifCountSmaller = function ($count, $countSmallerThan, $trueString, $falseString)
{
return $count < $countSmallerThan ? $trueString : $falseString;
};
return array(
"months" => explode('_', 'ledna_února_března_dubna_května_června_července_srpna_září_října_listopadu_prosince'),
"monthsShort" => explode('_', 'Led_Úno_Bře_Dub_Kvě_Čer_Čvc_Srp_Zář_Říj_Lis_Pro'),
"weekdays" => explode('_', 'pondělí_úterý_středa_čtvrtek_pátek_sobota_neděle'),
"weekdaysShort" => explode('_', 'po_út_st_čt_pá_so_ne'),
"calendar" => array(
"sameDay" => '[dnes]',
"nextDay" => '[zítra]',
"lastDay" => '[včera]',
"lastWeek" => '[minulý] l',
"sameElse" => 'l',
"withTime" => '[v] H:i',
"default" => 'd.m.Y',
),
"relativeTime" => array(
"future" => 'za %s',
"past" => 'před %s',
"s" => function ($count, $direction, Moment $m) use ($ifPast) {
return $ifPast($direction, 'okamžikem', 'okamžik');
},
"m" => function ($count, $direction, Moment $m) use ($ifPast) {
return $ifPast($direction, 'minutou', 'minutu');
},
"mm" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
return $ifPast($direction, '%d minutami', $ifCountSmaller($count, 5, '%d minuty', '%d minut'));
},
"h" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
return $ifPast($direction, 'hodinou', 'hodinu');
},
"hh" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
$ifPast($direction, '%d hodinami', $ifCountSmaller($count, 5, '%d hodiny', '%d hodin'));
},
"d" => function ($count, $direction, Moment $m) use ($ifPast) {
return $ifPast($direction, 'dnem', 'den');
},
"dd" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
return $ifPast($direction, '%d dny', $ifCountSmaller($count, 5, '%d dny', '%d dnů'));
},
"M" => function ($count, $direction, Moment $m) use ($ifPast) {
return $ifPast($direction, 'měsícem', 'měsíc');
},
"MM" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
return $ifPast($direction, '%d měsíci', $ifCountSmaller($count, 5, '%d měsíce', '%d měsíců'));
},
"y" => function ($count, $direction, Moment $m) use ($ifPast) {
return $ifPast($direction, 'rokem', 'rok');
},
"yy" => function ($count, $direction, Moment $m) use ($ifPast, $ifCountSmaller) {
return $ifPast($direction, $ifCountSmaller($count, 5, '%d roky', '%d lety'), $ifCountSmaller($count, 5, '%d roky', '%d let'));
},
),
"ordinal" => function ($number)
{
return $number . '.';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,43 @@
<?php
// locale: danish (da-dk)
// author: Morten Wulff https://github.com/wulff
return array(
"months" => explode('_', 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'),
"monthsShort" => explode('_', 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'),
"weekdays" => explode('_', 'mandag_tirsdag_onsdag_torsdag_fredag_lørdag_søndag'),
"weekdaysShort" => explode('_', 'man_tir_ons_tor_fre_lør_søn'),
"calendar" => array(
"sameDay" => '[I dag]',
"nextDay" => '[I morgen]',
"lastDay" => '[I går]',
"lastWeek" => '[Sidste] l',
"sameElse" => 'l',
"withTime" => '[kl] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'om %s',
"past" => '%s siden',
"s" => 'få sekunder',
"m" => 'et minut',
"mm" => '%d minutter',
"h" => 'en time',
"hh" => '%d timer',
"d" => 'en dag',
"dd" => '%d dage',
"M" => 'en måned',
"MM" => '%d måneder',
"y" => 'et år',
"yy" => '%d år',
),
"ordinal" => function ($number)
{
return $number . '.';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,43 @@
<?php
// locale: German (Germany) (de_DE)
// author: Tino Ehrich (tino@bigpun.me)
return array(
"months" => explode('_', 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'),
"monthsShort" => explode('_', 'Jan_Feb_Mär_Apr_Mai_Jun_Jul_Aug_Sep_Okt_Nov_Dez'),
"weekdays" => explode('_', 'Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag_Sonntag'),
"weekdaysShort" => explode('_', 'Mo_Di_Mi_Do_Fr_Sa_So'),
"calendar" => array(
"sameDay" => '[Heute]',
"nextDay" => '[Morgen]',
"lastDay" => '[Gestern]',
"lastWeek" => '[Letzten] l',
"sameElse" => 'l',
"withTime" => '[um] H:i',
"default" => 'd.m.Y',
),
"relativeTime" => array(
"future" => 'in %s',
"past" => 'vor %s',
"s" => 'ein paar Sekunden',
"m" => 'einer Minute',
"mm" => '%d Minuten',
"h" => 'einer Stunde',
"hh" => '%d Stunden',
"d" => 'einem Tag',
"dd" => '%d Tagen',
"M" => 'einem Monat',
"MM" => '%d Monaten',
"y" => 'einem Jahr',
"yy" => '%d Jahren',
),
"ordinal" => function ($number)
{
return $number . '.';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,52 @@
<?php
// locale: great britain english (en-gb)
// author: Chris Gedrim https://github.com/chrisgedrim
return array(
"months" => explode('_', 'January_February_March_April_May_June_July_August_September_October_November_December'),
"monthsNominative" => explode('_', 'January_February_March_April_May_June_July_August_September_October_November_December'),
"monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'),
"weekdays" => explode('_', 'Monday_Tuesday_Wednesday_Thursday_Friday_Saturday_Sunday'),
"weekdaysShort" => explode('_', 'Mon_Tue_Wed_Thu_Fri_Sat_Sun'),
"calendar" => array(
"sameDay" => '[Today]',
"nextDay" => '[Tomorrow]',
"lastDay" => '[Yesterday]',
"lastWeek" => '[Last] l',
"sameElse" => 'l',
"withTime" => '[at] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'in %s',
"past" => '%s ago',
"s" => 'a few seconds',
"m" => 'a minute',
"mm" => '%d minutes',
"h" => 'an hour',
"hh" => '%d hours',
"d" => 'a day',
"dd" => '%d days',
"M" => 'a month',
"MM" => '%d months',
"y" => 'a year',
"yy" => '%d years',
),
"ordinal" => function ($number)
{
$n = $number % 100;
$ends = array('th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th');
if ($n >= 11 && $n <= 13)
{
return $number . '[th]';
}
return $number . '[' . $ends[$number % 10] . ']';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,10 @@
<?php
// locale: american english (en_US)
$locale = require __DIR__ . '/en_GB.php';
$locale['calendar']['withTime'] = '[at] h:i A';
$locale['calendar']['default'] = 'm/d/Y';
$locale['week']['dow'] = 7;
return $locale;

View file

@ -0,0 +1,45 @@
<?php
// locale: spanish (es)
// author: Julio Napurí https://github.com/julionc
use Moment\Moment;
return array(
"months" => explode('_', 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'),
"monthsShort" => explode('_', 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'),
"weekdays" => explode('_', 'lunes_martes_miércoles_jueves_viernes_sábado_domingo'),
"weekdaysShort" => explode('_', 'lun._mar._mié._jue._vie._sáb._dom.'),
"calendar" => array(
"sameDay" => '[hoy]',
"nextDay" => '[mañana]',
"lastDay" => '[ayer]',
"lastWeek" => '[el] l',
"sameElse" => 'l',
"withTime" => function (Moment $moment) { return '[a la' . ($moment->getHour() !== 1 ? 's' : null) . '] H:i'; },
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'en %s',
"past" => 'hace %s',
"s" => 'unos segundos',
"m" => 'un minuto',
"mm" => '%d minutos',
"h" => 'una hora',
"hh" => '%d horas',
"d" => 'un día',
"dd" => '%d días',
"M" => 'un mes',
"MM" => '%d meses',
"y" => 'un año',
"yy" => '%d años',
),
"ordinal" => function ($number)
{
return $number . 'º';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,54 @@
<?php
// locale: french (fr)
// author: John Fischer https://github.com/jfroffice
return array(
"months" => explode('_', 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'),
"monthsShort" => explode('_', 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'),
"weekdays" => explode('_', 'lundi_mardi_mercredi_jeudi_vendredi_samedi_dimanche'),
"weekdaysShort" => explode('_', 'lun._mar._mer._jeu._ven._sam._dim.'),
"calendar" => array(
"sameDay" => '[Aujourd\'hui]',
"nextDay" => '[Demain]',
"lastDay" => '[Hier]',
"lastWeek" => 'l [dernier]',
"sameElse" => 'l',
"withTime" => '[à] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'dans %s',
"past" => 'il y a %s',
"s" => 'quelques secondes',
"m" => 'une minute',
"mm" => '%d minutes',
"h" => 'une heure',
"hh" => '%d heures',
"d" => 'un jour',
"dd" => '%d jours',
"M" => 'un mois',
"MM" => '%d mois',
"y" => 'un an',
"yy" => '%d ans',
),
"ordinal" => function ($number)
{
return $number . ($number === 1 ? '[er]' : '');
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
"customFormats" => array(
"LT" => "G:i", // 20:30
"L" => "d/m/Y", // 04/09/1986
"l" => "j/n/Y", // 4/9/1986
"LL" => "jS F Y", // 4 Septembre 1986
"ll" => "j M Y", // 4 Sep 1986
"LLL" => "jS F Y G:i", // 4 Septembre 1986 20:30
"lll" => "j M Y G:i", // 4 Sep 1986 20:30
"LLLL" => "l, jS F Y G:i", // Jeudi, 4 Septembre 1986 20:30
"llll" => "D, j M Y G:i", // Jeu, 4 Sep 1986 20:30
),
);

View file

@ -0,0 +1,69 @@
<?php
// locale: hungarian (hu)
// author: David Joseph Guzsik https://github.com/seinopsys
return array(
"months" => explode('_', 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'),
"monthsShort" => explode('_', 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'),
"weekdays" => explode('_', 'hétfő_kedd_szerda_csütörtök_péntek_szombat_vasárnap'),
"weekdaysShort" => explode('_', 'hét_kedd_sze_csüt_pén_szo_vas'),
"calendar" => array(
"sameDay" => '[ma] l[-kor]',
"nextDay" => '[holnap] l[-kor]',
"lastDay" => '[tegnap] l[-kor]',
"lastWeek" => function($n, $dir, \Moment\Moment $Moment){
$weekEndings = explode('_','vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton');
return '[múlt] [' . weekEndings[$Moment->getDay()] . '] l[-kor]';
},
"sameElse" => 'l',
"withTime" => 'H:i[-kor]',
"default" => 'Y.m.d.',
),
"relativeTime" => array(
"future" => '%s múlva',
"past" => '%s',
"s" => function($n, $dir){
return ($dir === 'future') ? 'néhány másodperc' : 'néhány másodperce';
},
"m" => function($n, $dir){
return 'egy ' . ($dir === 'future' ? 'perc' : 'perce');
},
"mm" => function($n, $dir){
return "$n " . ($dir === 'future' ? 'perc' : 'perce');
},
"h" => function($n, $dir){
return 'egy ' . ($dir === 'future' ? 'óra' : 'órája');
},
"hh" => function($n, $dir){
return "$n " . ($dir === 'future' ? 'óra' : 'órája');
},
"d" => function($n, $dir){
return 'egy ' . ($dir === 'future' ? 'nap' : 'napja');
},
"dd" => function($n, $dir){
return "$n " . ($dir === 'future' ? 'nap' : 'napja');
},
"M" => function($n, $dir){
return 'egy' . ($dir === 'future' ? 'hónap' : 'hónapja');
},
"MM" => function($n, $dir){
return "$n " . ($dir === 'future' ? 'hónap' : 'hónapja');
},
"y" => function($n, $dir){
return 'egy' . ($dir === 'future' ? 'év' : 'éve');
},
"yy" => function($n, $dir){
return "$n " . ($dir === 'future' ? 'év' : 'éve');
},
),
"ordinal" => function ($number)
{
return "$number.";
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 7 // The week that contains Jan 1st is the first week of the year.
),
);

View file

@ -0,0 +1,44 @@
<?php
// locale: Indonesian (Indonesia) (id-id)
// author: Yuda Sukmana https://github.com/ydatech
return array(
"months" => explode('_', 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'),
"monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agu_Sep_Okt_Nov_Des'),
"weekdays" => explode('_', 'Senin_Selasa_Rabu_Kamis_Jum\'at_Sabtu_Minggu'),
"weekdaysShort" => explode('_', 'Sen_Sel_Rab_Kam_Jum_Sab_Ming'),
"calendar" => array(
"sameDay" => '[Hari ini]',
"nextDay" => '[Besok]',
"lastDay" => '[Kemarin]',
"lastWeek" => 'l [Kemarin]',
"sameElse" => 'l',
"withTime" => '[pukul] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => '%s',
"past" => '%s',
"s" => 'beberapa detik yang lalu',
"m" => 'satu menit yang lalu',
"mm" => '%d menit yang lalu',
"h" => 'satu jam',
"hh" => '%d jam',
"d" => 'satu hari',
"dd" => '%d hari',
"M" => 'satu bulan',
"MM" => '%d bulan',
"y" => 'satu tahun',
"yy" => '%d tahun',
),
"ordinal" => function ($number)
{
return $number;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,43 @@
<?php
// locale: italia italiano (it_IT)
// author: Marco Micheli https://github.com/macfighterpilot
return array(
"months" => explode('_', 'Gennaio_Febbraio_Marzo_Aprile_Maggio_Giugno_Luglio_Agosto_Settembre_Ottobre_Novembre_Dicembre'),
"monthsShort" => explode('_', 'Gen_Feb_Mar_Apr_Mag_Giu_Lug_Ago_Set_Ott_Nov_Dic'),
"weekdays" => explode('_', 'Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato_Domenica'),
"weekdaysShort" => explode('_', 'Lun_Mar_Mer_Gio_Ven_Sab_Dom'),
"calendar" => array(
"sameDay" => '[Oggi]',
"nextDay" => '[Domani]',
"lastDay" => '[Ieri]',
"lastWeek" => '[Scorsa] l',
"sameElse" => 'l',
"withTime" => '[alle] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'tra %s',
"past" => '%s fa',
"s" => 'pochi secondi',
"m" => 'un minuto',
"mm" => '%d minuti',
"h" => 'una ora',
"hh" => '%d ore',
"d" => 'un giorno',
"dd" => '%d giorni',
"M" => 'un mese',
"MM" => '%d mesi',
"y" => 'un anno',
"yy" => '%d anni',
),
"ordinal" => function ($number)
{
return $number . '';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,42 @@
<?php
// locale: Japanese ( ja-jp )
// author: Takumi https://github.com/takumi-dev
return array(
"months" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
"monthsShort" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
"weekdays" => explode('_', '月曜日_火曜日_水曜日_木曜日_金曜日_土曜日_日曜日'),
"weekdaysShort" => explode('_', '月_火_水_木_金_土_日'),
"calendar" => array(
"sameDay" => '[今日]',
"nextDay" => '[明日]',
"lastDay" => '[昨日]',
"lastWeek" => '[先週]l',
"sameElse" => 'l',
"withTime" => 'H時i分',
"default" => 'Y年m月d日',
),
"relativeTime" => array(
"future" => '%s後',
"past" => '%s前',
"s" => '数秒',
"m" => '1分',
"mm" => '%d分',
"h" => '1時間',
"hh" => '%d時間',
"d" => '1日',
"dd" => '%d日',
"M" => '1ヶ月',
"MM" => '%dヶ月',
"y" => '1年',
"yy" => '%d年',
),
"ordinal" => function ($number)
{
$prefix = '第';
return $prefix.$number;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,55 @@
<?php
// locale: Dutch (Netherlands, The) (nl_NL)
// author: Peter Notenboom https://github.com/peternotenboom
return array(
"months" => explode('_', 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'),
"monthsShort" => explode('_', 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'),
"weekdays" => explode('_', 'maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag_zondag'),
"weekdaysShort" => explode('_', 'ma_di_wo_do_vr_za_zo'),
"calendar" => array(
"sameDay" => '[Vandaag]',
"nextDay" => '[Morgen]',
"lastDay" => '[Gisteren]',
"lastWeek" => '[Vorige] l',
"sameElse" => 'l',
"withTime" => '[om] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'in %s',
"past" => '%s geleden',
"s" => 'een paar seconden',
"m" => 'een minuut',
"mm" => '%d minuten',
"h" => 'een uur',
"hh" => '%d uren',
"d" => 'een dag',
"dd" => '%d dagen',
"M" => 'een maand',
"MM" => '%d maanden',
"y" => 'een jaar',
"yy" => '%d jaren',
),
"ordinal" => function ($number)
{
return $number; //Possible to add 'e': $m->format('WS'); // 11e. But that also breaks "11e Januari 2015"
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
"customFormats" => array(
"LT" => "G:i", // 20:30
"L" => "d/m/Y", // 04/09/1986
"l" => "j/n/Y", // 4/9/1986
"LL" => "jS F Y", // 4 September 1986
"ll" => "j M Y", // 4 Sep 1986
"LLL" => "jS F Y G:i", // 4 September 1986 20:30
"lll" => "j M Y G:i", // 4 Sep 1986 20:30
"LLLL" => "l jS F Y G:i", // Donderdag 4 September 1986 20:30
"llll" => "D j M Y G:i", // Do 4 Sep 1986 20:30
),
);

View file

@ -0,0 +1,62 @@
<?php
// locale: Occitan languedocian dialect (oc_lnc)
// author: CROWD Studio https://github.com/crowd-studio
return array(
"months" => explode('_', 'genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octobre_novembre_decembre'),
"monthsShort" => explode('_', 'gen._feb._mar._abr._mai._jun._jul._ag._set._oct._nov._dec.'),
"weekdays" => explode('_', 'dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte'),
"weekdaysShort" => explode('_', 'dg._dl._dm._dc._dj._dv._ds.'),
"calendar" => array(
"sameDay" => '[uèi]',
"nextDay" => '[deman]',
"lastDay" => '[ièr]',
"lastWeek" => 'l [passat]',
"sameElse" => 'l',
"withTime" => '[a] H[o]i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'dins %s',
"past" => 'fa %s',
"s" => 'unas segondas',
"m" => 'una minuta',
"mm" => '%d minutas',
"h" => 'una ora',
"hh" => '%d oras',
"d" => 'un jorn',
"dd" => '%d jorns',
"M" => 'un mes',
"MM" => '%d meses',
"y" => 'un an',
"yy" => '%d ans',
),
"ordinal" => function ($number)
{
switch ($number)
{
case 1:
$output = 'r';
break;
case 2:
$output = 'n';
break;
case 3:
$output = 'r';
break;
case 4:
$output = 't';
break;
default:
$output = 'è';
break;
}
return $number . '[' . $output . ']';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,80 @@
<?php
// locale: Polski (Poland) (pl_PL)
// author: Mateusz Błaszczyk https://github.com/Zaszczyk
use Moment\Moment;
$ifLastDigitIsSpecial = function ($count, $trueString, $falseString)
{
$specialDigits = array('2', '3', '4');
return
(in_array(mb_substr((string)$count, -1), $specialDigits) && $count > 20)
|| in_array((string)$count, $specialDigits)
? $trueString : $falseString;
};
$femaleWeekdays = array('3', '6', '7');
return array(
"months" => explode('_', 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'),
"monthsNominative" => explode('_', 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'),
"monthsShort" => explode('_', 'sty._lut._mar._kwi._maj_cze._lip._sie._wrz._paź._lis._gru.'),
"weekdays" => explode('_', 'poniedziałek_wtorek_środa_czwartek_piątek_sobota_niedziela'),
"weekdaysShort" => explode('_', 'pon._wt._śr._czw._pt._sob._niedz.'),
"calendar" => array(
"sameDay" => '[dzisiaj]',
"nextDay" => '[jutro]',
"lastDay" => '[wczoraj]',
"lastWeek" => function (Moment $moment) use ($femaleWeekdays)
{
$pre = 'ostatni';
if (in_array($moment->getWeekday(), $femaleWeekdays))
{
$pre = 'ostatnia';
}
return '[' . $pre . '] l';
},
"sameElse" => 'l',
"withTime" => '[o] H:i',
"default" => 'd.m.Y',
),
"relativeTime" => array(
"future" => 'za %s',
"past" => '%s temu',
"s" => 'kilka sekund',
"m" => '1 minutę',
"mm" => function ($count) use ($ifLastDigitIsSpecial)
{
return $ifLastDigitIsSpecial($count, '%d minuty', '%d minut');
},
"h" => '1 godzinę',
"hh" => function ($count) use ($ifLastDigitIsSpecial)
{
return $ifLastDigitIsSpecial($count, '%d godziny', '%d godzin');
},
"d" => '1 dzień',
"dd" => '%d dni',
"M" => '1 miesiąc',
"MM" => function ($count) use ($ifLastDigitIsSpecial)
{
return $ifLastDigitIsSpecial($count, '%d miesiące', '%d miesięcy');
},
"y" => '1 rok',
"yy" => function ($count) use ($ifLastDigitIsSpecial)
{
return $ifLastDigitIsSpecial($count, '%d lata', '%d lat');
},
),
"ordinal" => function ($number)
{
return $number . '.';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,45 @@
<?php
// locale: portuguese (pt-br)
// author: Jefferson Santos https://github.com/jefflssantos
use Moment\Moment;
return array(
"months" => explode('_', 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'),
"monthsShort" => explode('_', 'jan._fev._mar._abr._mai._jun._jul._ago._set._out._nov._dez.'),
"weekdays" => explode('_', 'segunda_terça_quarta_quinta_sexta_sábado_domingo'),
"weekdaysShort" => explode('_', 'seg._ter._qua._qui._sex._sáb._dom.'),
"calendar" => array(
"sameDay" => '[hoje]',
"nextDay" => '[amanhã]',
"lastDay" => '[ontem]',
"lastWeek" => '[útimo] l',
"sameElse" => 'eu',
"withTime" => function (Moment $moment) { return '[à' . ($moment->getHour() !== 1 ? 's' : null) . '] H:i'; },
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'em %s',
"past" => 'há %s',
"s" => 'alguns segundos',
"m" => 'um minuto',
"mm" => '%d minutos',
"h" => 'uma hora',
"hh" => '%d horas',
"d" => 'um dia',
"dd" => '%d dias',
"M" => 'um mês',
"MM" => '%d meses',
"y" => 'um ano',
"yy" => '%d anos',
),
"ordinal" => function ($number)
{
return $number . 'º';
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,4 @@
<?php
// locale: native portuguese (pt_PT)
return require __DIR__ . '/pt_BR.php';

View file

@ -0,0 +1,80 @@
<?php
// locale: romanian (ro-ro)
// author: Calin Rada https://github.com/calinrada
use Moment\Moment;
$rtwp = function ($count, $direction, Moment $m, $key)
{
$format = array(
'mm' => 'minute',
'hh' => 'ore',
'dd' => 'zile',
'MM' => 'luni',
'yy' => 'ani'
);
$separator = ' ';
if ($count % 100 >= 20 || ($count >= 100 && $count % 100 === 0))
{
$separator = ' de ';
}
return $count . $separator . $format[$key];
};
return array(
"months" => explode('_', 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'),
"monthsShort" => explode('_', 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'),
"weekdays" => explode('_', 'luni_marți_miercuri_joi_vineri_sâmbătă_duminică'),
"weekdaysShort" => explode('_', 'Lun_Mar_Mie_Joi_Vin_Sâm_Dum'),
"calendar" => array(
"sameDay" => '[azi]',
"nextDay" => '[mâine la]',
"lastDay" => '[ieri la]',
"lastWeek" => '[fosta] dddd [la]',
"sameElse" => 'l',
"withTime" => '[at] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'peste %s',
"past" => 'În urmă cu %s',
"s" => 'câteva secunde',
"m" => 'un minut',
"mm" => function ($count, $direction, Moment $m) use ($rtwp)
{
return $rtwp($count, $direction, $m, 'mm');
},
"h" => 'o oră',
"hh" => function ($count, $direction, Moment $m) use ($rtwp)
{
return $rtwp($count, $direction, $m, 'hh');
},
"d" => 'o zi',
"dd" => function ($count, $direction, Moment $m) use ($rtwp)
{
return $rtwp($count, $direction, $m, 'dd');
},
"M" => 'o lună',
"MM" => function ($count, $direction, Moment $m) use ($rtwp)
{
return $rtwp($count, $direction, $m, 'MM');
},
"y" => 'un an',
"yy" => function ($count, $direction, Moment $m) use ($rtwp)
{
return $rtwp($count, $direction, $m, 'yy');
},
),
"ordinal" => function ($number)
{
return $number;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 7 // The week that contains Jan 7th is the first week of the year.
),
);

View file

@ -0,0 +1,98 @@
<?php
// locale: Русский (Russia) (ru_RU)
// author: Oleg Bogdanov https://github.com/wormen
/**
* returns ending for plural form of word by number and array of variants (1, 4, 5)
* example variants for apples ['яблоко', 'яблока', 'яблок']
*/
/**
* @param int $number
* @param array $endingArray
*
* @return string
*/
$getNumEnding = function ($number, array $endingArray)
{
$number = $number % 100;
if ($number >= 11 && $number <= 19)
{
return $endingArray[2];
}
$i = $number % 10;
switch ($i)
{
case (1):
$ending = $endingArray[0];
break;
case (2):
case (3):
case (4):
$ending = $endingArray[1];
break;
default:
$ending = $endingArray[2];
}
return $ending;
};
return array(
'months' => explode('_', 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'),
'monthsNominative' => explode('_', 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'),
'monthsShort' => explode('_', 'янв_фев_мрт_апрай_июн_июл_авг_сен_окт_нбрек'),
'weekdays' => explode('_', 'понедельник_вторник_средаетверг_пятница_субботаоскресенье'),
'weekdaysShort' => explode('_', 'пн_вт_ср_чт_пт_сбс'),
'calendar' => array(
'sameDay' => '[сегодня]',
'nextDay' => '[завтра]',
'lastDay' => '[вчера]',
'lastWeek' => 'l',
'sameElse' => 'l',
'withTime' => '[в] H:i',
'default' => 'd/m/Y',
),
'relativeTime' => array(
'future' => 'через %s',
'past' => '%s назад',
's' => 'несколько секунд',
'm' => 'минуту',
'mm' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d минуту', '%d минуты', '%d минут'));
},
'h' => 'час',
'hh' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d час', '%d часа', '%d часов'));
},
'd' => 'день',
'dd' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d день', '%d дня', '%d дней'));
},
'M' => 'месяц',
'MM' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d месяц', '%d месяца', '%d месяцев'));
},
'y' => 'год',
'yy' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d год', '%d года', '%d лет'));
},
),
'ordinal' => function ($number)
{
return $number . 'е';
},
'week' => array(
'dow' => 1, // Monday is the first day of the week.
'doy' => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,42 @@
<?php
// locale: Swedish (se-SV)
// author: Martin Trobäck https://github.com/lekoaf
return array(
"months" => explode('_', 'Januari_Februari_Mars_April_Maj_Juni_Juli_Augusti_September_Oktober_November_December'),
"monthsShort" => explode('_', 'Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec'),
"weekdays" => explode('_', 'Måndag_Tisdag_Onsdag_Torsdag_Fredag_Lördag_Söndag'),
"weekdaysShort" => explode('_', 'Mån_Tis_Ons_Tor_Fre_Lör_Sön'),
"calendar" => array(
"sameDay" => '[Idag]',
"nextDay" => '[Imorgon]',
"lastDay" => '[Igår]',
"lastWeek" => '[Förra] l',
"sameElse" => 'l',
"withTime" => '[kl] H:i',
"default" => 'Y/m/d',
),
"relativeTime" => array(
"future" => 'om %s',
"past" => '%s sen',
"s" => 'några sekunder',
"m" => 'en minut',
"mm" => '%d minuter',
"h" => 'en timme',
"hh" => '%d timmar',
"d" => 'en dag',
"dd" => '%d dagar',
"M" => 'en månad',
"MM" => '%d månader',
"y" => 'ett år',
"yy" => '%d år',
),
"ordinal" => function ($number) {
return $number;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,43 @@
<?php
// locale: Thailand (th_TH)
// author: Tistee Boonsuwan https://github.com/partynetwork
return array(
"months" => explode('_', 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'),
"monthsShort" => explode('_', 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'),
"weekdays" => explode('_', 'จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์_อาทิตย์'),
"weekdaysShort" => explode('_', 'จ._อ._พ._พฤ_ศ._ส._อา.'),
"calendar" => array(
"sameDay" => '[วันนี้ เวลา]',
"nextDay" => '[พรุ่งนี้ เวลา]',
"lastDay" => '[เมื่อวานนี้]',
"lastWeek" => '[สัปดาห์ที่แล้ว] l',
"sameElse" => 'l',
"withTime" => '[เมื่อ] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'อีก %s',
"past" => '%s ที่แล้ว',
"s" => 'ไม่กี่วินาที',
"m" => '1 นาที',
"mm" => '%d นาที',
"h" => '1 ชั่วโมง',
"hh" => '%d ชั่วโมง',
"d" => '1 วัน',
"dd" => '%d วัน',
"M" => '1 เดือน',
"MM" => '%d เดือน',
"y" => '1 ปี',
"yy" => '%d ปี',
),
"ordinal" => function ($number)
{
return $number ;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,63 @@
<?php
/**
* Turkish (tr-TR) language support
* @author Engin Dumlu <engindumlu@gmail.com>
* @github https://github.com/roadrunner
*/
return array(
"months" => explode('_', 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'),
"monthsNominative" => explode('_', 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'),
"monthsShort" => explode('_', 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'),
"weekdays" => explode('_', 'Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi_Pazar'),
"weekdaysShort" => explode('_', 'Pts_Sal_Çar_Per_Cum_Cts_Paz'),
"calendar" => array(
"sameDay" => '[Bugün]',
"nextDay" => '[Yarın]',
"lastDay" => '[Dün]',
"lastWeek" => '[Geçen hafta] l',
"sameElse" => 'l',
"withTime" => 'H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => '%s sonra',
"past" => '%s önce',
"s" => 'birkaç saniye',
"m" => 'bir dakika',
"mm" => '%d dakika',
"h" => 'bir saat',
"hh" => '%d saat',
"d" => 'bir gün',
"dd" => '%d gün',
"M" => 'bir ay',
"MM" => '%d ay',
"y" => 'bir yıl',
"yy" => '%d yıl',
),
"ordinal" => function ($number) {
$n = $number % 100;
$ends = array('inci', 'inci', 'üncü', 'üncü', 'inci', 'ıncı', 'inci', 'inci', 'uncu', 'uncu');
if ($number > 0 && $n == 0) {
return $number . 'uncu';
}
return $number . '[' . $ends[$number % 10] . ']';
},
"week" => array(
"dow" => 1, // `Pazartesi` is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
"customFormats" => array(
"LT" => "G:i", // 20:30
"L" => "d/m/Y", // 04/09/1986
"l" => "j/n/Y", // 4/9/1986
"LL" => "jS F Y", // 4 Septembre 1986
"ll" => "j M Y", // 4 Sep 1986
"LLL" => "jS F Y G:i", // 4 Septembre 1986 20:30
"lll" => "j M Y G:i", // 4 Sep 1986 20:30
"LLLL" => "l, jS F Y G:i", // Jeudi, 4 Septembre 1986 20:30
"llll" => "D, j M Y G:i", // Jeu, 4 Sep 1986 20:30
),
);

View file

@ -0,0 +1,118 @@
<?php
// locale: Українська (Ukrainian) (uk_UA)
// author: Mykola Pukhalskyi
/**
* returns ending for plural form of word by number and array of variants (1, 4, 5)
* example variants for apples ['яблуко', 'яблука', 'яблук']
*/
/**
* @param int $number
* @param array $endingArray
*
* @return string
*/
$getNumEnding = function ($number, array $endingArray)
{
$number = $number % 100;
if ($number >= 11 && $number <= 19)
{
return $endingArray[2];
}
$i = $number % 10;
switch ($i)
{
case (1):
$ending = $endingArray[0];
break;
case (2):
case (3):
case (4):
$ending = $endingArray[1];
break;
default:
$ending = $endingArray[2];
}
return $ending;
};
return array(
'months' => explode('_', 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'),
'monthsNominative' => explode('_', 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'),
'monthsShort' => explode('_', 'січ_лют_бер_квіт_трав_черв_лип_серп_веровт_лист_груд'),
'weekdays' => explode('_', 'понеділок_вівторок_середаетвер_пятниця_суботаеділя'),
'weekdaysShort' => explode('_', 'пн_вт_ср_чт_пт_сб_нд'),
'calendar' => array(
'sameDay' => '[сьогодні]',
'nextDay' => '[завтра]',
'lastDay' => '[вчора]', // or "учора".
'lastWeek' => 'l',
'sameElse' => 'l',
'withTime' => function (\Moment\Moment $number)
{
return $number->format('G') == 11 ? '[об] H:i' : '[о] H:i';
},
'default' => 'd-m-Y',
),
'relativeTime' => array(
// 'future' => 'о %s', // or "об"
'future' => function (\Moment\Moment $number)
{
return $number->format('G') == 11 ? 'об %s' : 'о %s';
},
'past' => '%s тому',
's' => 'кілька секунд',
'm' => 'хвилину',
'mm' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d хвилину', '%d хвилини', '%d хвилин'));
},
'h' => 'година',
'hh' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d годину', '%d години', '%d годин'));
},
'd' => 'день',
'dd' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d день', '%d дні', '%d днів'));
},
'M' => 'місяць',
'MM' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d місяць', '%d місяці', '%d місяців'));
},
'y' => 'рік',
'yy' => function ($number) use ($getNumEnding)
{
return $getNumEnding($number, array('%d рік', '%d роки', '%d років'));
},
),
'ordinal' => function ($number)
{
$n = $number % 100;
$k = $number % 10;
$ends = array('-ше', '-ге', '-тє', '-те', '-те', '-те', '-ме', '-ме', '-те', '-те');
if ($n >= 11 && $n <= 13)
{
return $number . '[th]';
}
if ($n != 13 && $k = 3) {
return $number . '[' . $ends[2] . ']';
}
return $number . '[' . $ends[$k] . ']';
},
'week' => array(
'dow' => 1, // Monday is the first day of the week.
'doy' => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,46 @@
<?php
// locale: vietnamese - Viet Nam (vi_VN)
// author: Oanh Nguyen https://github.com/oanhnn
return array(
"months" => explode('_', 'Tháng một_Tháng hai_Tháng ba_Tháng tư_Tháng năm_Tháng sáu_Tháng bảy_Tháng tám_Tháng chín_Tháng mười_Tháng mười một_Tháng mười hai'),
"monthsNominative" => explode('_', 'Tháng 1_Tháng 2_Tháng 3_Tháng 4_Tháng 5_Tháng 6_Tháng 7_Tháng 8_Tháng 9_Tháng 10_Tháng 11_Tháng 12'),
"monthsShort" => explode('_', 'Th1_Th2_Th3_Th4_Th5_Th6_Th7_Th8_Th9_Th10_Th11_Th12'),
"weekdays" => explode('_', 'Thứ 2_Thứ 3_Thứ 4_Thứ 5_Thứ 6_Thứ 7_Chủ nhật'),
"weekdaysShort" => explode('_', 'T2_T3_T4_T5_T6_T7_CN'),
"calendar" => array(
"sameDay" => '[Hôm nay]',
"nextDay" => '[Ngày mai]',
"lastDay" => '[Hôm qua]',
"lastWeek" => '[tuần trước] l',
"sameElse" => 'l',
"withTime" => '[lúc] H:i',
"default" => 'd/m/Y',
),
"relativeTime" => array(
"future" => 'vào %s',
"past" => '%s trước đây',
"s" => 'một vài giây',
"m" => 'một phút',
"mm" => '%d phút',
"h" => 'một giờ',
"hh" => '%d giờ',
"d" => 'một ngày',
"dd" => '%d ngày',
"M" => 'một tháng',
"MM" => '%d tháng',
"y" => 'một năm',
"yy" => '%d năm',
),
"ordinal" => function ($number) {
$prefix = "thứ ";
return $prefix . $number;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,68 @@
<?php
// locale: chinese (zh-cn)
// author: suupic https://github.com/suupic
// author: Zeno Zeng https://github.com/zenozeng
// author: Senorsen https://github.com/Senorsen
// author: Tino Ehrich https://github.com/fightbulc
return array(
"months" => explode('_', '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'),
"monthsShort" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
"weekdays" => explode('_', '星期一_星期二_星期三_星期四_星期五_星期六_星期日'),
"weekdaysShort" => explode('_', '周一_周二_周三_周四_周五_周六_周日'),
"weekdaysMin" => explode('_', '一_二_三_四_五_六_日'),
"calendar" => array(
"sameDay" => '[今天]',
"nextDay" => '[明天]',
"lastDay" => '[昨天]',
"lastWeek" => '[上]D',
"sameElse" => '[本]D',
"withTime" => 'H:i',
"default" => 'Y-m-d',
),
"relativeTime" => array(
"future" => '%s内',
"past" => '%s前',
"s" => '几秒',
"m" => '1分钟',
"mm" => '%d分钟',
"h" => '1小时',
"hh" => '%d小时',
"d" => '1天',
"dd" => '%d天',
"M" => '1个月',
"MM" => '%d个月',
"y" => '1年',
"yy" => '%d年',
),
"ordinal" => function ($number, $token)
{
$symbol = null;
switch ($token)
{
case 'd':
case 'w':
$symbol = '[日]';
break;
case 'n':
$symbol = '[月]';
break;
case 'W':
$symbol = '[周]';
break;
default:
}
return $number . $symbol;
},
"week" => array(
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

View file

@ -0,0 +1,66 @@
<?php
// locale: traditional chinese (zh-tw)
// author: Ben https://github.com/ben-lin
// author: Senorsen https://github.com/Senorsen
// author: Tino Ehrich https://github.com/fightbulc
return array(
"months" => explode('_', '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'),
"monthsShort" => explode('_', '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'),
"weekdays" => explode('_', '星期一_星期二_星期三_星期四_星期五_星期六_星期日'),
"weekdaysShort" => explode('_', '週一_週二_週三_週四_週五_週六_週日'),
"weekdaysMin" => explode('_', '一_二_三_四_五_六_日'),
"calendar" => array(
"sameDay" => '[今天]',
"nextDay" => '[明天]',
"lastDay" => '[昨天]',
"lastWeek" => '[上]D',
"sameElse" => '[本]D',
"withTime" => 'H:i',
"default" => 'Y-m-d',
),
"relativeTime" => array(
"future" => '%s內',
"past" => '%s前',
"s" => '幾秒',
"m" => '一分鐘',
"mm" => '%d分鐘',
"h" => '一小時',
"hh" => '%d小時',
"d" => '一天',
"dd" => '%d天',
"M" => '一個月',
"MM" => '%d個月',
"y" => '一年',
"yy" => '%d年',
),
"ordinal" => function ($number, $token)
{
$symbol = null;
switch ($token)
{
case 'd':
case 'w':
$symbol = '[日]';
break;
case 'n':
$symbol = '[月]';
break;
case 'W':
$symbol = '[週]';
break;
default:
}
return $number . $symbol;
},
"week" => array(
"dow" => 1, // Monday is the first day of the week.
"doy" => 4 // The week that contains Jan 4th is the first week of the year.
),
);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
<?php
namespace Moment;
/**
* MomentException
* @package Moment
* @author Tino Ehrich (tino@bigpun.me)
*/
class MomentException extends \Exception
{
}

View file

@ -0,0 +1,316 @@
<?php
namespace Moment;
/**
* MomentFromVo
* @package Moment
* @author Tino Ehrich (tino@bigpun.me)
*/
class MomentFromVo
{
/**
* @var Moment
*/
protected $moment;
/**
* @var string
*/
protected $direction;
/**
* @var int
*/
protected $seconds;
/**
* @var float
*/
protected $minutes;
/**
* @var float
*/
protected $hours;
/**
* @var float
*/
protected $days;
/**
* @var float
*/
protected $weeks;
/**
* @var string
*/
protected $relative;
/**
* @param Moment $moment
*/
public function __construct(Moment $moment)
{
$this->moment = $moment;
}
/**
* @return Moment
*/
public function getMoment()
{
return $this->moment;
}
/**
* @param $value
*
* @return float
*/
protected function getRoundedValue($value)
{
$value = round($value, 2);
if ($this->getDirection() === 'future')
{
$value = '-' . $value;
}
return (float)$value;
}
/**
* @param string $direction
*
* @return MomentFromVo
*/
public function setDirection($direction)
{
$this->direction = $direction;
return $this;
}
/**
* @return string
*/
public function getDirection()
{
return $this->direction === '-' ? 'future' : 'past';
}
/**
* @param float $days
*
* @return MomentFromVo
*/
public function setDays($days)
{
$this->days = $days;
return $this;
}
/**
* @return float
*/
public function getDays()
{
return $this->getRoundedValue($this->days);
}
/**
* @param float $hours
*
* @return MomentFromVo
*/
public function setHours($hours)
{
$this->hours = $hours;
return $this;
}
/**
* @return float
*/
public function getHours()
{
return $this->getRoundedValue($this->hours);
}
/**
* @param float $minutes
*
* @return MomentFromVo
*/
public function setMinutes($minutes)
{
$this->minutes = $minutes;
return $this;
}
/**
* @return float
*/
public function getMinutes()
{
return $this->getRoundedValue($this->minutes);
}
/**
* @param int $seconds
*
* @return MomentFromVo
*/
public function setSeconds($seconds)
{
$this->seconds = $seconds;
return $this;
}
/**
* @return int
*/
public function getSeconds()
{
return (int)$this->getRoundedValue($this->seconds);
}
/**
* @param mixed $weeks
*
* @return MomentFromVo
*/
public function setWeeks($weeks)
{
$this->weeks = $weeks;
return $this;
}
/**
* @return float
*/
public function getWeeks()
{
return $this->getRoundedValue($this->weeks);
}
/**
* @return float
*/
public function getMonths()
{
return $this->getRoundedValue($this->weeks / 4);
}
/**
* @return float
*/
public function getYears()
{
return $this->getRoundedValue($this->days / 365);
}
/**
* @return string
*/
public function getRelative()
{
$formatArgs = array();
if ($this->valueInRange($this->getSeconds(), 0, 45))
{
$localeKeys = array('relativeTime', 's');
$formatArgs[] = 1;
}
elseif ($this->valueInRange($this->getSeconds(), 45, 90))
{
$localeKeys = array('relativeTime', 'm');
$formatArgs[] = 1;
}
elseif ($this->valueInRange($this->getSeconds(), 90, 45 * 60))
{
$localeKeys = array('relativeTime', 'mm');
$formatArgs[] = $this->roundAbs($this->getMinutes());
}
elseif ($this->valueInRange($this->getMinutes(), 45, 90))
{
$localeKeys = array('relativeTime', 'h');
$formatArgs[] = 1;
}
elseif ($this->valueInRange($this->getMinutes(), 90, 22 * 60))
{
$localeKeys = array('relativeTime', 'hh');
$formatArgs[] = $this->roundAbs($this->getHours());
}
elseif ($this->valueInRange($this->getHours(), 22, 36))
{
$localeKeys = array('relativeTime', 'd');
$formatArgs[] = 1;
}
elseif ($this->valueInRange($this->getHours(), 36, 25 * 24))
{
$localeKeys = array('relativeTime', 'dd');
$formatArgs[] = $this->roundAbs($this->getDays());
}
elseif ($this->valueInRange($this->getDays(), 25, 45))
{
$localeKeys = array('relativeTime', 'M');
$formatArgs[] = 1;
}
elseif ($this->valueInRange($this->getDays(), 25, 345))
{
$localeKeys = array('relativeTime', 'MM');
$formatArgs[] = $this->roundAbs($this->getMonths());
}
elseif ($this->valueInRange($this->getDays(), 345, 547))
{
$localeKeys = array('relativeTime', 'y');
$formatArgs[] = 1;
}
else
{
$localeKeys = array('relativeTime', 'yy');
$formatArgs[] = $this->roundAbs($this->getYears());
}
// add to context
$formatArgs[] = $this->getDirection();
$formatArgs[] = $this->getMoment();
// render value
$time = MomentLocale::renderLocaleString($localeKeys, $formatArgs);
// render value result by direction string
return MomentLocale::renderLocaleString(array('relativeTime', $this->getDirection()), array($time));
}
/**
* @param $value
* @param $from
* @param $to
*
* @return bool
*/
private function valueInRange($value, $from, $to)
{
return abs($value) >= $from && abs($value) <= $to ? true : false;
}
/**
* @param $number
*
* @return float
*/
private function roundAbs($number)
{
return round(abs($number));
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace Moment;
/**
* MomentHelper
* @package Moment
* @author Tino Ehrich (tino@bigpun.me)
*/
class MomentHelper
{
/**
* @param $quarter
* @param $year
* @param string $timeZoneString
*
* @return MomentPeriodVo
* @throws MomentException
*/
public static function getQuarterPeriod($quarter, $year, $timeZoneString = 'UTC')
{
switch ($quarter)
{
case 1:
$startMonth = 1;
$endMonth = 3;
break;
case 2:
$startMonth = 4;
$endMonth = 6;
break;
case 3:
$startMonth = 7;
$endMonth = 9;
break;
case 4:
$startMonth = 10;
$endMonth = 12;
break;
default:
throw new MomentException('Invalid quarter. The range of quarters is 1 - 4. You asked for: ' . $quarter);
}
// set start
$start = new Moment();
$start
->setTimezone($timeZoneString)
->setYear($year)
->setMonth($startMonth)
->setDay(1)
->setTime(0, 0, 0);
// set end
$end = new Moment();
$end
->setTimezone($timeZoneString)
->setYear($year)
->setMonth($endMonth)
->setDay($end->format('t'))
->setTime(23, 59, 59);
// set period vo
$momentPeriodVo = new MomentPeriodVo();
return $momentPeriodVo
->setInterval($quarter)
->setStartDate($start)
->setEndDate($end);
}
}

View file

@ -0,0 +1,173 @@
<?php
namespace Moment;
/**
* MomentLocale
* @package Moment
* @author Tino Ehrich (tino@bigpun.me)
*/
class MomentLocale
{
/**
* @var Moment
*/
private static $moment;
/**
* @var string
*/
private static $locale = 'en_GB';
/**
* @var array
*/
private static $localeContent = array();
/**
* @param Moment $moment
*/
public static function setMoment(Moment $moment)
{
self::$moment = $moment;
}
/**
* @param $locale
*
* @return void
* @throws MomentException
*/
public static function setLocale($locale)
{
self::$locale = $locale;
self::loadLocaleContent();
}
/**
* @return void
* @throws MomentException
*/
public static function loadLocaleContent()
{
$pathFile = __DIR__ . '/Locales/' . self::$locale . '.php';
if (file_exists($pathFile) === false)
{
throw new MomentException('Locale does not exist: ' . $pathFile);
}
self::$localeContent = require $pathFile;
}
/**
* @return array
*/
public static function getLocaleContent()
{
return self::$localeContent;
}
/**
* @param array $keys
*
* @return array|string|\Closure
* @throws MomentException
*/
public static function getLocaleString(array $keys)
{
$string = self::$localeContent;
foreach ($keys as $key)
{
if (isset($string[$key]) === false)
{
throw new MomentException('Locale string does not exist for key: ' . join(' > ', $keys));
}
$string = $string[$key];
}
return $string;
}
/**
* @param array $localeKeys
* @param array $formatArgs
*
* @return string
*/
public static function renderLocaleString(array $localeKeys, array $formatArgs = array())
{
// get locale handler
$localeString = self::getLocaleString($localeKeys);
// handle callback
if ($localeString instanceof \Closure)
{
$localeString = call_user_func_array($localeString, $formatArgs);
}
return vsprintf($localeString, $formatArgs);
}
/**
* @param string $format
*
* @return string
*/
public static function prepareSpecialLocaleTags($format)
{
$placeholders = array(
// months
'(?<!\\\)F' => 'n__0001',
'(?<!\\\)M' => 'n__0002',
'(?<!\\\)f' => 'n__0005',
// weekdays
'(?<!\\\)l' => 'N__0003',
'(?<!\\\)D' => 'N__0004',
);
foreach ($placeholders as $regexp => $tag)
{
$format = preg_replace('/' . $regexp . '/u', $tag, $format);
}
return $format;
}
/**
* @param string $format
*
* @return string
*/
public static function renderSpecialLocaleTags($format)
{
$placeholders = array(
// months
'\d{1,2}__0001' => 'months',
'\d{1,2}__0002' => 'monthsShort',
'\d{1,2}__0005' => 'monthsNominative',
// weekdays
'\d__0003' => 'weekdays',
'\d__0004' => 'weekdaysShort',
);
foreach ($placeholders as $regexp => $tag)
{
preg_match_all('/(' . $regexp . ')/', $format, $match);
if (isset($match[1]))
{
foreach ($match[1] as $date)
{
list($localeIndex, $type) = explode('__', $date);
$localeString = self::renderLocaleString(array($tag, --$localeIndex));
$format = preg_replace('/' . $date . '/u', $localeString, $format);
}
}
}
return $format;
}
}

View file

@ -0,0 +1,103 @@
<?php
namespace Moment;
/**
* MomentPeriodVo
* @package Moment
* @author Tino Ehrich (tino@bigpun.me)
*/
class MomentPeriodVo
{
/** @var Moment */
protected $startDate;
/** @var Moment */
protected $endDate;
/** @var Moment */
protected $refDate;
/** @var int */
protected $interval;
/**
* @return int
*/
public function getInterval()
{
return $this->interval;
}
/**
* @param int $interval
*
* @return MomentPeriodVo
*/
public function setInterval($interval)
{
$this->interval = $interval;
return $this;
}
/**
* @param Moment $reference
*
* @return MomentPeriodVo
*/
public function setRefDate(Moment $reference)
{
$this->refDate = $reference;
return $this;
}
/**
* @return \Moment\Moment
*/
public function getRefDate()
{
return $this->refDate;
}
/**
* @param Moment $end
*
* @return MomentPeriodVo
*/
public function setEndDate(Moment $end)
{
$this->endDate = $end;
return $this;
}
/**
* @return Moment
*/
public function getEndDate()
{
return $this->endDate;
}
/**
* @param Moment $start
*
* @return MomentPeriodVo
*/
public function setStartDate(Moment $start)
{
$this->startDate = $start;
return $this;
}
/**
* @return Moment
*/
public function getStartDate()
{
return $this->startDate;
}
}

View file

@ -0,0 +1,3 @@
<?php
require __DIR__ . '/../vendor/autoload.php';

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="bootstrap.php" backupGlobals="false" colors="true" backupStaticAttributes="false" strict="true" verbose="true">
<testsuites>
<testsuite name="unit">
<directory>unit</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -0,0 +1,8 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
$twitterCreatedAt = 'Fri Jun 24 17:43:26 +0000 2011';
$m = new \Moment\Moment($twitterCreatedAt);
echo $m->format('U');

View file

@ -0,0 +1,221 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>moment.php testing</title>
<style>
body
{
font-family: "Helvetica Neue";
}
div
{
background: #eee;
padding: 10px 20px;
margin-bottom: 10px;
}
pre
{
background: #cef;
}
code
{
display: block;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<h1>Moment.php</h1>
<p>Wrapper for PHP's DateTime class inspired by moment.js</p>
<div>
<h3>1. DateTime from "Now" (UTC)</h3>
<p>{{test01}}</p>
</div>
<div>
<h3>2. Set date and add 2 hours</h3>
<p><strong>Date:</strong> 15.05.2012 12:30:00 (CET)</p>
<p>{{test02}}</p>
</div>
<div>
<h3>3. Set date and subtract 7 days and 15 minutes</h3>
<p><strong>Date:</strong> 15.05.2012 12:30:00 (CET)</p>
<p>{{test03}}</p>
</div>
<div>
<h3>4. Difference between two dates</h3>
<p><strong>Date#1:</strong> 12.05.2012 / 15:00:00 (UTC)</p>
<p><strong>Date#2:</strong> 25.09.2011 / 10:00:00 (UTC)</p>
<p><strong>Difference seconds:</strong> {{test04.01}}</p>
<p><strong>Difference in minutes:</strong> {{test04.02}}</p>
<p><strong>Difference in hours:</strong> {{test04.03}}</p>
<p><strong>Difference in days:</strong> {{test04.04}}</p>
<p><strong>Difference in weeks:</strong> {{test04.05}}</p>
<p><strong>Difference in months:</strong> {{test04.06}}</p>
<p><strong>Difference in years:</strong> {{test04.07}}</p>
<p><strong>Difference relative:</strong> {{test04.08}}</p>
</div>
<div>
<h3>5. Difference Date#1 to "Now"</h3>
<p><strong>Date#1:</strong> {{test05.00}}</p>
<p><strong>Difference seconds:</strong> {{test05.01}}</p>
<p><strong>Difference in minutes:</strong> {{test05.02}}</p>
<p><strong>Difference in hours:</strong> {{test05.03}}</p>
<p><strong>Difference in days:</strong> {{test05.04}}</p>
<p><strong>Difference in weeks:</strong> {{test05.05}}</p>
<p><strong>Difference in months:</strong> {{test05.06}}</p>
<p><strong>Difference in years:</strong> {{test05.07}}</p>
<p><strong>Difference relative:</strong> {{test05.08}}</p>
</div>
<div>
<h3>6. CET to UTC</h3>
<p><strong>CET:</strong> {{test06.01}}</p>
<p><strong>UTC:</strong> {{test06.02}}</p>
</div>
<div>
<h3>7. Custom format</h3>
<p>{{test07.00}}</p>
<p><strong>Default locale (L):</strong> {{test07.01}}</p>
<p><strong>fr_FR locale (LT):</strong> {{test07.02}}</p>
<p><strong>fr_FR locale (L):</strong> {{test07.03}}</p>
<p><strong>fr_FR locale (l):</strong> {{test07.04}}</p>
<p><strong>fr_FR locale (LL):</strong> {{test07.05}}</p>
<p><strong>fr_FR locale (ll):</strong> {{test07.06}}</p>
<p><strong>fr_FR locale (LLL):</strong> {{test07.07}}</p>
<p><strong>fr_FR locale (lll):</strong> {{test07.08}}</p>
<p><strong>fr_FR locale (LLLL):</strong> {{test07.09}}</p>
<p><strong>fr_FR locale (llll):</strong> {{test07.10}}</p>
</div>
<div>
<h3>8. Get period</h3>
Reference date for calculating period: {{test08.00}}
<br>
<br>
<strong>Weekly period:</strong>
<ul>
<li><strong>starts on:</strong> {{test08.01}}</li>
<li><strong>ends on:</strong> {{test08.02}}</li>
<li><strong>interval:</strong> {{test08.03}}</li>
</ul>
<br>
<strong>Monthly period:</strong>
<ul>
<li><strong>starts on:</strong> {{test08.04}}</li>
<li><strong>ends on:</strong> {{test08.05}}</li>
<li><strong>interval:</strong> {{test08.06}}</li>
</ul>
<br>
<strong>Quarter period:</strong>
<ul>
<li><strong>starts on:</strong> {{test08.07}}</li>
<li><strong>ends on:</strong> {{test08.08}}</li>
<li><strong>interval:</strong> {{test08.09}}</li>
</ul>
</div>
<div>
<h3>9. Use other format definitions via FormatsInterface</h3>
Reference date '2012-04-25T03:00:00' in 'CET'.
<p><strong>Moment.php format:</strong><br>"l, F jS Y g:i A"<br>{{test09.01}}</p>
<p><strong>Moment.js</strong><br>"LLLL"<br>{{test09.02}}</p>
<p><strong>Moment.php format:</strong>&nbsp;(with fixed ordinal representation)<br>"WS [week of the year]"<br>{{test09.03}}
</p>
<p><strong>Moment.js</strong><br>"WO"<br>{{test09.04}}</p>
</div>
<div>
<h3>10. Calendar Time</h3>
<p>Calendar time displays time relative to now, but slightly differently than moment::fromNow.</p>
<p>moment::calendar will format a date with different strings depending on how close to today the date is.</p>
<p><strong>Last week</strong><br>{{test10.01}}</p>
<p><strong>The day before</strong><br>{{test10.02}}</p>
<p><strong>The same day</strong><br>{{test10.03}}</p>
<p><strong>The next day</strong><br>{{test10.04}}</p>
<p><strong>Upcoming days</strong><br>{{test10.05}}</p>
<p><strong>Everything else</strong><br>{{test10.06}}</p>
</div>
<div>
<h3>11. startOf()</h3>
<p style="background:#ffe"><strong>Reference date</strong> {{test11.00}}</p>
<ul>
<li><strong>Minute</strong><br>{{test11.01}}</li>
<li><strong>Hour</strong><br>{{test11.02}}</li>
<li><strong>Day</strong><br>{{test11.03}}</li>
<li><strong>Week</strong><br>{{test11.04}}</li>
<li><strong>Month</strong><br>{{test11.05}}</li>
<li><strong>Quarter</strong><br>{{test11.06}}</li>
<li><strong>Year</strong><br>{{test11.07}}</li>
</ul>
</div>
<div>
<h3>12. endOf()</h3>
<p style="background:#ffe"><strong>Reference date</strong> {{test12.00}}</p>
<ul>
<li><strong>Minute</strong><br>{{test12.01}}</li>
<li><strong>Hour</strong><br>{{test12.02}}</li>
<li><strong>Day</strong><br>{{test12.03}}</li>
<li><strong>Week</strong><br>{{test12.04}}</li>
<li><strong>Month</strong><br>{{test12.05}}</li>
<li><strong>Quarter</strong><br>{{test12.06}}</li>
<li><strong>Year</strong><br>{{test12.07}}</li>
</ul>
</div>
</body>
</html>

View file

@ -0,0 +1,189 @@
<?php
require __DIR__ . '/../vendor/autoload.php';
$response = array();
// ############################################
$m = new \Moment\Moment();
$response['test01'] = $m->format();
// ------------------------------------------
$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
$response['test02'] = $m->addHours(2)->format();
// ------------------------------------------
$m = new \Moment\Moment('2012-05-15T12:30:00', 'CET');
$response['test03'] = $m
->subtractDays(7)
->subtractMinutes(15)
->format();
// ------------------------------------------
$m = new \Moment\Moment('2013-02-01T07:00:00');
$result = $m->from('2011-09-25T10:00:00');
$response['test04.01'] = $result->getSeconds();
$response['test04.02'] = $result->getMinutes();
$response['test04.03'] = $result->getHours();
$response['test04.04'] = $result->getDays();
$response['test04.05'] = $result->getWeeks();
$response['test04.06'] = $result->getMonths();
$response['test04.07'] = $result->getYears();
$response['test04.08'] = $result->getRelative();
// ------------------------------------------
$m = new \Moment\Moment('2014-12-09T07:00:00');
$result = $m->fromNow();
$response['test05.00'] = $m->format('c');
$response['test05.01'] = $result->getSeconds();
$response['test05.02'] = $result->getMinutes();
$response['test05.03'] = $result->getHours();
$response['test05.04'] = $result->getDays();
$response['test05.05'] = $result->getWeeks();
$response['test05.06'] = $result->getMonths();
$response['test05.07'] = $result->getYears();
$response['test05.08'] = $result->getRelative();
// ------------------------------------------
$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
$response['test06.01'] = $m->format();
$response['test06.02'] = $m->setTimezone('UTC')->format();
// ------------------------------------------
$m = new \Moment\Moment('2012-04-25T15:00:00', 'CET');
$response['test07.00'] = $m->format('l, dS F Y / H:i (e)');
$momentJs = new \Moment\CustomFormats\MomentJs();
$response['test07.01'] = $m->format('LT', $momentJs);
$m->setLocale('fr_FR');
$response['test07.02'] = $m->format('LT', $momentJs);
$response['test07.03'] = $m->format('L', $momentJs);
$response['test07.04'] = $m->format('l', $momentJs);
$response['test07.05'] = $m->format('LL', $momentJs);
$response['test07.06'] = $m->format('ll', $momentJs);
$response['test07.07'] = $m->format('LLL', $momentJs);
$response['test07.08'] = $m->format('lll', $momentJs);
$response['test07.09'] = $m->format('LLLL', $momentJs);
$response['test07.10'] = $m->format('llll', $momentJs);
// ------------------------------------------
$m = new \Moment\Moment('2013-10-23T10:00:00', 'CET');
$momentPeriodVo = $m->getPeriod('week');
$response['test08.00'] = $momentPeriodVo
->getRefDate()
->format('Y-m-d');
$response['test08.01'] = $momentPeriodVo
->getStartDate()
->format('Y-m-d');
$response['test08.02'] = $momentPeriodVo
->getEndDate()
->format('Y-m-d');
$response['test08.03'] = $momentPeriodVo->getInterval();
$momentPeriodVo = $m->getPeriod('month');
$response['test08.04'] = $momentPeriodVo
->getStartDate()
->format('Y-m-d');
$response['test08.05'] = $momentPeriodVo
->getEndDate()
->format('Y-m-d');
$response['test08.06'] = $momentPeriodVo->getInterval();
$momentPeriodVo = $m->getPeriod('quarter');
$response['test08.07'] = $momentPeriodVo
->getStartDate()
->format('Y-m-d');
$response['test08.08'] = $momentPeriodVo
->getEndDate()
->format('Y-m-d');
$response['test08.09'] = $momentPeriodVo->getInterval();
// ------------------------------------------
//$m = new \Moment\Moment('2012-04-25T03:00:00', 'CET');
$response['test09.01'] = $m->format('l, F jS Y g:i A');
$response['test09.02'] = $m->format('LLLL', new \Moment\CustomFormats\MomentJs());
$response['test09.03'] = $m->format('WS [week of the year]');
$response['test09.04'] = $m->format('Wo [week of the year]', new \Moment\CustomFormats\MomentJs());
// ------------------------------------------
$date = 'now';
// last week
$m = new \Moment\Moment($date, 'CET');
$response['test10.01'] = $m->subtractDays(6)->calendar();
// yesterday
$m = new \Moment\Moment($date, 'CET');
$response['test10.02'] = $m->subtractDays(1)->calendar();
// today
$m = new \Moment\Moment($date, 'CET');
$response['test10.03'] = $m->calendar();
// tomorrow
$m = new \Moment\Moment($date, 'CET');
$response['test10.04'] = $m->addDays(1)->calendar();
$m = new \Moment\Moment($date, 'CET');
$response['test10.05'] = $m->addDays(3)->calendar();
// everything else
$m = new \Moment\Moment($date, 'CET');
$response['test10.06'] = $m->addDays(10)->calendar();
// ------------------------------------------
$date = '20140515T10:15:23';
$m = new \Moment\Moment($date, 'CET');
$response['test11.00'] = $m->format();
foreach (array('minute', 'hour', 'day', 'week', 'month', 'quarter', 'year') as $k => $period)
{
$index = $k + 1;
$response['test11.0' . $index] = $m->startOf($period)->format();
}
// ------------------------------------------
$date = '20140515T10:15:23';
$m = new \Moment\Moment($date, 'CET');
$response['test12.00'] = $m->format();
foreach (array('minute', 'hour', 'day', 'week', 'month', 'quarter', 'year') as $k => $period)
{
$index = $k + 1;
$response['test12.0' . $index] = $m->endOf($period)->format();
}
// ############################################
$tmpl = join('', file('test.html'));
foreach ($response as $key => $value)
{
$tmpl = str_replace('{{' . $key . '}}', $value, $tmpl);
}
echo $tmpl;

View file

@ -0,0 +1,90 @@
<?php
namespace Moment;
class MomentFrenchLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('fr_FR');
}
public function testWeekdayNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('lun.', 'lundi'),
2 => array('mar.', 'mardi'),
3 => array('mer.', 'mercredi'),
4 => array('jeu.', 'jeudi'),
5 => array('ven.', 'vendredi'),
6 => array('sam.', 'samedi'),
7 => array('dim.', 'dimanche'),
);
for ($d = 1; $d < 7; $d++)
{
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testMonthNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$monthNames = array(
1 => array('janv.', 'janvier'),
2 => array('févr.', 'février'),
3 => array('mars', 'mars'),
4 => array('avr.', 'avril'),
5 => array('mai', 'mai'),
6 => array('juin', 'juin'),
7 => array('juil.', 'juillet'),
8 => array('août', 'août'),
9 => array('sept.', 'septembre'),
10 => array('oct.', 'octobre'),
11 => array('nov.', 'novembre'),
12 => array('déc.', 'décembre'),
);
for ($d = 1; $d < 12; $d++)
{
$this->assertEquals($monthNames[$moment->format('n')][0], $moment->getMonthNameShort(), 'month short name failed');
$this->assertEquals($monthNames[$moment->format('n')][1], $moment->getMonthNameLong(), 'month long name failed');
$moment->addMonths(1);
}
}
public function testFormat()
{
$a = array(
array('l, F d Y, g:i:s a', 'dimanche, février 14 2010, 3:25:50 pm'),
array('D, gA', 'dim., 3PM'),
array('n m F M', '2 02 février févr.'),
array('Y y', '2010 10'),
array('j d', '14 14'),
array('[the] z [day of the year]', 'the 44 day of the year')
);
$b = new Moment('2010-02-14 15:25:50');
for ($i = 0; $i < count($a); $i++) {
$this->assertEquals($a[$i][1], $b->format($a[$i][0]));
}
}
public function testRelative()
{
$beginningMoment = new Moment('2015-06-14 20:46:22', 'Europe/Berlin');
$endMoment = new Moment('2015-06-14 20:48:32', 'Europe/Berlin');
$this->assertEquals('dans 2 minutes', $endMoment->from($beginningMoment)->getRelative());
$this->assertEquals('il y a 2 minutes', $beginningMoment->from($endMoment)->getRelative());
}
}

View file

@ -0,0 +1,87 @@
<?php
namespace Moment;
class MomentGermanLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('de_DE');
}
public function testWeekdayNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('Mo', 'Montag'),
2 => array('Di', 'Dienstag'),
3 => array('Mi', 'Mittwoch'),
4 => array('Do', 'Donnerstag'),
5 => array('Fr', 'Freitag'),
6 => array('Sa', 'Samstag'),
7 => array('So', 'Sonntag'),
);
for ($d = 1; $d < 7; $d++)
{
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testMonthNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$monthNames = array(
1 => array('Jan', 'Januar'),
2 => array('Feb', 'Februar'),
3 => array('Mär', 'März'),
4 => array('Apr', 'April'),
5 => array('Mai', 'Mai'),
6 => array('Jun', 'Juni'),
7 => array('Jul', 'Juli'),
8 => array('Aug', 'August'),
9 => array('Sep', 'September'),
10 => array('Okt', 'Oktober'),
11 => array('Nov', 'November'),
12 => array('Dez', 'Dezember'),
);
for ($d = 1; $d < 12; $d++)
{
$this->assertEquals($monthNames[$moment->format('n')][0], $moment->getMonthNameShort(), 'month short name failed');
$this->assertEquals($monthNames[$moment->format('n')][1], $moment->getMonthNameLong(), 'month long name failed');
$moment->addMonths(1);
}
}
public function testHirbodIssueLocaleDate001()
{
// @see: https://github.com/fightbulc/moment.php/issues/50
$string = '2015-06-14 20:46:22';
$moment = new Moment($string, 'Europe/Berlin');
$this->assertEquals('14. Juni', $moment->format('d. F'));
$string = '2015-03-08T15:14:53-0500';
$moment = new Moment($string, 'Europe/Berlin');
$this->assertEquals('08. März', $moment->format('d. F'));
}
public function testHirbodIssueLocaleDate002()
{
// @see: https://github.com/fightbulc/moment.php/issues/61
$moment = new Moment('2016-01-03 16:17:07', 'Europe/Berlin');
$this->assertEquals('03. Dezember', $moment->subtractMonths(1)->format('d. F'));
}
}

View file

@ -0,0 +1,122 @@
<?php
namespace Moment;
class MomentPolishLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('pl_PL');
}
public function testWeekdayNames()
{
$startingDate = '2016-01-29T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('pon.', 'poniedziałek'),
2 => array('wt.', 'wtorek'),
3 => array('śr.', 'środa'),
4 => array('czw.', 'czwartek'),
5 => array('pt.', 'piątek'),
6 => array('sob.', 'sobota'),
7 => array('niedz.', 'niedziela'),
);
for ($d = 1; $d < 7; $d++) {
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testDayMonthFormat001()
{
$string = '2015-06-14 20:46:22';
$moment = new Moment($string, 'Europe/Berlin');
$this->assertEquals('14 czerwca', $moment->format('j F'));
$string = '2015-03-08T15:14:53-0500';
$moment = new Moment($string, 'Europe/Berlin');
$this->assertEquals('8 marca', $moment->format('j F'));
}
public function testDayMonthFormat002()
{
$moment = new Moment('2016-01-03 16:17:07', 'Europe/Berlin');
$this->assertEquals('3 grudnia', $moment->subtractMonths(1)->format('j F'));
}
public function testMonthFormatFN()
{
$startingDate = '2016-01-01T00:00:00+0000';
$moment = new Moment($startingDate);
$monthsNominative = array(
1 => 'styczeń',
2 => 'luty',
3 => 'marzec',
4 => 'kwiecień',
5 => 'maj',
6 => 'czerwiec',
7 => 'lipiec',
8 => 'sierpień',
9 => 'wrzesień',
10 => 'październik',
11 => 'listopad',
12 => 'grudzień'
);
for ($d = 1; $d < count($monthsNominative); $d++) {
$this->assertEquals($monthsNominative[$moment->format('n')], $moment->format('f'), 'month nominative failed');
$moment->addMonths(1);
}
}
public function testMinutes()
{
$past = new Moment('2016-01-03 16:17:07', 'Europe/Berlin');
$relative = $past->from('2016-01-03 16:34:07');
$this->assertEquals('17 minut temu', $relative->getRelative());
$relative = $past->from('2016-01-03 16:40:07');
$this->assertEquals('23 minuty temu', $relative->getRelative());
$relative = $past->from('2016-01-03 16:30:07');
$this->assertEquals('13 minut temu', $relative->getRelative());
}
public function testLastWeekWeekend()
{
$past = new Moment('2016-04-10');
$this->assertEquals('ostatnia niedziela', $past->calendar(false, new Moment('2016-04-12')));
$past = new Moment('2016-04-11');
$this->assertEquals('ostatni poniedziałek', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-12');
$this->assertEquals('ostatni wtorek', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-13');
$this->assertEquals('ostatnia środa', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-14');
$this->assertEquals('ostatni czwartek', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-15');
$this->assertEquals('ostatni piątek', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('wczoraj', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('ostatnia sobota', $past->calendar(false, new Moment('2016-04-18')));
}
}

View file

@ -0,0 +1,150 @@
<?php
namespace Moment;
class MomentRussianLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('ru_RU');
}
public function testWeekdayNames()
{
$startingDate = '2016-01-29T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('пн', 'понедельник'),
2 => array('вт', 'вторник'),
3 => array('ср', 'среда'),
4 => array('чт', 'четверг'),
5 => array('пт', 'пятница'),
6 => array('сб', 'суббота'),
7 => array('вс', 'воскресенье'),
);
for ($d = 1; $d < 7; $d++) {
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testDayMonthFormat001()
{
$string = '2015-06-14 20:46:22';
$moment = new Moment($string, 'Europe/Moscow');
$this->assertEquals('14 июня', $moment->format('j F'));
$string = '2015-03-08T15:14:53-0500';
$moment = new Moment($string, 'Europe/Moscow');
$this->assertEquals('8 марта', $moment->format('j F'));
}
public function testDayMonthFormat002()
{
$moment = new Moment('2016-01-03 16:17:07', 'Europe/Moscow');
$this->assertEquals('3 декабря', $moment->subtractMonths(1)->format('j F'));
}
public function testMonthFormatFN()
{
$startingDate = '2016-01-01T00:00:00+0000';
$moment = new Moment($startingDate);
$monthsNominative = array(
1 => 'январь',
2 => 'февраль',
3 => 'март',
4 => 'апрель',
5 => 'май',
6 => 'июнь',
7 => 'июль',
8 => 'август',
9 => 'сентябрь',
10 => 'октябрь',
11 => 'ноябрь',
12 => 'декабрь'
);
for ($d = 1; $d < count($monthsNominative); $d++) {
$this->assertEquals($monthsNominative[$moment->format('n')], $moment->format('f'), 'month nominative failed');
$moment->addMonths(1);
}
}
public function testMinutes()
{
$past = new Moment('2016-01-03 16:17:07', 'Europe/Moscow');
$relative = $past->from('2016-01-03 16:34:07');
$this->assertEquals('17 минут назад', $relative->getRelative());
$relative = $past->from('2016-01-03 16:40:07');
$this->assertEquals('23 минуты назад', $relative->getRelative());
$relative = $past->from('2016-01-03 16:30:07');
$this->assertEquals('13 минут назад', $relative->getRelative());
}
public function testLastWeekWeekend()
{
$past = new Moment('2016-04-10 16:30:07');
$this->assertEquals('воскресенье в 16:30', $past->calendar(true, new Moment('2016-04-12')));
$past = new Moment('2016-04-11');
$this->assertEquals('понедельник', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-12');
$this->assertEquals('вторник', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-13');
$this->assertEquals('среда', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-14');
$this->assertEquals('четверг', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-15');
$this->assertEquals('пятница', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('вчера', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('суббота', $past->calendar(false, new Moment('2016-04-18')));
}
public function testFutureRelative()
{
$date = new Moment('2017-01-11 01:00:00');
$this->assertEquals('через несколько секунд', $date->from('2017-01-11 00:59:59')->getRelative(), 'seconds');
$this->assertEquals('через 2 минуты', $date->from('2017-01-11 00:58:00')->getRelative(), 'minutes');
$this->assertEquals('через 2 часа', $date->from('2017-01-10 23:00:00')->getRelative(), 'hours');
$this->assertEquals('через день', $date->from('2017-01-10 00:00:00')->getRelative(), 'days');
$this->assertEquals('через месяц', $date->from('2016-12-11 00:00:00')->getRelative(), 'month');
$this->assertEquals('через год', $date->from('2016-01-11 00:00:00')->getRelative(), 'year');
}
public function testOrdinalFormat()
{
$date = new Moment('2017-01-01 01:00:00');
$this->assertEquals('1е января 2017', $date->format('jS F Y'));
$date = new Moment('2017-01-12 01:00:00');
$this->assertEquals('12е января 2017', $date->format('jS F Y'));
$date = new Moment('2017-01-23 01:00:00');
$this->assertEquals('23е января 2017', $date->format('jS F Y'));
$date = new Moment('2017-01-25 01:00:00');
$this->assertEquals('25е января 2017', $date->format('jS F Y'));
}
}

View file

@ -0,0 +1,480 @@
<?php
namespace Moment;
class MomentTest extends \PHPUnit_Framework_TestCase
{
public function testMoment()
{
$data = '1923-12-31 12:30:00';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0000', $m->format());
$data = '1923-12-31T12:30:00.000';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0000', $m->format());
$data = '1923-12-31T12:30:00.123';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0000', $m->format());
$data = '1923-12-31T12:30:00.123+02:00';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0200', $m->format());
$data = '1923-12-31T12:30:00.123+0200';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0200', $m->format());
$data = '1923-12-31T12:30:00.123Z';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0000', $m->format());
$data = '1923-12-31T12:30:00.123Europe/Warsaw';
$m = new Moment($data);
$this->assertEquals('1923-12-31T12:30:00+0100', $m->format());
$data = '1923-12-31T12:30:00.123Europe/Warsaw';
$m = new Moment($data, 'UTC');
$this->assertEquals('1923-12-31T12:30:00+0100', $m->format());
$data = '1923-12-31T12:30:00.123UTC';
$m = new Moment($data, 'Europe/Warsaw');
$this->assertEquals('1923-12-31T12:30:00+0000', $m->format());
}
public function testIsMoment()
{
$m = new Moment();
$this->assertFalse($m->isMoment('2012-12-01T12:00:00'));
$this->assertTrue($m->isMoment(new Moment('2012-12-01T12:00:00')));
}
public function testFromOnLeapYear()
{
$m = new Moment('2017-01-01 00:00:00');
$from = $m->from('2016-01-01 00:00:00');
$this->assertEquals(-366, $from->getSeconds() / 60 / 60 / 24);
}
public function testIsBefore()
{
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T10:10:12');
$this->assertTrue($s->isBefore($i));
$this->assertFalse($i->isBefore($s));
$this->assertFalse($s->isBefore($i, 'minute'));
$this->assertFalse($i->isBefore($s, 'minute'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T10:12:12');
$this->assertTrue($s->isBefore($i, 'minute'));
$this->assertFalse($i->isBefore($s, 'minute'));
$this->assertFalse($s->isBefore($i, 'hour'));
$this->assertFalse($i->isBefore($s, 'hour'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T12:12:12');
$this->assertTrue($s->isBefore($i, 'minute'));
$this->assertFalse($i->isBefore($s, 'minute'));
$this->assertFalse($s->isBefore($i, 'day'));
$this->assertFalse($i->isBefore($s, 'day'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-02T12:12:12');
$this->assertTrue($s->isBefore($i, 'day'));
$this->assertFalse($i->isBefore($s, 'day'));
$this->assertFalse($s->isBefore($i, 'month'));
$this->assertFalse($i->isBefore($s, 'month'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-02-02T12:12:12');
$this->assertTrue($s->isBefore($i, 'month'));
$this->assertFalse($i->isBefore($s, 'month'));
$this->assertFalse($s->isBefore($i, 'year'));
$this->assertFalse($i->isBefore($s, 'year'));
//from string
$s = new Moment('2014-01-01T10:10:11');
$i = '2014-01-01T10:12:12';
$this->assertTrue($s->isBefore($i, 'minute'));
$s = '2014-01-01T10:10:11';
$i = new Moment('2014-01-01T10:12:12');
$this->assertFalse($i->isBefore($s, 'minute'));
}
public function testIsAfter()
{
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T10:10:12');
$this->assertTrue($i->isAfter($s));
$this->assertFalse($s->isAfter($i));
$this->assertFalse($s->isAfter($i, 'minute'));
$this->assertFalse($i->isAfter($s, 'minute'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T10:12:12');
$this->assertFalse($s->isAfter($i, 'minute'));
$this->assertTrue($i->isAfter($s, 'minute'));
$this->assertFalse($s->isAfter($i, 'hour'));
$this->assertFalse($i->isAfter($s, 'hour'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-01T12:12:12');
$this->assertFalse($s->isAfter($i, 'minute'));
$this->assertTrue($i->isAfter($s, 'minute'));
$this->assertFalse($s->isAfter($i, 'day'));
$this->assertFalse($i->isAfter($s, 'day'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-01-02T12:12:12');
$this->assertFalse($s->isAfter($i, 'day'));
$this->assertTrue($i->isAfter($s, 'day'));
$this->assertFalse($s->isAfter($i, 'month'));
$this->assertFalse($i->isAfter($s, 'month'));
$s = new Moment('2014-01-01T10:10:11');
$i = new Moment('2014-02-02T12:12:12');
$this->assertFalse($s->isAfter($i, 'month'));
$this->assertTrue($i->isAfter($s, 'month'));
$this->assertFalse($s->isAfter($i, 'year'));
$this->assertFalse($i->isAfter($s, 'year'));
//from string
$s = new Moment('2014-01-01T10:10:11');
$i = '2014-01-01T10:12:12';
$this->assertFalse($s->isAfter($i, 'minute'));
$s = '2014-01-01T10:10:11';
$i = new Moment('2014-01-01T10:12:12');
$this->assertTrue($i->isAfter($s, 'minute'));
}
public function testIsAfterTz()
{
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T10:10:00+0000');
$this->assertTrue($i->isAfter($s));
$this->assertFalse($s->isAfter($i));
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T10:10:01+0000');
$this->assertTrue($i->isAfter($s));
$this->assertFalse($s->isAfter($i));
$s = new Moment('2014-01-01T10:10:00CET');
$i = new Moment('2014-01-01T09:10:00UTC');
$this->assertFalse($i->isAfter($s));
$this->assertFalse($s->isAfter($i));
$s = new Moment('2014-01-01T10:10:00Europe/Warsaw');
$i = new Moment('2014-01-01T09:10:01UTC');
$this->assertTrue($i->isAfter($s));
$this->assertFalse($s->isAfter($i));
}
public function testIsSame()
{
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T10:10:00+0000');
$this->assertFalse($i->isSame($s));
$this->assertFalse($s->isSame($i));
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T10:10:00CET');
$this->assertTrue($i->isSame($s));
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T10:10:00Europe/Warsaw');
$this->assertTrue($i->isSame($s));
$s = new Moment('2014-01-01T10:10:00CET');
$i = new Moment('2014-01-01T09:10:00UTC');
$this->assertTrue($i->isSame($s));
$s = new Moment('2014-01-01T10:10:00+0100');
$i = '2014-01-01T10:10:00Europe/Warsaw';
$this->assertTrue($s->isSame($i));
//Periods
$s = new Moment('2014-01-01T10:10:00+0100');
$i = new Moment('2014-01-01T09:10:01+0000');
$this->assertFalse($i->isSame($s));
$this->assertTrue($i->isSame($s, 'minute'));
$i = new Moment('2014-01-01T09:11:01+0000');
$this->assertFalse($i->isSame($s, 'minute'));
$this->assertTrue($i->isSame($s, 'hour'));
}
public function testIsSameHour()
{
// half an hour abbreviation
$s = new Moment('2014-01-01T09:40:00+0030');
$i = new Moment('2014-01-01T09:10:00+0000');
$this->assertTrue($i->isSame($s));
$this->assertTrue($s->isSame($i));
$s = new Moment('2014-01-01T10:05:00+0045');
$i = new Moment('2014-01-01T09:20:00+0000');
$this->assertTrue($i->isSame($s));
$this->assertTrue($s->isSame($i));
$s = new Moment('2014-01-01T10:04:00+0045');
$i = new Moment('2014-01-01T09:20:00+0000');
$this->assertTrue($i->isSame($s, 'hour'));
$this->assertTrue($s->isSame($i, 'hour'));
}
public function testIsSameDay()
{
$s = new Moment('2014-01-01T00:14:00+0230');
$i = new Moment('2013-12-31T23:45:00+0000');
$this->assertFalse($i->isSame($s));
$this->assertFalse($s->isSame($i));
$this->assertFalse($i->isSame($s, 'hour'));
$this->assertFalse($s->isSame($i, 'hour'));
$this->assertTrue($i->isSame($s, 'day'));
$this->assertTrue($s->isSame($i, 'day'));
$this->assertTrue($i->isSame($s, 'month'));
$this->assertTrue($s->isSame($i, 'month'));
$this->assertTrue($i->isSame($s, 'year'));
$this->assertTrue($s->isSame($i, 'year'));
}
public function testIsSameMonth()
{
$s = new Moment('2014-01-01T00:14:00+0230');
$i = new Moment('2013-12-30T23:45:00+0000');
$this->assertFalse($i->isSame($s));
$this->assertFalse($s->isSame($i));
$this->assertFalse($i->isSame($s, 'hour'));
$this->assertFalse($s->isSame($i, 'hour'));
$this->assertFalse($i->isSame($s, 'day'));
$this->assertFalse($s->isSame($i, 'day'));
$this->assertTrue($i->isSame($s, 'month'));
$this->assertTrue($s->isSame($i, 'month'));
$this->assertTrue($i->isSame($s, 'year'));
$this->assertTrue($s->isSame($i, 'year'));
}
public function testIsSameYear()
{
$s = new Moment('2014-01-01T00:14:00+0230');
$i = new Moment('2013-11-30T23:45:00+0000');
$this->assertFalse($i->isSame($s));
$this->assertFalse($s->isSame($i));
$this->assertFalse($i->isSame($s, 'hour'));
$this->assertFalse($s->isSame($i, 'hour'));
$this->assertFalse($i->isSame($s, 'day'));
$this->assertFalse($s->isSame($i, 'day'));
$this->assertFalse($i->isSame($s, 'month'));
$this->assertFalse($s->isSame($i, 'month'));
$this->assertTrue($i->isSame($s, 'year'));
$this->assertTrue($s->isSame($i, 'year'));
}
public function testIsBetween()
{
$l = new Moment('2014-01-01T10:00:00Z');
$r = new Moment('2014-01-01T12:00:00Z');
$n = $l->cloning();
$this->assertTrue($n->isBetween($l, $r, true));
$this->assertFalse($n->isBetween($l, $r, false));
$n = $r->cloning();
$this->assertTrue($n->isBetween($l, $r, true));
$this->assertFalse($n->isBetween($l, $r, false));
//Minutes
$l = new Moment('2014-01-01T10:30:30Z');
$r = new Moment('2014-01-01T12:30:30Z');
$n = new Moment('2014-01-01T10:30:00Z');
$this->assertFalse($n->isBetween($l, $r, true));
$n = new Moment('2014-01-01T12:30:45Z');
$this->assertFalse($n->isBetween($l, $r, true));
$n = new Moment('2014-01-01T10:30:00Z');
$this->assertTrue($n->isBetween($l, $r, true, 'minute'));
$n = new Moment('2014-01-01T12:30:45Z');
$this->assertTrue($n->isBetween($l, $r, true, 'minute'));
//Hour
$n = new Moment('2014-01-01T10:29:00Z');
$this->assertFalse($n->isBetween($l, $r, true, 'minute'));
$n = new Moment('2014-01-01T12:31:45Z');
$this->assertFalse($n->isBetween($l, $r, true, 'minute'));
$n = new Moment('2014-01-01T10:29:00Z');
$this->assertTrue($n->isBetween($l, $r, true, 'hour'));
$n = new Moment('2014-01-01T12:31:45Z');
$this->assertTrue($n->isBetween($l, $r, true, 'hour'));
//Day
$n = new Moment('2014-01-01T09:29:00Z');
$this->assertFalse($n->isBetween($l, $r, true, 'hour'));
$n = new Moment('2014-01-01T13:31:45Z');
$this->assertFalse($n->isBetween($l, $r, true, 'hour'));
$n = new Moment('2014-01-01T10:29:00Z');
$this->assertTrue($n->isBetween($l, $r, true, 'day'));
$n = new Moment('2014-01-01T12:31:45Z');
$this->assertTrue($n->isBetween($l, $r, true, 'day'));
//Month
$l = new Moment('2014-01-10T10:30:30Z');
$r = new Moment('2014-01-20T12:30:30Z');
$n = new Moment('2014-01-09T09:29:00Z');
$this->assertFalse($n->isBetween($l, $r, true, 'day'));
$n = new Moment('2014-01-21T13:31:45Z');
$this->assertFalse($n->isBetween($l, $r, true, 'day'));
$n = new Moment('2014-01-09T10:29:00Z');
$this->assertTrue($n->isBetween($l, $r, true, 'month'));
$n = new Moment('2014-01-21T12:31:45Z');
$this->assertTrue($n->isBetween($l, $r, true, 'month'));
//year
$l = new Moment('2014-04-10T10:30:30Z');
$r = new Moment('2015-08-20T12:30:30Z');
$n = new Moment('2014-03-09T09:29:00Z');
$this->assertFalse($n->isBetween($l, $r, true, 'month'));
$n = new Moment('2015-09-21T13:31:45Z');
$this->assertFalse($n->isBetween($l, $r, true, 'month'));
$n = new Moment('2014-03-09T10:29:00Z');
$this->assertTrue($n->isBetween($l, $r, true, 'year'));
$n = new Moment('2015-09-21T12:31:45Z');
$this->assertTrue($n->isBetween($l, $r, true, 'year'));
}
public function testLocaleDow()
{
//Test en_GB for Monday start of week
Moment::setLocale('en_GB');
//Expected Values
$gb_start = new Moment('2015-04-27T00:00:00Z');
$gb_end = new Moment('2015-05-03T23:59:59Z');
//Current date: Middle of the week
$gb = new Moment('2015-04-28T10:29:00Z');
$this->assertTrue($gb->cloning()->startOf('week')->isSame($gb_start));
$this->assertTrue($gb->cloning()->endOf('week')->isSame($gb_end));
//Current Date: Beginning of the week
$gb = new Moment('2015-04-27T10:29:00Z');
$this->assertTrue($gb->cloning()->startOf('week')->isSame($gb_start));
$this->assertTrue($gb->cloning()->endOf('week')->isSame($gb_end));
//Current Date: End of week
$gb = new Moment('2015-05-03T10:29:00Z');
$this->assertTrue($gb->cloning()->startOf('week')->isSame($gb_start));
$this->assertTrue($gb->cloning()->endOf('week')->isSame($gb_end));
//Test en_US for Sunday start of week
Moment::setLocale('en_US');
//Expected Values
$us_start = new Moment('2015-04-26T00:00:00Z');
$us_end = new Moment('2015-05-02T23:59:59Z');
//Current date: Middle of the week
$us = new Moment('2015-04-28T10:29:00Z');
$this->assertTrue($us->cloning()->startOf('week')->isSame($us_start));
$this->assertTrue($us->cloning()->endOf('week')->isSame($us_end));
//Current Date: Beginning of the week
$us = new Moment('2015-04-26T10:29:00Z');
$this->assertTrue($us->cloning()->startOf('week')->isSame($us_start));
$this->assertTrue($us->cloning()->endOf('week')->isSame($us_end));
//Current Date: End of week
$us = new Moment('2015-05-02T10:29:00Z');
$this->assertTrue($us->cloning()->startOf('week')->isSame($us_start));
$this->assertTrue($us->cloning()->endOf('week')->isSame($us_end));
}
public function testImplicitCloning()
{
$origin = new Moment('1923-12-31 12:30:00', 'UTC', true);
$this->assertNotSame($origin, $origin->addMonths(1));
$origin->setImmutableMode(false);
$this->assertSame($origin, $origin->addMonths(1));
$origin->setImmutableMode(true);
$this->assertNotSame($origin, $origin->addMonths(1));
}
/**
* @link https://github.com/fightbulc/moment.php/issues/62
*/
// public function testLeapYear()
// {
// $now = new Moment('2016-01-31', 'Asia/Tokyo');
//
// $now
// ->subtractDays(1)
// ->addDays(1)
// ->startOf('day')
// ->cloning()
// ->startOf('month')
// ->addMonths(1)
// ->setDay('30')
// ->subtractMonths(1)
// ->endOf('month')
// ->format();
// }
}

View file

@ -0,0 +1,136 @@
<?php
/**
* Turkish (tr-TR) language support
* @author Engin Dumlu <engindumlu@gmail.com>
* @github https://github.com/roadrunner
*/
namespace Moment;
class MomentTurkishLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('tr_TR');
}
public function testWeekdayNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('Pts', 'Pazartesi'),
2 => array('Sal', 'Salı'),
3 => array('Çar', 'Çarşamba'),
4 => array('Per', 'Perşembe'),
5 => array('Cum', 'Cuma'),
6 => array('Cts', 'Cumartesi'),
7 => array('Paz', 'Pazar'),
);
for ($d = 1; $d < 7; $d++) {
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testMonthNames()
{
$startingDate = '2015-01-04T00:00:00+0000';
$moment = new Moment($startingDate);
$monthNames = array(
1 => array('Oca', 'Ocak'),
2 => array('Şub', 'Şubat'),
3 => array('Mar', 'Mart'),
4 => array('Nis', 'Nisan'),
5 => array('May', 'Mayıs'),
6 => array('Haz', 'Haziran'),
7 => array('Tem', 'Temmuz'),
8 => array('Ağu', 'Ağustos'),
9 => array('Eyl', 'Eylül'),
10 => array('Eki', 'Ekim'),
11 => array('Kas', 'Kasım'),
12 => array('Ara', 'Aralık'),
);
for ($d = 1; $d <= 12; $d++) {
$this->assertEquals($monthNames[$moment->format('n')][0], $moment->getMonthNameShort(), 'month short name failed');
$this->assertEquals($monthNames[$moment->format('n')][1], $moment->getMonthNameLong(), 'month long name failed');
$moment->addMonths(1);
}
}
public function testFormat()
{
$a = array(
array('l, F d Y, g:i:s a', 'Pazar, Şubat 14 2010, 3:25:50 pm'),
array('D, gA', 'Paz, 3PM'),
array('n m F M', '2 02 Şubat Şub'),
array('Y y', '2010 10'),
array('j d', '14 14'),
array('[the] z [day of the year]', 'the 44 day of the year')
);
$b = new Moment('2010-02-14 15:25:50');
for ($i = 0; $i < count($a); $i++) {
$this->assertEquals($a[$i][1], $b->format($a[$i][0]));
}
}
public function testRelative()
{
$beginningMoment = new Moment('2015-06-14 20:46:22', 'Europe/Istanbul');
$endMoment = new Moment('2015-06-14 20:48:32', 'Europe/Istanbul');
$this->assertEquals('2 dakika sonra', $endMoment->from($beginningMoment)->getRelative());
$this->assertEquals('2 dakika önce', $beginningMoment->from($endMoment)->getRelative());
}
public function testMinutes()
{
$past = new Moment('2016-01-03 16:17:07', 'Europe/Kiev');
$relative = $past->from('2016-01-03 16:34:07');
$this->assertEquals('17 dakika önce', $relative->getRelative());
$relative = $past->from('2016-01-03 16:40:07');
$this->assertEquals('23 dakika önce', $relative->getRelative());
$relative = $past->from('2016-01-03 16:30:07');
$this->assertEquals('13 dakika önce', $relative->getRelative());
}
public function testLastWeekWeekend()
{
$past = new Moment('2016-04-10 16:30:07');
$this->assertEquals('Geçen hafta Pazar 16:30', $past->calendar(true, new Moment('2016-04-12')));
$past = new Moment('2016-09-24 11:30:07');
$this->assertEquals('Geçen hafta Cumartesi 11:30', $past->calendar(true, new Moment('2016-09-26')));
$past = new Moment('2016-04-11');
$this->assertEquals('Geçen hafta Pazartesi', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-12');
$this->assertEquals('Geçen hafta Salı', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-13');
$this->assertEquals('Geçen hafta Çarşamba', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-14');
$this->assertEquals('Geçen hafta Perşembe', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-15');
$this->assertEquals('Geçen hafta Cuma', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('Dün', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('Geçen hafta Cumartesi', $past->calendar(false, new Moment('2016-04-18')));
}
}

View file

@ -0,0 +1,125 @@
<?php
namespace Moment;
class MomentUkrainianLocaleTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
Moment::setLocale('uk_UA');
}
public function testWeekdayNames()
{
$startingDate = '2016-01-29T00:00:00+0000';
$moment = new Moment($startingDate);
$weekdayNames = array(
1 => array('пн', 'понеділок'),
2 => array('вт', 'вівторок'),
3 => array('ср', 'середа'),
4 => array('чт', 'четвер'),
5 => array('пт', 'п’ятниця'),
6 => array('сб', 'субота'),
7 => array('нд', 'неділя'),
);
for ($d = 1; $d < 7; $d++) {
$this->assertEquals($weekdayNames[$moment->getWeekday()][0], $moment->getWeekdayNameShort(), 'weekday short name failed');
$this->assertEquals($weekdayNames[$moment->getWeekday()][1], $moment->getWeekdayNameLong(), 'weekday long name failed');
$moment->addDays(1);
}
}
public function testDayMonthFormat001()
{
$string = '2015-06-14 20:46:22';
$moment = new Moment($string, 'Europe/Kiev');
$this->assertEquals('14 червня', $moment->format('j F'));
$string = '2015-03-08T15:14:53-0500';
$moment = new Moment($string, 'Europe/Kiev');
$this->assertEquals('8 березня', $moment->format('j F'));
}
public function testDayMonthFormat002()
{
$moment = new Moment('2016-01-03 16:17:07', 'Europe/Kiev');
$this->assertEquals('3 грудня', $moment->subtractMonths(1)->format('j F'));
}
public function testMonthFormatFN()
{
$startingDate = '2016-01-01T00:00:00+0000';
$moment = new Moment($startingDate);
$monthsNominative = array(
1 => 'січень',
2 => 'лютий',
3 => 'березень',
4 => 'квітень',
5 => 'травень',
6 => 'червень',
7 => 'липень',
8 => 'серпень',
9 => 'вересень',
10 => 'жовтень',
11 => 'листопад',
12 => 'грудень'
);
for ($d = 1; $d < count($monthsNominative); $d++) {
$this->assertEquals($monthsNominative[$moment->format('n')], $moment->format('f'), 'month nominative failed');
$moment->addMonths(1);
}
}
public function testMinutes()
{
$past = new Moment('2016-01-03 16:17:07', 'Europe/Kiev');
$relative = $past->from('2016-01-03 16:34:07');
$this->assertEquals('17 хвилин тому', $relative->getRelative());
$relative = $past->from('2016-01-03 16:40:07');
$this->assertEquals('23 хвилини тому', $relative->getRelative());
$relative = $past->from('2016-01-03 16:30:07');
$this->assertEquals('13 хвилин тому', $relative->getRelative());
}
public function testLastWeekWeekend()
{
$past = new Moment('2016-04-10 16:30:07');
$this->assertEquals('неділя о 16:30', $past->calendar(true, new Moment('2016-04-12')));
$past = new Moment('2016-09-24 11:30:07');
$this->assertEquals('субота об 11:30', $past->calendar(true, new Moment('2016-09-26')));
$past = new Moment('2016-04-11');
$this->assertEquals('понеділок', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-12');
$this->assertEquals('вівторок', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-13');
$this->assertEquals('середа', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-14');
$this->assertEquals('четвер', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-15');
$this->assertEquals('п’ятниця', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('вчора', $past->calendar(false, new Moment('2016-04-17')));
$past = new Moment('2016-04-16');
$this->assertEquals('субота', $past->calendar(false, new Moment('2016-04-18')));
}
}

View file

@ -3,6 +3,10 @@
// set your time zone:
date_default_timezone_set('Europe/Paris');
// set locale (see supported locales: https://github.com/fightbulc/moment.php#switch-locale)
$config['locale'] = 'en_US';
// enable in production:
error_reporting(0);

View file

@ -15,57 +15,41 @@ $purifier_config->set('HTML.Nofollow', true);
$purifier_config->set('HTML.ForbiddenElements', array("img"));
$purifier = new HTMLPurifier($purifier_config);
\Moment\Moment::setLocale($config['locale']);
$mailIds = array_map(function ($mail) {
return $mail->id;
}, $emails);
$mailIdsJoinedString = filter_var(join('|', $mailIds), FILTER_SANITIZE_SPECIAL_CHARS);
function niceDate($date) {
$m = new \Moment\Moment($date, date_default_timezone_get());
return $m->calendar();
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css"
integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp"
crossorigin="anonymous">
<title><?php
echo $emails ? "(" . count($emails) . ") " : "";
echo $user->address ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" type="image/x-icon" href="favicon.gif">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta charset="utf-8">
<link rel="stylesheet" href="bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="spinner.css">
<link rel="stylesheet" href="style.css">
<script>
var mailCount = <?php echo count($emails)?>;
function copyToClipboard(text) {
var inp = document.createElement('input');
document.body.appendChild(inp);
inp.value = text;
inp.select();
document.execCommand('copy', false);
inp.remove();
}
function toggle_email_visibility(email_id) {
var mailPreviewHeader = document.getElementById("email-preview-header-" + email_id);
var mailFullHeader = document.getElementById("email-fullheader-" + email_id);
var mailBody = document.getElementById("email-content-" + email_id);
if (mailPreviewHeader.style.display !== 'none') {
mailPreviewHeader.style.display = 'none';
mailFullHeader.style.display = 'block';
mailBody.style.display = 'block';
} else {
mailPreviewHeader.style.display = 'block';
mailFullHeader.style.display = 'none';
mailBody.style.display = 'none';
}
}
setInterval(function () {
var r = new XMLHttpRequest();
r.open("GET", "./json-api.php?action=has_new_messages&address=$<?php echo $user->address?>&email_ids=<?php echo $mailIdsJoinedString?>", true);
@ -86,229 +70,290 @@ $mailIdsJoinedString = filter_var(join('|', $mailIds), FILTER_SANITIZE_SPECIAL_C
}, 15000);
</script>
</head>
<body>
<div id="new-content-avalable" class="alert alert-info alert-fixed" role="alert">
<strong>New mails</strong> have arrived - <a href="javascript:location.reload();" class="alert-link">reload!</a>
<div id="new-content-avalable">
<div class="alert alert-info alert-fixed" role="alert">
<strong>New emails</strong> have arrived.
<button type="button" class="btn btn-outline-secondary" onclick="location.reload()">
<i class="fas fa-sync"></i>
Reload!
</button>
</div>
<!-- move the rest of the page a bit down to show all content -->
<div style="height: 3rem">&nbsp;</div>
</div>
<header>
<div class="container">
<small class="form-text text-muted">
You have <span class="badge badge-pill badge-info"><?php echo count($emails); ?> </span> messages in your
mailbox:
</small>
<p class="lead ">
Your disposable mailbox is ready.
</p>
<div class="row" id="address-box-normal">
<form id="header-form" action="?action=redirect" method="post">
<div class="form-group row">
<div class="col my-address-block">
<span id="my-address">
<?php echo $user->address ?>
</span>&nbsp;<button class="copy-button" data-clipboard-target="#my-address">
Copy
</button>
</div>
<div class="col get-new-address-col">
<button type="button" class="btn btn-outline-dark"
data-toggle="collapse" title="choose your own address"
data-target=".change-address-toggle"
aria-controls="address-box-normal address-box-edit" aria-expanded="false">
<i class="fas fa-magic"></i> Change address
</button>
</div>
</div>
<form class="collapse change-address-toggle" id="address-box-edit" action="?action=redirect" method="post">
<div class="card">
<div class="card-body">
<p>
<a href="?action=random" role="button" class="btn btn-dark">
<i class="fa fa-random"></i>
Open random mailbox
</a>
</p>
or create your own address:
<div class="form-row align-items-center">
<div class="col-sm">
<label class="sr-only" for="inlineFormInputName">username</label>
<input name="username" type="text" class="form-control" id="inlineFormInputName"
placeholder="username"
value="<?php echo $user->username ?>">
</div>
<div class="col-sm-auto my-1">
<label class="sr-only" for="inlineFormInputGroupUsername">Domain</label>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">@</div>
</div>
<select class="custom-select" id="inlineFormInputGroupUsername" name="domain">
<?php
foreach ($config['domains'] as $aDomain) {
$selected = $aDomain === $user->domain ? ' selected ' : '';
print "<option value='$aDomain' $selected>@$aDomain</option>";
}
?>
</select>
</div>
</div>
<div class="col-auto my-1">
<button type="submit" class="btn btn-primary">Open mailbox</button>
</div>
</div>
<div class="col-lg-5 col-md-4 col-sm-6 col-xs-12">
<input id="username" class="form-control form-control-lg" name="username" title="username"
value="<?php echo $user->username ?>">
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
<?php
if (count($config['domains']) == 1) {
$domain = $config['domains'][0];
print "<h3>@$domain</h3>";
print "<input type='hidden' name='domain' value='$domain'/>";
} else {
?>
<select id="domain" class="form-control form-control-lg" name="domain" title="domain"
onchange="this.form.submit()">
<?php
foreach ($config['domains'] as $aDomain) {
$selected = $aDomain === $user->domain ? ' selected ' : '';
print "<option value='$aDomain' $selected>@$aDomain</option>";
}
?>
</select>
<?php
}
?>
</div>
<div class="col-lg-3 col-md-4 col-sm-12 col-xs-12 random-column">
<a role="button" href="?action=random"
class="btn btn-outline-primary col-sm-12 col-xs-12 random-button">Generate
Random</a>
</div>
</div>
</form>
</div>
</header>
<main>
<div class="container min-height">
<div class="container">
<?php
if (empty($emails)) {
?>
<div>
<div class="card waiting-screen">
<div class="card-block">
<p class="lead">Your mailbox <strong
><?php echo $user->address ?></strong> is ready. </p>
<p>
<button class="btn btn-outline-primary"
onClick="copyToClipboard('<?php echo $user->address ?>');">
Copy email address
</button>
</p>
<div id="email-list" class="list-group">
<p>Emails will appear here automatically. They will be deleted after 30 days.</p>
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
</div>
</div>
<?php
} else {
foreach ($emails
foreach ($emails as $email) {
as $email) {
$safe_email_id = filter_var($email->id, FILTER_VALIDATE_INT);
?>
<div class="email-table">
<a class="list-group-item list-group-item-action email-list-item" data-toggle="collapse"
href="#mail-box-<?php echo $email->id ?>"
role="button"
aria-expanded="false" aria-controls="mail-box-<?php echo $email->id ?>">
<div class="card email">
<div class="media">
<button class="btn btn-white open-collapse-button">
<i class="fas fa-caret-right expand-button-closed"></i>
<i class="fas fa-caret-down expand-button-opened"></i>
</button>
<!-- preview header -->
<div class="card-block header-shadow email-preview-header"
id="email-preview-header-<?php echo filter_var($email->id, FILTER_SANITIZE_SPECIAL_CHARS); ?>"
onclick="toggle_email_visibility('<?php echo filter_var($email->id, FILTER_SANITIZE_SPECIAL_CHARS); ?>')">
<div class="row">
<div class="col-sm-12">
<b class="card-title">
<?php echo filter_var($email->subject, FILTER_SANITIZE_SPECIAL_CHARS); ?>
</b>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<h6 class="card-subtitle mt-1 text-muted">
<?php
echo filter_var($email->fromName, FILTER_SANITIZE_SPECIAL_CHARS);
echo ' &lt;';
echo filter_var($email->fromAddress, FILTER_SANITIZE_SPECIAL_CHARS);
echo '&gt;';
?>
</h6>
</div>
<div class="col-sm-4">
<h6 class="card-subtitle mt-1 text-muted"
style="text-align: right">
<?php echo filter_var($email->date, FILTER_SANITIZE_SPECIAL_CHARS); ?>
</h6>
</div>
</div>
<div class="media-body">
<h6 class="list-group-item-heading"><?php echo filter_var($email->fromName, FILTER_SANITIZE_SPECIAL_CHARS) ?>
<span class="text-muted"><?php echo filter_var($email->fromAddress, FILTER_SANITIZE_SPECIAL_CHARS) ?></span>
<small class="float-right"><?php echo niceDate($email->date) ?></small>
</h6>
<p class="list-group-item-text text-truncate" style="width: 75%">
<?php echo filter_var($email->subject, FILTER_SANITIZE_SPECIAL_CHARS); ?>
</p>
</div>
</div>
</a>
<!-- full header -->
<div class="card-block header-shadow email-fullheader"
id="email-fullheader-<?php echo filter_var($email->id, FILTER_SANITIZE_SPECIAL_CHARS); ?>"
onclick="toggle_email_visibility('<?php echo filter_var($email->id, FILTER_SANITIZE_SPECIAL_CHARS); ?>')">
<div class="row">
<div class="col-sm-8">
<h3 class="card-title">
<?php echo filter_var($email->subject, FILTER_SANITIZE_SPECIAL_CHARS); ?>
</h3>
</div>
<div class="col-sm-4 text-right">
<a class="btn btn-sm btn-outline-primary " download="true"
role="button"
href="?action=download_email&download_email_id=<?php echo $safe_email_id; ?>&amp;address=<?php echo $user->address ?>">Download
</a>
<a class="btn btn-sm btn-outline-danger"
role="button"
href="?action=delete_email&email_id=<?php echo $safe_email_id; ?>&amp;address=<?php echo $user->address ?>">Delete
</a>
</div>
<div id="mail-box-<?php echo $email->id ?>" role="tabpanel" aria-labelledby="headingCollapse1"
class="card-collapse collapse"
aria-expanded="true">
<div class="card-body">
<div class="card-block email-body">
<div class="float-right primary">
<a class="btn btn-outline-primary btn-sm" download="true"
role="button"
href="<?php echo "?action=download_email&email_id=$safe_email_id&address=$user->address" ?>">
Download
</a>
<a class="btn btn-outline-danger btn-sm"
role="button"
href="<?php echo "?action=delete_email&email_id=$safe_email_id&address=$user->address" ?>">
Delete
</a>
</div>
<div class="row">
<div class="col-sm-8">
<h6 class="card-subtitle mt-1 text-muted">
<?php
echo filter_var($email->fromName, FILTER_SANITIZE_SPECIAL_CHARS);
echo ' &lt;';
echo filter_var($email->fromAddress, FILTER_SANITIZE_SPECIAL_CHARS);
echo '&gt;';
?>
</h6>
</div>
<div class="col-sm-4">
<h6 class="card-subtitle mt-1 text-muted"
style="text-align: right">
<?php echo filter_var($email->date, FILTER_SANITIZE_SPECIAL_CHARS); ?>
</h6>
</div>
</div>
</div>
<!-- email content -->
<div class="card-block email-content"
id="email-content-<?php echo filter_var($email->id, FILTER_SANITIZE_SPECIAL_CHARS); ?>">
<h6 class="card-subtitle text-muted">
To: <?php echo filter_var($email->toString, FILTER_SANITIZE_SPECIAL_CHARS); ?></h6>
<?php
foreach ($email->cc as $cc) {
print "<h6 class='card-subtitle text-muted'>CC: " . filter_var($cc, FILTER_SANITIZE_SPECIAL_CHARS) . "</h6>";
$safeHtml = $purifier->purify($email->textHtml);
$safeText = htmlspecialchars($email->textPlain);
$safeText = nl2br($safeText);
$safeText = \AutoLinkExtension::auto_link_text($safeText);
$hasHtml = strlen(trim($safeHtml)) > 0;
$hasText = strlen(trim($safeText)) > 0;
if ($config['prefer_plaintext']) {
if ($hasText) {
echo $safeText;
} else {
echo $safeHtml;
}
} else {
if ($hasHtml) {
echo $safeHtml;
} else {
echo $safeText;
}
}
?>
<div class="mt-2 card-text">
<?php
$safeHtml = $purifier->purify($email->textHtml);
$safeText = htmlspecialchars($email->textPlain);
$safeText = nl2br($safeText);
$safeText = \AutoLinkExtension::auto_link_text($safeText);
$hasHtml = strlen(trim($safeHtml)) > 0;
$hasText = strlen(trim($safeText)) > 0;
if ($config['prefer_plaintext']) {
if ($hasText) {
echo $safeText;
} else {
echo $safeHtml;
}
} else {
if ($hasHtml) {
echo $safeHtml;
} else {
echo $safeText;
}
}
?>
</div>
</div>
</div>
</div>
<?php } ?>
<?php
} // end foreach $email
} // end: has emails
?>
</div>
<?php
if (empty($emails)) { ?>
<div id="empty-mailbox">
<p>Emails will appear here automatically. </p>
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
<?php } ?>
</div>
</main>
<footer>
<p>Powered by <a href="https://github.com/synox/disposable-mailbox"><strong>synox/disposable-mailbox</strong></a>
| <a href="https://github.com/synox/disposable-mailbox">Contribute to the development on Github.</a></p>
<div class="container">
<!-- <select id="language-selection" class="custom-select" title="Language">-->
<!-- <option selected>English</option>-->
<!-- <option value="1">Deutsch</option>-->
<!-- <option value="2">Two</option>-->
<!-- <option value="3">Three</option>-->
<!-- </select>-->
<!-- <br>-->
<small class="text-justify quick-summary">
This is a disposable mailbox service. Whoever knows your username, can read your emails.
Emails will be deleted after 30 days.
<a data-toggle="collapse" href="#about"
aria-expanded="false"
aria-controls="about">
Show Details
</a>
</small>
<div class="card card-body collapse" id="about" style="max-width: 40rem">
<p class="text-justify">This disposable mailbox keeps your main mailbox clean from spam.</p>
<p class="text-justify">Just choose an address and use it on websites you don't trust and
don't
want to use
your
main email address.
Once you are done, you can just forget about the mailbox. All the spam stays here and does
not
fill up
your
main mailbox.
</p>
<p class="text-justify">
You select the address you want to use and received emails will be displayed
automatically.
There is not registration and no passwords. If you know the address, you can read the
emails.
<strong>Basically, all emails are public. So don't use it for sensitive data.</strong>
</p>
</div>
<p>
<small>Powered by
<a
href="https://github.com/synox/disposable-mailbox"><strong>synox/disposable-mailbox</strong></a>
</small>
</p>
</div>
</footer>
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"
integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
clipboard = new ClipboardJS('[data-clipboard-target]');
$(function () {
$('[data-tooltip="tooltip"]').tooltip()
});
/** from https://github.com/twbs/bootstrap/blob/c11132351e3e434f6d4ed72e5a418eb692c6a319/assets/js/src/application.js */
clipboard.on('success', function (e) {
$(e.trigger)
.attr('title', 'Copied!')
.tooltip('_fixTitle')
.tooltip('show')
.tooltip('_fixTitle');
e.clearSelection();
});
</script>
</body>
</html>

View file

@ -1,33 +1,102 @@
html > body {
/* override bootstrap background */
background: #f9f9f9;
html > body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
#my-address {
margin-top: 0.5rem;
margin-left: 1rem;
color: black;
}
.my-address-block {
background-color: #F8F9FA;
padding: 0.5rem;
white-space: nowrap;
padding-left: 0;
margin-left: 1rem;
text-align: center;
padding-right: 0;
}
.get-new-address-col {
text-align: center;
padding: 0.5rem;
}
.email-list-item {
padding-left: 0;
padding-bottom: 0;
}
.copy-button {
font-size: 75%;
color: #808080;
cursor: pointer;
background-color: transparent;
border: 0;
border-radius: 0.25rem;
}
.copy-button:hover {
color: #fff;
background-color: #007BFF;
}
header {
/*background-color: #f9f9f9;*/
padding-bottom: 1rem;
padding-top: 1rem;
}
main {
flex: 1;
padding-bottom: 30px;
flex: 1; /* stick footer to the bottom */
padding-top: 2rem;
padding-bottom: 2rem;
}
#language-selection {
width: 10rem;
}
footer {
font-size: 12px;
padding-top: 1rem;
background-color: #eeeeee;
}
.open-collapse-button {
background-color: transparent;
width: 3rem;
}
.open-collapse-button > i {
font-size: 1.5em;
}
[aria-expanded="false"] .expand-button-closed {
display: block;
}
[aria-expanded="false"] .expand-button-opened {
display: none;
}
[aria-expanded="true"] .expand-button-closed {
display: none;
}
[aria-expanded="true"] .expand-button-opened {
display: block;
}
#new-content-avalable {
display: none;
text-align: center;
padding-top: 1em;
}
.card-block {
padding: 1.25rem;
}
.email-table {
margin-top: 20px;
}
div.min-height {
min-height: 400px;
.email-body {
}
.alert-fixed {
@ -39,48 +108,6 @@ div.min-height {
border-radius: 0px;
text-align: center;
}
.email-fullheader {
display: none;
}
.email-preview-header {
cursor: pointer;
}
.email-content {
display: none;
}
#new-content-avalable {
display: none;
}
header {
background-color: #D9E2E9;
padding-top: 5px;
padding-bottom: 5px;
margin-bottom: 15px;
}
.email-table > .email {
border-top: 5px solid #7C96AB;
}
.header-shadow {
box-shadow: 0 2px 2px rgba(182, 182, 182, 0.75);
}
.waiting-screen {
padding: 40px 15px;
text-align: center;
}
.random-column {
border-left: 1px dashed #333;
}
.random-button {
height: 48px;
padding: 10px;
#address-box-edit {
margin: 1rem;
}