Home » Bài 17: Xử lý date time ngày tháng trong PHP

Bài 17: Xử lý date time ngày tháng trong PHP

Handling date time in PHP

by Tan Nguyen
20 minutes read

Ở bài viết trước đã học qua về cách xử lý đối với file trong PHP, tiếp tục series học PHP căn bản, bài này chúng ta sẽ tìm hiểu về phương pháp xử lý ngày tháng (date) trong PHP nhé!

Vấn đề xử lý ngày tháng cực kì quan trọng khi bạn xử lý với các bài toán liên quan đến thời gian như lịch bài viết và đăng lên website, những yêu cầu về trạng thái, dòng thời gian, lịch sử,… Ví dụ bạn cần in ra ngày tháng đăng bài viết hiển thị theo kiểu ngày / tháng / năm hoặc ngày – tháng – năm thì bắt buộc bạn phải biết cách sử dụng các hàm xử lý ngày tháng trong PHP thì mới làm được.

date time xu ly thoi gian ngay thang php

Xử lý date time ngày tháng trong PHP

Không những thế nó còn có liên quan đặc biệt đến cấu trúc cơ sở dữ liệu database nữa nên tầm quan trọng của việc xử lý thời gian này là không hề nhỏ.

Thiết lập múi thời gian (timezone) tại Việt Nam

Để cấu hình và làm việc với thời gian datetime đúng theo giờ Việt Nam thì bắt buộc ban phải thiết lập time zone( múi giờ) cho nó.

Cú pháp để thiết lập time zone là: date_default_timezone_set(‘timezone_identifier’);

Trong đó timezone_identifier là time zone mà bạn muốn thiết lập.

Mình đang ở Châu Á và ở Việt Nam – Hồ Chí Minh nên sẽ có timezone là Asia/Ho_Chi_Minh, mỗi khu vực sẽ chênh lệch nhau thời gian nên các bạn phải chú ý khi website có liên quan đến nước ngoài.

date_default_timezone_set('Asia/Ho_Chi_Minh');

Về múi giờ các bạn có thể tham khảo thêm tại: http://php.net/manual/en/timezones.php

Hoặc các bạn có thể sử dụng đoạn code dưới đây để xuất ra màn hình danh sách tất cả các timezone:

<?php
$timezone = DateTimeZone::listIdentifiers() ;
foreach ($timezone as $value){
    echo $value. '<br/>';
}
?>

Hoặc ta cũng có thể sử dụng hàm timezone_abbreviations_list để xuất ra timezone theo code bên dưới.

<?php
foreach (timezone_abbreviations_list() as $timezone) {
    foreach ($timezone as $value) {
        if (isset($value['timezone_id'])) {
            echo $value['timezone_id'] . '<br>';
        }
    }
}
?>
Lưu ý: Hàm thiết lập timezine này các bạn nên đặt ở đầu trang để cách đoạn code bên dưới hoạt động được hiệu quả và trính vị lỗi nhé!

Định dạng ngày tháng với hàm date()

Hàm date dùng để chuyển đổi thời gian theo format mà lập trình viên chỉ định mong muốn.

Cú pháp: date(format, timestamp);

Trong đó:

  • format: định  dạng ngày tháng năm, giờ phút giây.
  • timestamp(không bắt buộc) mặc định là hàm time() (chính là thời gian hiện tại).

Danh sách các format định dạng của date()

  1. h: Trả về giờ trong ngày kiểu 12h.
  2. H: Trả về giờ trong ngày kiểu 24h.
  3. i: Trả về phút trong giờ.
  4. s: Trả về số giây trong phút.
  5. S: Trả về hậu tố tiếng Anh cho ngày trong tháng, 2 ký tự. (st, nd, rd, th)
  6. d: trả về ngày trong tháng(bằng số từ 1- đến31).
  7. t: Số ngày trong 1 tháng (28 -> 31)
  8. j: Trả về ngày trong tháng, nhưng nếu ngày<10 sẽ không hiển thị số 0.
  9. D: Trả về định dạng thứ trong tuần bằng tiếng anh viết tắt. (có 3 chữ cái)
  10. l: Trả về đầy đủ thứ trong tuần (tiếng anh).
  11. m: Trả về tháng trong năm (bằng số từ 1 đến 12).
  12. M: Trả về tháng trong năm nhưng bằng tiếng anh viết tắt.
  13. y: Trả về 2 số cuối cùng của năm.
  14. Y: trả về đầy đủ 4 số của năm.
  15. c: trả về thời gian kiểu ISO 8601, thường dùng tạo cho thẻ meta publish time trong SEO
  16. z: trả về số ngày trong năm (Ngày trong năm bắt đầu từ 0 -> 365)

Ngoài ra các bạn có thể xem chi tiết đầy đủ về các format khác tại đây

echo date("Y-m-d"),'<br>'; //kết quả trả ra có dạng như 2020-02-23
 
echo date("d-m-Y"),'<br>'; //kết quả trả ra có dạng như 23-02-2020
 
echo date("d-m-Y H:i:s"),'<br>'; //kết quả trả ra có dạng như 22-02-2020 12:25:31

Ngoài ra chúng ta có thể phân cách ngày tháng năm bằng các dấu chéo / hoặc dấu gạch nối - hoặc dấu hai chấm :

Truyền thêm chuỗi trong hàm date()

Để cho nội dung chuỗi mà các bạn muốn hiển thị được như ý muốn thì các bạn thêm dấu chéo ngược \ vào trước mỗi ký tự của chuỗi.

<?php
echo date('\B\â\y \g\i\ờ \l\à d-m-Y H:i:s');

Phương pháp xử lý ngày tháng nâng cao trong PHP

Kiểu định dạng ngày tháng chuẩn trong MySQL

Để lưu đúng định dạng ngày tháng trong MySQL thì bạn sử dụng format bên dưới.

date('Y-m-d H:i:s');

Đây là định dạng chuẩn để bạn có thể sử dụng để đăng bài cũng như upload hay comment một content nào đó mà có lưu lên database.

Chuyển đổi kiểu định dạng ngày tháng

Ngoài cách đổi kiểu định dạng trực tiếp trong hàm date() thì ta có có một cách thay đổi kiểu định dạng xuất ra ngày tháng khác đó là hàm date_format()

<?php
$date = date_create("2020-02-23"); //tạo ngày có thể dùng hàm date_create
echo date_format($date,"d/Y/m");  //đổi định dạng
//output: 23/2020/02

Cộng trừ ngày tháng với mktime()

Hàm mktime() sẽ tính toán đưa ra ngày chính xác bởi các tham số truyền vào.

mktime($hour, $minute, $second, $month, $day , $year);
Lưu ý: Hàm này sẽ trả về thời gian kiểu INT nên bạn phải sử dụng hàm date() để chuyển đổi ra định dạng mong muốn.
Ví dụ: ta sẽ cộng thêm 5 ngày và 6 giờ đối với ngày 23/02/2020
<?php
$date = mktime((0 + 6), 0, 0, 02, (23 + 5), 2020);
echo date('d/m/Y', $date); //output: 28/02/2020

Ví dụ 2: ta sẽ cộng thêm 26 giờ đối với ngày 23/02/2020

<?php
$date = mktime((0 + 26), 0, 0, 02, 23, 2020);
echo date('d/m/Y', $date); //output: 24/02/2020 - ngày đã tự động tăng thêm 1 ngày

Ví dụ 3: ta sẽ cộng thêm 15 ngày đối với ngày 23/02/2020

<?php
$date = mktime(0, 0, 0, 02, (23 + 15), 2020);
echo date('d/m/Y', $date); //output: 09/03/2020 - ngày và tháng đã tự động tăng phù hợp

Các bạn để ý từ 2 ví dụ trên, nếu bạn công số giờ có kết quả quá 24, hoặc cộng số ngày có kết quả vượt qua số ngày trong tháng đó thì giờ hoặc ngày hoặc tháng sẽ tự động tăng thêm 1. Tương tự đối với năm cũng vậy. Chính vì thế khi thực hiện công trừ đối với thời gian bạn hãy kiểm tra cẩn thận để không bị sai lệch nhé!

<?php
//xuất ra ngày kế tiếp(ngày mai)
$tomorrow  = mktime(0, 0, 0, date("m")  , date("d")+1, date("Y"));
echo date('d/m/Y', $tomorrow) . '<br>';

//Xuất ra ngày này tháng sau
$lastmonth = mktime(0, 0, 0, date("m")-1, date("d"),   date("Y"));
echo date('d/m/Y', $lastmonth) . '<br>';

//xuất ra ngày này năm sau
$nextyear  = mktime(0, 0, 0, date("m"),   date("d"),   date("Y")+1);
echo date('d/m/Y', $nextyear) . '<br>';

Thay đổi ngày tháng date_modify()

Hàm date_modify() giúp ta thay đổi ngày tháng hiện hành. Đây cũng là một phương pháp dùng để tính toán cộng trừ cho ngày tháng các bạn nhé!

<?php
$date=date_create("2020-02-23");
date_modify($date, "+11 days"); // thay đổi ngày bằng phép cộng
echo date_format($date,"d/Y/m");  //đổi định dạng
Như vậy ta có thể sử dụng hàm date_modify() và hàm mktime() để tính ngày tháng đều được cả. Nhưng đối với mình, trường hợp phải cần làm việc với các hàm php thì lại thường hay dùng hàm mktime để tính hơn.

Lấy thông tin ngày giờ theo dạng mảng với getdate()

Hàm getdate() sẽ giúp ta chuyển đổi dữ liệu ngày tháng về dạng mảng trong PHP và ta có thể xuất ra màn hình theo phương pháp sau

<?php
var_dump(getdate());
/*kêt quả:
array (size=11)
  'seconds' => int 16
  'minutes' => int 3
  'hours' => int 4
  'mday' => int 23
  'wday' => int 0
  'mon' => int 2
  'year' => int 2020
  'yday' => int 53
  'weekday' => string 'Sunday' (length=6)
  'month' => string 'February' (length=8)
  0 => int 1582430596
*/
Khóa Giá trị ví dụ
“seconds” số giây 0 đến 59
“minutes” số phút 0 đến 59
“hours” số giờ 0 đến 23
“mday” Ngày trong tháng 1 đến 31
“wday” Ngày trong tuần 0 (Sunday) đến 6 (Saturday)
“mon” Tháng 1 đến 12
“year” Năm 1999
“yday” Ngày của năm 0 đến 365
“weekday” Ngày trong tuần(dạng chữ) Sunday đến Saturday
“month” Tháng(dạng chữ) January đến December
0 time() timestamp,-2147483648 đến 2147483647.

Một số hàm lấy thông tin date/time khác

Lấy ngày cuối cùng của một tháng

//last day of month
function lastday($month = '', $year = '') {
   if (empty($month)) {
      $month = date('m');
   }
   if (empty($year)) {
      $year = date('Y');
   }
   $result = strtotime("{$year}-{$month}-01");
   $result = strtotime('-1 second', strtotime('+1 month', $result));
   return date('Y-m-d', $result);
}
echo lastday('6','2020');

Ở hàm trên bạn sẽ thấy trong code có tạo 2 biến $year$month. Đầu tiên sẽ kiểm tra nếu ko có 2 thông số truyền vào phù hợp thì hàm sẽ tự đông lấy năm và tháng thông qua thời gian của hiện tại. Sau đó ta sẽ gán biến $result bằng ngày đầu tiên của tháng trong năm hiện tại. Tiếp tục ta gán đè biến $result thêm 1 lần nữa như sau:

Ở lệnh strtotime(‘-1 second’, strtotime(‘+1 month’, $result)); ta thấy hàm strtotime được lồng bên trong sẽ tính bằng cách lấy năm hiện tại, còn tháng hiện tại thì cộng thêm 1 với thời gian là 0h0m0s. Khi đó ta có thời gian là năm hiện tại, tháng tiếp theo của tháng hiện tại và ngày đầu tiên của tháng đó.

Tiếp theo đi ra lệnh strtotime bên ngoài thời gian sẽ bị trừ đi 1s, tức là khi này từ 0h của ngày đầu tiên của tháng tiếp theo đó sẽ bị trừ và giờ là còn 23h59m59s của ngày trước đó. Tự khắc thời gian sẽ bị lùi về 1 ngày cũng như lùi về 1 tháng. Như vậy kết quả xuất ra màn hình sẽ là ngày cuối cùng của tháng hiện tại.

Lấy ngày đầu tiên của tháng chỉ định.

//first day of month
function firstDay($month = '', $year = '')
{
    if (empty($month)) {
      $month = date('m');
   }
   if (empty($year)) {
      $year = date('Y');
   }
   $result = strtotime("{$year}-{$month}-01");
   return date('Y-m-d', $result);
}
echo lastday('6','2020');

Ở hàm trên bạn sẽ thấy trong code có tạo 2 biến $year$month. Đầu tiên sẽ kiểm tra nếu ko có 2 thông số truyền vào phù hợp thì hàm sẽ tự đông lấy năm và tháng thông qua thời gian của hiện tại. Sau đó ta sẽ gán biến $result bằng ngày đầu tiên của tháng trong năm hiện tại. Rồi ta xuất ra trong định dạng của hàm date()

Các bạn hãy tham khảo về hàm strtotime() ở mục bên dưới để hiểu hơn nhé.

Hàm strtotime() xử lý ngày tháng trong PHP

Hàm này giúp tạo ra một kiểu định dạng thời gian theo kiểu INT từ một chuỗi.

Trường hợp này được sử dụng nhiều khi lấy dữ liệu từ MySQL với định dạng là datetime.

cú pháp: strtotime($time)

echo date('d/m/Y',strtotime('23-02-2020'));

Công dụng của hàm này chưa phải chỉ mỗi như vậy. Nó còn dùng để thực hiện một số hàm nâng cao khác, ví dụ như hàm lấy ngày cuối , ngày đầu trong tháng đã được giới thiệu ở phần trên.

Phép toán với hàm strtotime

Bắt đầu từ thời điểm nào đó trong quá khứ hoặc tương lai.
<?php
$date = strtotime('+1 day',strtotime('2020-02-23'));    //+ tính từ ngày nào đó.
echo date("d/m/Y", $date);
//output: 24/02/2020

$date2 = strtotime('-2 day',strtotime('2020-02-23'));    //- tính từ ngày nào đó.
echo date("d/m/Y", $date2);
//output: 21/02/2020
Cộng 1 tháng tính từ thời điểm hiện tại.
<?php
echo date( "Y-m-d", strtotime( "2020-02-23 +1 month" ) );   
//output: 2020-03-23
Cộng gộp 2 thời gian khác nhau

Áp dụng từ việc công trừ ngày hoặc tháng từ 2 ví dụ trên, ta có thể sử dụng phương pháp đó để cộng dồn 2 thời gian khác nhau lại với nhau theo hàm bên dưới.

<?php 
date_default_timezone_set('Asia/Ho_Chi_Minh');
function add2times($hour_one,$hour_two){
    
    $h =  strtotime($hour_one);
    $h2 = strtotime($hour_two);
 
    $minute = date("i", $h2); //gán phút của giờ thứ 2
    $second = date("s", $h2);//gán giây của giờ thứ 2
    $hour = date("H", $h2);//gán giờ của giờ thứ 2
 
    //lấy giấy, phút, giờ của giờ thứ 1 cộng cho giờ thứ 2 bằng phép cộng dồn với hàm strtotime()
    $convert = strtotime("+$minute minutes", $h); //biến $minute là phút của giờ thứ 2
    $convert = strtotime("+$second seconds", $convert); //biến $second là giây của giờ thứ 2
    $convert = strtotime("+$hour hours", $convert);//biến $hour là giờ của giờ thứ 2
    echo date('H:i:s', $convert);
}
add2times(date('H:m:s'),"8:10:56");

Hàm strtotime này có thể sau này mình sẽ viết một bài riêng để nói chuyên về nó sau vì hàm này được dùng để tính toán và ứng dụng rất nhiều.

So sánh sự chệnh lệch giữa 2 ngày

trong trường hợp so sánh độ chênh lệch của 2 ngày ta dùng hàm diff().

$date1->diff($date2);

<?php
$t1=new DateTime('2020-02-23 17:0:0');
$t2=new DateTime('2020-02-24 18:1:50');
$ss=$t1->diff($t2);
var_dump($ss);    
/*object(DateInterval)[3]
  public 'y' => int 0
  public 'm' => int 0
  public 'd' => int 1
  public 'h' => int 1
  public 'i' => int 1
  public 's' => int 50
  public 'f' => float 0
  public 'weekday' => int 0
  public 'weekday_behavior' => int 0
  public 'first_last_day_of' => int 0
  public 'invert' => int 0
  public 'days' => int 1
  public 'special_type' => int 0
  public 'special_amount' => int 0
  public 'have_weekday_relative' => int 0
  public 'have_special_relative' => int 0*/
//từ kết quả var_dump trên ta thấy độ chênh lệch là 1 ngày 1h 1 phút và 50 giây

Kiểm tra tính hợp lệ của ngày tháng.

Để kiểm tra tính hợp lệ về định dạng cho ngày tháng ta dùng hàm checkdate. Kết quả đúng sẽ trả về true, sai sẽ trả về false.

Cú pháp: checkdate($mouth, $day, $year);

<?php
var_dump(checkdate(02, 30, 2020)); //output: false
var_dump(checkdate(2, 23, 2020)); //output: true

Kết thúc

Qua bài viết trên mình đã liệu kê một số phương pháp, một số hàm cần thiết để xử lý thời gian date/time trong PHP.

Tuỳ vào mỗi trường hợp và tính đơn giản của bài toán mà ta sẽ phải áp dụng các hàm tính toán ngày tháng hoặc năm dạng nâng cao nói trên theo từng cách phù hợp nhất. Vấn đề này các bạn cần làm nhiều bài tập thì sẽ có nhiều kinh nghiệm để tự  lựa chọn phù hợp được.

Mỗi bài viết về kiến thức học PHP của mình đều có thể chưa hoàn toàn đầy đủ, cho nên mong các bạn hãy search google khi tham khảo và mong bạn có thể gửi lại comment bổ sung bên dưới để mình có thể hoàn thiện lại bài viết hơn. Cảm ơn các bạn!

Nếu các bạn cảm thấy Website TanHongIT.Com thật sự hữu ích mình mong các bạn có thể chia sẻ những bài viết đến cho cộng đồng cùng thao khảo nhé. Cảm ơn các bạn !!!

Các bạn có bất kì thắc mắc cần được hỗ trợ hay yêu cầu các phần mềm, thủ thuật, khoá học,… thì cứ để lại comment bên dưới bài viết hoặc liên hệ qua fanpage của TanHongIT để được hỗ trợ nhé! Mình sẽ cố gắng chia sẻ cho các bạn mọi thứ cần thiết nhất!

Xem thêm:

CHÚC CÁC BẠN THÀNH CÔNG VÀ VUI VẺ

5/5 - (2 votes)

Related Posts

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

0
Would love your thoughts, please comment.x
()
x