Почему PHP анализирует некоторые числа с плавающей точкой как странные даты? - PullRequest
3 голосов
/ 21 сентября 2019

Сегодня 21 сентября.Почему следующие числа с плавающей точкой анализируются как странные даты?Я понимаю, что сначала они преобразуются в строки, затем анализируются, но формат, похоже, не имеет никакого смысла.Следуют ли они некоторому формату, о котором я не знаю, или это неопределенное поведение?

Я не вижу применимого формата ни в одном из:

var_dump(new DateTime(5.123456));
class DateTime#1 (3) {
  public $date =>
  string(26) "3456-09-21 05:12:00.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(3) "UTC"
}

5.123456

  • час: 5
  • минута: 12
  • секунда: 0,0
  • год: 3456
  • месяц: сейчас (9)
  • день: сейчас (21)
var_dump(new DateTime(5.1203047891));
class DateTime#1 (3) {
  public $date =>
  string(26) "7891-09-21 05:12:00.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(3) "UTC"
}

5.1203047891

  • час: 5
  • минута: 12
  • секунда: 0,0
  • игнорируется: 0304
  • год: 7891
  • месяц: сейчас (9)
  • день: сейчас (21)

Некоторые другие строки:

  • '5': Failed to parse time string
  • '5.': Failed to parse time string
  • '5.1': 2019-09-21 05:01:00.000000 5:01, 2019-09-21 (сегодня)
  • '5.12': 2019-09-21 05:12:00.000000 5:12, 2019-09-21 (сегодня)
  • '5.123 ': Failed to parse time string
  • '5.1234': Failed to parse time string
  • '5.12345': Failed to parse time string
  • '5.123456': 3456-09-21 05:12:00.000000 5:12, 3456-09-21
  • '5.1234567': Failed to parse time string
  • '5.12345678': Failed to parse time string
  • '5.123456789': Failed to parse time string
  • '5.1234567891':7891-09-21 05:12:00.000000 5:12, 7891-09-21
  • '5.12345678912': Failed to parse time string
  • '5.123456789123': Failed to parse time string
  • '5.1234567891234': 7891-08-22 05:12:00.000000 5:12, 7891-08-22
  • '5.12345678912345': Failed to parse time string
  • '5.123456789123456': Failed to parse time string
  • '5.1234567891234567': Failed to parse time string
  • '5.12345678912345678': 5678-08-22 05:12:00.000000 5:12, 5678-08-22
  • '5.123456789123456789': Failed to parse time string
  • '5.12345678901234567': 4567-05-03 05:12:00.0000005:12, 4567-05-03
  • '5.1234567890 001 4567': Failed to parse time string
  • '5.1234567890 002 4567': Failed to parse time string
  • '5.1234567890 003 4567': 4567-01-03 05:12:00.000000 5:12, 4567-01-03 (3-й день года)
  • '5.1234567890 365 4567 ': 4567-12-31 05:12:00.000000 5:12, 4567-12-31 (365-й день года)
  • '5.1234567890 366 4567': 4568-01-01 05:12:00.000000 5:12, 4568-01-01 (366-й (!) День без високосного года)
  • '5.1234567890 367 4567 ': Failed to parse time string

Я был в состоянии предсказать некоторые части, но он не соответствует разумному общему формату.Что здесь происходит?

1 Ответ

0 голосов
/ 23 сентября 2019

Только создатель кода класса DateTime может полностью ответить на вопрос.Я просто пытаюсь объяснить мотивацию.DateTime хочет интерпретировать многие из возможных бесплатных форматов.Сначала входные данные преобразуются в строку.

class test{
  public function __toString(){
    return "2001-02-03 04:05:06";
  }
}

$d = new DateTime(new test);
//object(DateTime)#2 (3) { ["date"]=> string(19) "2001-02-03 04:05:06" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } 

Используемый здесь метод __toString подтверждает это.Если строка пуста, то генерируется дата из текущего дня и текущего времени.Это также основа для недостающей информации из входных данных.Затем пытается распознать время ( Форматы времени ).

Этот тест показывает, что первая попытка состоит в определении времени.Посмотрите на следующие тесты или подтверждение.Это описано в руководстве Форматы даты :

Год (и только год) YY "1978", "2008"

'1978«не может быть времени, поэтому он анализируется как год.

var_dump(new DateTime('1978'));  //"1978-09-23 09:46:43.000000"

Но« 2008 »может представлять время.Он анализируется как время 20: 08.

var_dump(new DateTime('2008'));  //  "2019-09-23 20:08:00.000000"

Часы, минуты и секунды могут быть изменены с помощью: ,,.или ничего не должно быть отделено.Если обнаружен только один раз, то текущий день принимается за дату.Примеры (сегодня 23 сентября 2019 г.):

'04:08','0408','04.08'      => "2019-09-23 04:08:00.000000"
'04.08.05','04.08:05','040805'  => "2019-09-23 04:08:05.000000"

Затем выполняется попытка анализа даты.Порядок Дата / Время или Время Дата на входе не имеет значения.Все строки анализируются на "2001-02-03 04: 05: 00.000000":

'04:05 2001-02-03'
'04.05 20010203'
'04.0520010203'
'4.0520010203'

'2001020304.05'
'20010203 04.05'

Ваша строка: '5.123456'

Сначала анализатор анализирует 5.12 как время 05:12.Остальное «3456» в году.

Строка «5.12345678901232004» будет проанализирована как «5.12 34567890123 2004» 5.12, как время 05:12 и 2004 как год.

var_dump(new DateTime('5.12 34567890123 2004'));
//object(DateTime)#2 (3) { ["date"]=> string(26) "2004-05-02 05:12:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" }

У меня естьне знаю, как определить оставшуюся строку '34567890123' день 02 и месяц 05.

На вопрос не ответили полностью.Я надеюсь, что внес вклад в понимание синтаксического анализатора DateTime.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...