Chuyển đổi chuỗi thành Date và DateTime


292

Nếu tôi có một chuỗi PHP ở định dạng mm-dd-YYYY(ví dụ: 10-16-2003), làm thế nào để tôi chuyển đổi chính xác chuỗi đó thành a Datevà sau đó là DateTimeđịnh dạng YYYY-mm-dd? Lý do duy nhất tôi yêu cầu cho cả hai DateDateTimelà vì tôi cần một điểm, và điểm kia ở một điểm khác.

Câu trả lời:


480

Sử dụng strtotime()vào ngày đầu tiên của bạn sau đó date('Y-m-d')để chuyển đổi lại:

$time = strtotime('10/16/2003');

$newformat = date('Y-m-d',$time);

echo $newformat;
// 2003-10-16

Lưu ý rằng có một sự khác biệt giữa việc sử dụng dấu gạch chéo /và dấu gạch nối -trong strtotime()hàm. Để trích dẫn từ php.net:

Ngày ở các định dạng m / d / y hoặc dmy được định nghĩa bằng cách nhìn vào dấu phân cách giữa các thành phần khác nhau: nếu dấu phân cách là dấu gạch chéo (/), thì giả sử m / d / y của Mỹ; trong khi nếu dấu phân cách là dấu gạch ngang (-) hoặc dấu chấm (.), thì định dạng dmy châu Âu được giả sử.

Để tránh sự mơ hồ tiềm ẩn, tốt nhất nên sử dụng ngày ISO 8601 (YYYY-MM-DD) hoặc DateTime :: createdFromFormat () khi có thể.


11
Điều này sẽ không làm việc. PHP sẽ diễn giải đầu vào đó là DD-MM-YYYY.
Matthew

tôi đã thêm một chút giải thích cho mã của mình, cảm ơn @konforce
Ibu

9
Đọc câu trả lời tiếp theo để có giải pháp tốt hơn
Manuel Bitto

@delive chuỗi ngày của bạn rất có thể không phải là một ngày chính xác.
Ibu

8
Nó không hoạt động vì câu trả lời này là sai lệch. strtotimechấp nhận các định dạng nhất định. Bạn không thể cho nó ăn bất cứ thứ gì. Đó là lý do tại sao DateTime::createFromFormatnên được sử dụng thay vì strtotime. Đáng buồn thay, câu trả lời này có quá nhiều upvote cho bất cứ ai chú ý. Đó là tất cả các bản sao dán những ngày này.
NB

432

Bạn cần cẩn thận với các định dạng m / d / Y và mdY. PHP coi /là m / d / Y và -có nghĩa là dmY. Tôi sẽ mô tả rõ ràng định dạng đầu vào trong trường hợp này:

$ymd = DateTime::createFromFormat('m-d-Y', '10-16-2003')->format('Y-m-d');

Bằng cách đó, bạn không phải là ý tưởng bất chợt.


37
Tò mò về lý do tại sao đây không phải là câu trả lời được chấp nhận ... Điều này linh hoạt hơn nhiều so với việc dựa vào các yêu cầu của strtotime()chức năng.
jzimmerman2011

9
Điều quan trọng là phải chỉ ra rằng lớp php DateTime có sẵn kể từ phiên bản PHP 5.2 và createdFromFormat kể từ 5.3
Diego Nemo

14
Như với mọi chức năng, bạn nên kiểm tra xem nó có đáp ứng phiên bản tối thiểu mà bạn phải hỗ trợ hay không. Nhưng PHP 5.2 EOL là tháng 1 năm 2011. Không ai nên chạy nó nữa; Phục vụ cho những người đó chỉ là cho phép họ chạy phần mềm lỗi thời, không an toàn.
Matthew

@Matthew vâng, đúng rồi. Nhưng bạn chưa bao giờ, ngay cả hôm nay tôi đã tìm thấy phiên bản PHP4.1 vẫn được cài đặt ...
Roland

29

Để phân tích ngày, bạn nên sử dụng: DateTime :: createdFromFormat ();

Ví dụ:

$dateDE = "16/10/2013";
$dateUS = \DateTime::createFromFormat("d.m.Y", $dateDE)->format("m/d/Y");

Tuy nhiên, cẩn thận, bởi vì điều này sẽ sụp đổ với:

PHP Fatal error: Call to a member function format() on a non-object 

Bạn thực sự cần phải kiểm tra xem định dạng đã ổn chưa, trước tiên:

$dateDE = "16/10/2013";
$dateObj = \DateTime::createFromFormat("d.m.Y", $dateDE);
if (!$dateObj)
{
    throw new \UnexpectedValueException("Could not parse the date: $date");
}
$dateUS = $dateObj->format("m/d/Y");

Bây giờ thay vì sụp đổ, bạn sẽ có một ngoại lệ, mà bạn có thể bắt, tuyên truyền, v.v.

$ dateDE có định dạng sai, nó phải là "16.10.2013";


Lưu ý rằng việc kiểm tra $ dateObj theo cách đó sẽ chỉ đảm bảo rằng định dạng phù hợp với mặt nạ, không phải là ngày thực sự hợp lệ. Ví dụ: một ngày như 99/99/2010 sẽ vượt qua kiểm tra này vì nó phù hợp với m / d / Y nhưng đó không phải là ngày mà bạn thường muốn cho phép. Câu trả lời này giải quyết tình huống này -> stackoverflow.com/a/10120725/995014
Kilian Perdomo Curbelo

22
$d = new DateTime('10-16-2003');

$timestamp = $d->getTimestamp(); // Unix timestamp
$formatted_date = $d->format('Y-m-d'); // 2003-10-16

Chỉnh sửa: bạn cũng có thể chuyển một hàm tạo DateTimeZone cho DateTime () để đảm bảo tạo ngày cho múi giờ mong muốn, chứ không phải mặc định của máy chủ.


6
Tôi tin rằng điều này sẽ ném một ngoại lệ vì tháng 16 không hợp lệ.
Matthew

Điều quan trọng là phải chỉ ra rằng lớp php DateTime có sẵn kể từ phiên bản PHP 5.2 và getTimestamp kể từ 5.3
Diego Nemo

2

Cho ngày đầu tiên

$_firstDate = date("m-d-Y", strtotime($_yourDateString));

Cho ngày mới

$_newDate = date("Y-m-d",strtotime($_yourDateString));

2

Nếu bạn có định dạng dd-mm-yyyy thì trong PHP nó sẽ không hoạt động như mong đợi. Trong tài liệu PHP họ có hướng dẫn dưới đây.

Ngày ở các định dạng m / d / y hoặc dmy được định nghĩa bằng cách nhìn vào dấu phân cách giữa các thành phần khác nhau: nếu dấu phân cách là dấu gạch chéo (/), thì giả sử m / d / y của Mỹ; trong khi nếu dấu phân cách là dấu gạch ngang (-) hoặc dấu chấm (.), thì định dạng dmy châu Âu được giả sử.

Vì vậy, bạn không thể sử dụng như bạn muốn. Khi bạn cố gắng sử dụng định dạng dd / mm / yyyy với định dạng này thì nó sẽ xóa FALSE. Bạn có thể điều chỉnh với những điều sau đây.

$date = "23/02/2013";
$timestamp = strtotime($date);
if ($timestamp === FALSE) {
  $timestamp = strtotime(str_replace('/', '-', $date));
}
echo $timestamp; // prints 1361577600

1

Giống như chúng tôi có ngày "07 tháng 5 năm 2018" và chúng tôi cần ngày "2018-05-07" khi tương thích với mysql

if (!empty($date)) {
    $timestamp = strtotime($date);
    if ($timestamp === FALSE) {
         $timestamp = strtotime(str_replace('/', '-', $date));
     }
         $date = date('Y-m-d', $timestamp);
  }

Nó làm việc cho tôi. thưởng thức :)


0

Vì không ai đề cập đến điều này, đây là một cách khác:

$date = date_create_from_format("m-d-Y", "10-16-2003")->format("Y-m-d");


0

Nếu bạn muốn chấp nhận ngày bằng cách sử dụng đơn đặt hàng của Mỹ (tháng, ngày, năm) cho các định dạng kiểu châu Âu (sử dụng dấu gạch ngang hoặc thời gian là ngày, tháng, năm) trong khi vẫn chấp nhận các định dạng khác , bạn có thể mở rộng lớp DateTime:

/**
 * Quietly convert European format to American format
 *
 * Accepts m-d-Y, m-d-y, m.d.Y, m.d.y, Y-m-d, Y.m.d
 * as well as all other built-in formats
 * 
 */
class CustomDateTime extends DateTime 
{
  public function __construct(string $time="now", DateTimeZone $timezone = null) 
  {
    // convert m-d-y or m.d.y to m/d/y to avoid PHP parsing as d-m-Y (substr avoids microtime error)
    $time = str_replace(['-','.'], '/', substr($time, 0, 10)) . substr($time, 10 );

    parent::__construct($time, $timezone);
  }
}

// usage:
$date = new CustomDateTime('7-24-2019');
print $date->format('Y-m-d');

// => '2019-07-24'

Hoặc, bạn có thể tạo một hàm để chấp nhận mdY và xuất Ymd:

/**
 * Accept dates in various m, d, y formats and return as Y-m-d
 * 
 * Changes PHP's default behaviour for dates with dashes or dots.
 * Accepts:
 *   m-d-y, m-d-Y, Y-m-d,
 *   m.d.y, m.d.Y, Y.m.d,
 *   m/d/y, m/d/Y, Y/m/d,
 *   ... and all other formats natively supported 
 * 
 * Unsupported formats or invalid dates will generate an Exception
 * 
 * @see https://www.php.net/manual/en/datetime.formats.date.php PHP formats supported
 * @param  string $d various representations of date
 * @return string    Y-m-d or '----' for null or blank
 */
function asYmd($d) {
  if(is_null($d) || $d=='') { return '----'; }

  // convert m-d-y or m.d.y to m/d/y to avoid PHP parsing as d-m-Y
  $d = str_replace(['-','.'], '/', $d);

  return (new DateTime($d))->format('Y-m-d');
}

// usage:

<?= asYmd('7-24-2019') ?>

// or

<?php echo asYmd('7-24-2019'); ?>

0

để tạo ngày từ bất kỳ chuỗi nào, sử dụng:
$ date = DateTime :: createdFromFormat ('dmy H: i', '01 -01-01 01:00 '); echo $ date-> định dạng ('Ymd H: i');

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.