diff --git a/lib/Date.php b/lib/Date.php index 53b73bd..e89d6a2 100644 --- a/lib/Date.php +++ b/lib/Date.php @@ -8,8 +8,8 @@ namespace MensBeam\Lax; class Date extends \DateTimeImmutable implements \JsonSerializable { protected const PATTERN_RFC3339 = '/^(\d{4}-\d\d-\d\d)[Tt ](\d\d:\d\d(?::\d\d(?:\.\d+)?)?)\s*([Zz]|[+\-]\d\d:?\d\d)?$/'; - protected const PATTERN_RFC8XX = '/^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun|(?:Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day)(?:, ?| )(\d\d)(?
|-|)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(?P=dd)(\d\d(?:\d\d)?) (\d\d:\d\d(?::\d\d(?:\.\d+)?)?)\s*(?-i:([A-Z]|GMT|UTC?|[ECMP][SD]T|[+\-]\d\d:?\d\d)?)$/i'; - protected const PATTERN_ASCTIME = '/^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d\d?) (\d\d:\d\d(?::\d\d(?:\.\d+)?)?) (\d{4})$/'; + protected const PATTERN_RFC8XX = '/^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun|(?:Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day)(?:, ?| )(\d\d)(?
|-)(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(?P=dd)(\d\d(?:\d\d)?) (\d\d:\d\d(?::\d\d(?:\.\d+)?)?)\s*(?-i:([A-Z]|GMT|UTC?|[ECMP][SD]T|[+\-]\d\d:?\d\d)?)$/i'; + protected const PATTERN_ASCTIME = '/^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d\d?) (\d\d:\d\d:\d\d) (\d{4})$/'; protected const INPUT_FORMAT = '!Y-m-d\TH:i:s.uO'; protected const MICROTIME_PRECSISION = 6; protected const MONTH_MAP = ['Jan' => "01", 'Feb' => "02", 'Mar' => "03", 'Apr' => "04", 'May' => "05", 'Jun' => "06", 'Jul' => "07", 'Aug' => "08", 'Sep' => "09", 'Oct' => "10", 'Nov' => "11", 'Dec' => "12"]; @@ -85,10 +85,10 @@ class Date extends \DateTimeImmutable implements \JsonSerializable { * the ambiguous century of RFC 822 and RFC 850 formats is interpreted per * RFC 7231. Timezones used for RFC 822 are also accepted for RFC 850. * - * All formats additionally are accepted with subsecond precision, or with - * minute precision. Whitespace before the timezone may be omitted or used - * in all formats as well (RFC 3339 does not normally allow whitespace, - * while other formats require it). + * All formats except asctime() are also accepted with subsecond precision, + * or with minute precision. Whitespace before the timezone may be omitted + * or used in all formats as well (RFC 3339 does not normally allow + * whitespace, while other formats require it). * * If no timezone is specified, -00:00 is used. * @@ -149,9 +149,6 @@ class Date extends \DateTimeImmutable implements \JsonSerializable { } protected static function parseZone(string $zone): string { - if (!strlen($zone)) { - return "-0000"; - } $out = self::TZ_MAP[strtoupper($zone)] ?? null; if ($out) { return $out; diff --git a/tests/cases/Date/test-asctime.yaml b/tests/cases/Date/test-asctime.yaml new file mode 100644 index 0000000..c6c4ffe --- /dev/null +++ b/tests/cases/Date/test-asctime.yaml @@ -0,0 +1,24 @@ +asctime(): + input: + - 'Thu Mar 5 23:08:55 2020' + - 'Thu Mar 5 23:08:55 2020' # This is the only syntax variation allowed + output: '2020-03-05T23:08:55-00:00' + +asctime() with invalid data: + input: + - 'Thu Feb 31 23:08:55 2020' # impossible date (February 31) + - 'Thu Mar 5 25:08:55 2020' # impossible hour + - 'Thu Mar 5 23:65:55 2020' # impossible minute + - 'Thu Mar 5 23:08:74 2020' # impossible second + output: null + +asctime() with invalid syntax: + input: + - 'Thu, Mar 5 23:08:55 2020' + - 'Thursday Mar 5 23:08:55 2020' + - 'Thu Mar 5 23:08:55 2020 GMT' + - 'Thu Mar 5 2:08:55 2020' + - 'Thu Mar 5 23:8:55 2020' + - 'Thu Mar 5 23:08:5 2020' + - 'Thu Mar 5 23:08:55 20' + output: null diff --git a/tests/cases/Date/test-rfc822.yaml b/tests/cases/Date/test-rfc822.yaml index 82cd1f9..a561763 100644 --- a/tests/cases/Date/test-rfc822.yaml +++ b/tests/cases/Date/test-rfc822.yaml @@ -326,7 +326,6 @@ RFC 822 with accepted syntax variations: - 'Thu, 05 mar 2020 23:08:55Z' - 'Thu, 05 mAR 2020 23:08:55Z' - 'Thu, 05 MAR 2020 23:08:55Z' - - 'Thu, 05MAR2020 23:08:55Z' output: '2020-03-05T23:08:55+00:00' RFC 822 with invalid data: @@ -337,4 +336,17 @@ RFC 822 with invalid data: - 'Thu, 05 Mar 2020 24:08:55Z' # impossible hour - 'Thu, 05 Mar 2020 23:74:55Z' # impossible minute - 'Thu, 05 Mar 2020 23:08:88Z' # impossible second + - 'Thu, 05 Mar 2020 23:08:55 EET' # not an allowed time zone + output: null + +RFC 822 with invalid syntax: + input: + - '05 Mar 2020 23:08:55Z' + - 'Thu, 5 Mar 2020 23:08:55Z' + - 'Thu, 05Mar2020 23:08:55Z' + - 'Thu, 05 Mar 202 23:08:55Z' + - 'Thu, 05 Mar 2020 3:08:55Z' + - 'Thu, 05 Mar 2020 23:8:55Z' + - 'Thu, 05 Mar 2020 23:08:5Z' + - 'Thu, 05 Mar 2020 23:08:55z' # timezone must be uppercase output: null diff --git a/tests/cases/Date/test-rfc850.yaml b/tests/cases/Date/test-rfc850.yaml index 59329e0..84d64d2 100644 --- a/tests/cases/Date/test-rfc850.yaml +++ b/tests/cases/Date/test-rfc850.yaml @@ -326,5 +326,27 @@ RFC 850 with accepted syntax variations: - 'Thursday, 05-mar-2020 23:08:55Z' - 'Thursday, 05-mAR-2020 23:08:55Z' - 'Thursday, 05-MAR-2020 23:08:55Z' - - 'Thursday, 05MAR2020 23:08:55Z' output: '2020-03-05T23:08:55+00:00' + +RFC 850 with invalid data: + input: + - 'Wandsday, 05-Mar-2020 23:08:55Z' # bad weekday + - 'Thursday, 31-Feb-2020 23:08:55Z' # impossible day of month + - 'Thursday, 05-Fro-2020 23:08:55Z' # bad month + - 'Thursday, 05-Mar-2020 24:08:55Z' # impossible hour + - 'Thursday, 05-Mar-2020 23:74:55Z' # impossible minute + - 'Thursday, 05-Mar-2020 23:08:88Z' # impossible second + - 'Thursday, 05-Mar-2020 23:08:55 EET' # not an allowed time zone + output: null + +RFC 850 with invalid syntax: + input: + - '05-Mar-2020 23:08:55Z' + - 'Thursday, 5-Mar-2020 23:08:55Z' + - 'Thursday, 05Mar2020 23:08:55Z' + - 'Thursday, 05-Mar-202 23:08:55Z' + - 'Thursday, 05-Mar-2020 3:08:55Z' + - 'Thursday, 05-Mar-2020 23:8:55Z' + - 'Thursday, 05-Mar-2020 23:08:5Z' + - 'Thursday, 05-Mar-2020 23:08:55z' # timezone must be uppercase + output: null