Nếu đã biết cấu trúc dữ liệu của ngày tháng năm sinh, chúng ta có thể xử lý thêm gì nữa

Trong bài viết trước, tôi đã viết 2 hàm xử lý ngày tháng năm dạng thô. Nó có tác dụng rất tốt trong việc thống kê tổng thể dữ liệu của chúng ta. Cho ta biết cấu trúc dữ liệu chủ yếu của nó, cũng như xuất ra các dữ liệu không hợp chuẩn.

Bây giờ câu hỏi là: giả sử chúng ta biết được cấu trúc dữ liệu của ngày tháng năm rồi, chúng ta nên làm gì tiếp?

Có mấy vấn đề:

  • Đối xử thế nào với dữ liệu sai?
  • Đối xử thế nào với dữ liệu khác chuẩn?
  • Dữ liệu đã khớp rồi nhưng muốn chuẩn hóa thêm nữa thì làm những gì?

Xử lý thế nào với dữ liệu sai?

Dữ liệu ngày tháng sai, thiếu có thể là:

  • Rỗng hoàn toàn, chúng ta chẳng thể làm gì với dữ liệu này, ngoài việc đánh dấu lỗi nó để các thống kê liên quan đến ngày tháng năm không lôi nó vào tính toán (xóa dữ liệu, kể cả dữ liệu lỗi là điều nên tránh, vì các cột khác có thể dùng được, và dữ liệu lỗi là mẫu tốt trong một số trường hợp đề xuất giải pháp chỉnh sửa);
  • Dữ liệu thiếu, ví dụ chỉ có ngày/tháng hoặc tháng/năm, tức là chỉ có 2 dữ liệu trên tổng số 3 dữ liệu tiêu chuẩn. Nhìn chung việc sửa dữ liệu này tương đối nguy hiểm, bởi rất khó chắc chắn, và phần lớn trường hợp chúng ta cũng nên đánh dấu lỗi để không đưa vào thống kê nếu số lượng dữ liệu này không quá lớn (nếu lượng lớn dữ liệu bị thiếu hụt thông tin, có thể chúng ta sẽ phải điều chỉnh lại cách thức thống kê, chắc chắn nó ảnh hưởng đến độ tin cậy của kết luận). Đôi khi dữ liệu này có thể sửa được, nhưng cũng thường là ước tính khoảng được thôi. Ví dụ một sinh viên trong một lớp thì có thể đoán được khá chắc là năm sinh của người đó nằm trong khoảng xê dịch vài năm so với năm sinh của các bạn cùng lớp mà chúng ta có;

Làm gì với dữ liệu khác chuẩn?

Dữ liệu khác chuẩn với tỷ lệ rất nhỏ khi mà chúng ta lấy từ một nguồn tương đối ổn định có thể có 2 lựa chọn:

  • Bạn loại trừ nó, vì nó cũng không ảnh hưởng gì đáng kể đến kết quả thống kê tổng thể cuối cùng, vì lượng dữ liệu của nó rất nhỏ;
  • Lượng dữ liệu rất nhỏ sai lệch cũng thường do lỗi nhiều hơn, chứ không phải do cấu trúc lựa chọn chủ động. Nếu không chắc chắn, dĩ nhiên chúng ta nên bỏ không đưa nó vào tính toán;

Nếu dữ liệu khác chuẩn có tỷ lệ lớn, khả năng cao đấy là sự lựa chọn chủ động của người nhập liệu, chúng ta sẽ phải soát lại dữ liệu để chắc chắn về điều này. Dữ liệu khác chuẩn chiếm tỷ lệ cao nó sẽ đi theo nhóm dữ liệu mà chúng ta thu thập, chứ sẽ không phải dạng hàng 1 thì kiểu A, còn hàng 2 thì kiểu B đảo qua đảo lại.

Khi chắc chắn chúng ta sẽ thay đổi cấu trúc của nó về dạng tiêu chuẩn.

Chuẩn hóa tiếp dữ liệu đã khớp như thế nào?

Chuẩn hóa dữ liệu như kiểu chúng ta lọc nước vậy, nó có nhiều lớp- nào cát, nào sỏi, nào than.

Càng can thiệp chuẩn xác, việc thống kê của chúng ta sẽ càng chính xác và đơn giản hơn sau này.

Dữ liệu ngày tháng năm nếu đã chuẩn hóa bước một theo thứ tự như vậy, còn mấy điều sau chúng ta cần để ý:

  • Thống nhất số 0 có đứng đằng trước giá trị dưới 10 hay không, tức là chọn 05/07/2015 hay 5/7/2015?
  • Trước tôi từng thích kiểu 5/7/2015 hơn, nhưng nghĩ lại thì kiểu có số 0 đằng trước mới thực sự hay hơn, nếu thói quen đó được duy trì nó sẽ hạn chế tối đa lỗi nhập liệu. Việc tách số lấy dữ liệu với ngày tháng có số 0 đằng trước cũng rất đơn giản;
  • Chúng ta thích để kiểu dữ liệu năm là 2 số hay 4 số? Cá nhân tôi thích 4 số vì dữ liệu rõ ràng hơn. Trong bài viết này chúng ta cũng sẽ viết mã để điều chỉnh việc này;
  • Năm sinh là giá trị mà chúng ta có nhiều cái để xử lý. Thường năm sinh sẽ chỉ nằm trong một khoảng hợp lệ nhất định. Ví dụ học sinh lớp một sẽ hiếm có dữ liệu năm sinh trước năm 2013 (năm tôi viết bài này là 2021, tức là sinh năm 2013 đã là 8 tuổi rồi, sẽ rất ít trường hợp 8 tuổi đổ lên học lớp 1). Một ví dụ khác, năm sinh của người sống sẽ không thể sớm hơn 1900 được, thậm chí là khó sớm hơn 1920. Năm sinh của bất kỳ ai cũng không thể hơn năm ở thời điểm hiện tại được (ví dụ năm nay là năm 2021 thì không thể có năm sinh của ai đó đã sinh khỏi bụng mẹ mà là năm 2022 được, dự sinh thì OK!)

Bây giờ sẽ đến các đoạn mã xử lý

Đoạn mã dưới đây sẽ xử lý tổng thể các lỗi liên quan đến ngày tháng năm, trong thực tế, mã có thể đơn giản hơn tương đối nhiều, vì dữ liệu ngày tháng năm được nhập liệu tương đối chính xác, có lẽ là nhờ các công cụ bảng tính như Excel hoặc các bảng tính trực tuyến tương tự.

Ở đây chúng ta cũng sẽ viết hàm để tiện gọi khi cần.

function chuan_hoa_ntn($nscu) {}//hàm lấy biến đầu vào là năm sinh cần chuẩn hóa $nscu

Tiếp đến chúng ta loại bỏ khoảng trắng trước và trong dữ liệu, cái này để phòng xa, nhiều dữ liệu không bị lỗi này:

$nscu1 = trim($nscu, ' '); // loại bỏ khoảng trắng trước và sau chuỗi

$nscu2 = preg_replace('/\s+/', ' ', $nscu1); // loại bỏ khoảng trắng thừa ở giữa chuỗi

Hàm preg_replace liên quan đến biểu thức chính quy (regex) trong PHP (regex được rất nhiều ngôn ngữ lập trình hỗ trợ, dù không thống nhất 100%, rất nhiều mã là tương tự nhau, nghĩa là bạn có thể dùng nó trong nhiều ngôn ngữ khác nhau mà không phải học lại từ đầu). Đây là công cụ rất mạnh để xử lý chuỗi, các bạn nào chưa biết nên thử tìm hiểu…

Cũng để phòng xa, chúng ta tiến hành loại bỏ các ký tự không được phép trong chuỗi ngày tháng, lỗi này cũng ít gặp, và trước khi thực hiện chúng ta phải quan sát trước các dữ liệu để biết rằng làm như vậy thì việc loại bỏ có đúng hay không (chứ không phải là chuyển một kiểu sai này sang một kiểu sai khác), giả định là được phép thì mã lệnh sẽ thế này:

$ktdu = array('~', '!', '@', '#','$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '[', '{', ']', '}', '|', ':', ';', '"', ',', '<', '>', '?', '+', '\\', '\''); // ký tự dư lỗi

$nscu3 = str_replace($ktdu, "", $nscu2); // câu lệnh loại bỏ ký tự dư

Mã tiếp theo chúng ta sẽ thống nhất các ký tự phân cách ngày tháng năm về cùng một kiểu. Cụ thể tôi sẽ chuyển các ký tự phân cách là dấu gạch ngang - và dấu . về dấu gạch xuôi /

Đoạn mã cụ thể như thế này:


$nscu4 = preg_replace('/\./', '/', $nscu3); //thay dấu chấm
$nscu5 = preg_replace('/-/', '/', $nscu4); //thay dấu gạch ngang

Vì kết hợp cả hai dấu không được nên tôi tách riêng, bạn chú ý dấu chấm là một ký tự đại diện đã được định nghĩa trong regex nên để dùng nó như một ký hiệu bình thường chúng ta cần thêm dấu gạch ngược \

Phần tiếp theo chúng ta sẽ dùng Regex để thiết lập và lấy mẫu ngày/tháng/năm tiêu chuẩn, ở đây tôi sẽ bắt chặt hơn thông thường, vì đây là năm sinh của người trong khoảng thời gian nhiều nhất là từ đầu thế kỷ 19 cho đến thời điểm hiện tại:

$rea = '/^(0?[1-9]|[12]\d|3[01])[\/](0?[1-9]|[1][012])[\/](\d{2}|19\d{2}|20[012]\d)$/'; // năm chỉ hợp lệ từ 1900 đến 2029

$kq=preg_match($rea, $nscu3, $match); // kiểm tra xem có khớp với mẫu chuẩn hay chưa

Mảng $match sẽ lưu kết quả nếu khớp. Trong đó:

  • $match[0] là cả chuỗi ngày tháng năm;
  • $match[1] là ngày;
  • $match[2] là tháng;
  • $match[3] là năm;
  • Nếu khớp thì giá trị $kq sẽ bằng 1, còn không nó sẽ bằng 0;

Giờ chúng ta sẽ kiểm tra những thành phần tháng hoặc ngày nào dưới 10 mà ở dạng một số ta sẽ thêm 0 vào để thành kiểu như 05/07/2015

if($kq==1) {
                $mn=$match[1]; // lấy thông tin ngày
                $s_mn=(int)$mn; // chuyển nó sang giá trị số
                if (mb_strlen($s_mn)==1) {$mn2="0".$s_mn;} else {$mn2=$mn;} 
                
}

Hàm mb_strlen() giúp chúng ta đếm số ký tự trong chuỗi. Sau khi chuyển đổi sang dạng số, mà số lượng ký tự chỉ là 1, chúng ta hiểu rằng giá trị của nó chỉ có thể là từ 1 đến 9. Vì vậy chúng ta sẽ gắn số 0 đằng trước cho phù hợp với chuẩn đề ra ban đầu.

Nếu số lượng ký tự khác 1, tức là nó có 2 chữ số (10,11, cho đến 31). Trường hợp này chúng ta không phải chỉnh sửa gì, và gán lại giá trị trung gian cho giá trị ban đầu (đoạn $mn2=$mn;).

Mã chuyển đổi cho tháng cũng tương tự.

Nâng cao chức năng của hàm

Về cơ bản chúng ta đã đi được nửa chặng đường, chỉ cần xử lý dữ liệu năm từ 2 số thành 4 số nữa là xong.

Ở đây tôi muốn nâng cao hàm chuẩn hóa ngày tháng này trong trường hợp tổng quát. Tôi sẽ bổ sung thêm tính năng để nó xác định một thời điểm năm sinh nào đó có hợp lệ hay là không. Để đỡ phức tạp, biến truyền vào xác thực dữ liệu chỉ cần là năm, điều này cũng giải quyết được chính xác vấn đề trong rất nhiều trường hợp.

Hàm function giờ sẽ có cấu trúc như thế này:

function chuan_hoa_ntn($nscu,$nann,$naln,$utn) {}

Trong đó ngoài biến $nscu đại diện dữ liệu ngày tháng năm chúng ta cần xử lý thì giờ chúng ta có thêm 3 biến mới:

  • Biến $nann để chỉ năm hợp lệ nhỏ nhất được phép, giá trị chuẩn là một số gồm 4 chữ số không được nhỏ hơn 1900;
  • Biến $naln để chỉ năm hợp lệ lớn nhất được phép, giá trị chuẩn là một số có 4 chữ số, lớn hơn hoặc bằng giá trị của $nann, nhưng không được lớn hơn năm hiện tại (2021 tại thời điểm tôi viết bài này);
  • Biến $utn liên quan đến cách chuyển dữ liệu từ 2 số sang bốn số sẽ ưu tiên kiểu chuyển nào hơn, nó cũng rất quan trọng, về sau khi đi vào mã chi tiết bạn sẽ hiểu rõ hơn;

Ở phần mã lấy tham 3 tham số đầu vào ở trên không có gì quá đặc biệt, dù nó là mấy vòng IF trông hơi lằng nhằng, mục đích cốt yếu là để dự phòng ngay cả khi tham số đầu vào nhập sai ví dụ sai giá trị hoặc thậm chí nhập vào ký tự khác số, nó vẫn có được các thiết lập cơ bản để tránh lỗi.

Đối với dữ liệu năm là dạng 4 số, công việc của chúng ta rất đơn giản, chúng ta sẽ chuyển dữ liệu đó thành dạng số (dùng hàm (int)) rồi so sánh nó với giá trị lớn nhất và nhỏ nhất để xác thực.

Đối với dữ liệu năm chỉ có 2 chữ số, vấn đề sẽ phức tạp hơn. Ví dụ cụ thể để chúng ta hiểu rõ hơn:

  • Chẳng hạn bạn có dữ liệu đầu vào như thế này 29/11/15 dù chúng ta biết rằng năm hợp lệ là từ 1900 đến năm hiện tại thì vấn đề ở đây là chúng ta gán 19 hay 20 thêm vào giá trị 15? Vì cả hai giá trị này khi gán vào đều không sai.
  • Đây là lý do xuất hiện biến $utn nếu nó có giá trị bằng 20, thì hàm sẽ gán 20 vào các giá trị nằm trong khoảng từ 0 cho đến 2 số cuối của năm hiện tại, tức là nếu 2 số của năm cuối nằm trong khoảng từ 00 đến 21 nó sẽ gán 20 vào, còn nếu rơi vào các giá trị khác từ 22 đến 99 sẽ gắn 19;
  • Nếu $utn được đặt bằng 19, tất cả dữ liệu năm 2 số sẽ được gắn thêm 19 vào trước đó;
  • Trong thực tế đối với các dữ liệu năm sinh người trong khoảng thời gian gần hiện tại thì $utn bằng 20 sẽ hợp lý hơn nên mặc định hệ thống cũng set giá trị này nếu vô tình bạn nhập vào giá trị khác 19 hoặc 20;

Ở phần cuối cùng khi trả về giá trị cho hàm, tôi đưa nó vào mảng, vì cần lưu tới 3 kết quả khác nhau, bao gồm:

  • Một giá trị 0 hoặc 1 để xác định dữ liệu có phải là ngày/tháng/năm tiêu chuẩn không, nó là giá trị đầu tiên trong mảng;
  • Giá trị thứ 2 của mảng là giá trị ngày tháng năm được chuẩn hóa với số 0 đằng trước các giá trị dưới 10 trong ngày hoặc/và tháng. Ngoài ra là chuyển đổi năm từ dạng 2 số về 4 số;
  • Giá trị cuối cùng trong mảng cũng là dạng 0 hoặc 1 để xác định năm của dữ liệu có nằm trong khẳng năm nhỏ nhất và lớn nhất hay không;

OK, cuối cùng là đoạn mã hoàn chỉnh, bạn có thể copy-paste nó sang một ứng dụng chuyên để viết code PHP như Netbeans sẽ dễ quan sát hơn nhiều, vì trong mã tôi viết rất nhiều chú thích.

<?php
function chuan_hoa_ntn($nscu,$nann,$naln,$utn) {
        // $nscu là năm cần chuẩn hóa, $naln là năm lớn nhất được cho phép trong dữ liệu
        // giá trị hợp lệ của $nann năm nhỏ nhất nhất là 1900 đến tối đa là năm hiện tại
        // giá trị hợp lệ của $naln năm lớn nhất là 1900 đến tối đa là năm hiện tại
        // nann cần phải nhỏ hơn naln đây là khoảng giá trị mà chúng ta dùng để đánh giá giá trị năm có hợp lệ không
        // nann nếu không được thiết lập hoặc thiết lập sai sẽ lấy giá trị là 1900
        // khi naln không được thiết lập hoặc thiết lập sai nó sẽ lấy giá trị mặc định là năm hiện tại
        // $utn là ưu tiên các ghép dữ liệu năm 2 số là 19 hay 20 tùy trường hợp
        // giá trị hợp lệ của $utn là 19 hoặc 20, khi không thiết lập hoặc thiết lập sai nó mặc định là 20
        $nscu1 = trim($nscu, ' '); // loại bỏ khoảng trắng trước và sau chuỗi
        $nscu2 = preg_replace('/\s+/', ' ', $nscu1); // loại bỏ khoảng trắng thừa ở giữa chuỗi
        
        $ktdu = array('~', '!', '@', '#','$', '%', '^', '&', '*', '(', ')', '_', '=', '+', '[', '{', ']', '}', '|', ':', ';', '"', ',', '<', '>', '?', '+', '\\', '\''); // ký tự dư lỗi
        // Vì trùng với cú pháp trong PHP nên một số dấu như ' và \ bạn cần thêm dấu \ đằng trước, không nó sẽ báo lỗi.
        
        $nscu3 = str_replace($ktdu, "", $nscu2); // câu lệnh loại bỏ ký tự dư
        
        // Chuyển vê cùng một dạng dấu phân cách
        $nscu4 = preg_replace('/\./', '/', $nscu3); //thay dấu chấm
        $nscu5 = preg_replace('/-/', '/', $nscu4); //thay dấu gạch ngang
        
        $rea = '/^(0?[1-9]|[12]\d|3[01])[\/](0?[1-9]|[1][012])[\/](\d{2}|19\d{2}|20[012]\d)$/'; // năm chỉ hợp lệ từ 1900 đến 2029
        // Biểu thức chính quy Regex này bắt ngày tháng năm khá chặt
        // ngày từ 1 đến 31 có thể có 0 ở trước số dưới 10
        // tháng từ 1 đến 12, có thể có 0 đằng trước số dưới 10
        // năm bắt từ năm 1900 đến tối đa 2029, hàm này đúng trong vòng 8 năm nữa, đến năm 2030 hàm bắt năm sinh sẽ không còn đúng nữa
        
        $kq=preg_match($rea, $nscu5, $match); // kiểm tra xem có khớp với mẫu chuẩn hay chưa
        
        if($kq==1) {
                $mn=$match[1]; // lấy thông tin ngày
                $s_mn=(int)$mn;
                if (mb_strlen($s_mn)==1) {$mn2="0".$s_mn;} else {$mn2=$mn;} //đã chuyển ngày dạng dưới 10 không có số không đằng trước thành có số 0 đằng trước
                
                $mt=$match[2]; // lấy thông tin tháng
                $s_mt=(int)$mt;
                if (mb_strlen($s_mt)==1) {$mt2="0".$s_mt;} else {$mt2=$mt;}//đã chuyển tháng dạng dưới 10 không có số không đằng trước thành có số 0 đằng trước

                $ns_hl=1; // kiểm tra xem giá trị của năm có hợp lệ hay không, mặc định để là hợp lệ

                $nho_chuoi_nam=$match[3]; //để gắn vào khi cần

                $mna=$match[3]; // lấy năm trong chuỗi
                $s_mna=(int)$mna; // chuyển về dạng số, nếu là dạng 4 số sẽ chuyển thành 4 số, nếu là dạn 2 số sẽ chuyển thành 2 số, nếu 2 số có số 0 đằng trước sẽ chuyển thành dạng 1 số

                $y4=date("Y"); // lấy giá trị của năm hiện tại ở dạng 4 số, đây là một hàm của PHP, dùng dự phòng trong trường hợp giá trị năm lớn nhất $nln không được thiết lập

                // Đánh giá tham số năm nhỏ nhất truyền vào hàm
                if (isset($nann)) { // kiểm tra xem dữ liệu năm lớn nhất có được đưa vào hàm hay không
                                    $nann=(int)$nann; //chuyển nó về dạng số vì hàm is_int kiểm tra chặt
                                    if (is_int($nann)) { // kiểm tra xem nó có phải là số nguyên hay không?
                                                        if ($nann>$y4 || $nann<1900) {$nann_tt=1900;} //nếu có thì kiểm tra nó có nằm trong giá trị hợp lệ không 
                                                        // nếu không hợp thì naln được gán cho 1900
                                                        else {$nann_tt=$nann;}}//nếu hợp lệ nó mới được gán giá trị vào nann_tt
                                    else {$nann_tt=1900;} // nếu giá trị nhập vào không phải là số nó cũng được gán cho $y4, tức là năm hiện tại                   
                } else {$nann_tt=1900;} // nếu có tham số thì lấy giá trị của $nln, còn nếu không có thì lấy năm hiện tại
                $nann_tt=(int)$nann_tt;//chuyển sang giá trị só cho chắc ăn

                // Đánh giá tham số năm lớn nhất truyền vào hàm
                if (isset($naln)) { // kiểm tra xem dữ liệu năm lớn nhất có được đưa vào hàm hay không
                                    $naln=(int)$naln; //chuyển nó về dạng số vì hàm is_int kiểm tra chặt
                                    if (is_int($naln)) { // kiểm tra xem nó có phải là số nguyên hay không?
                                                        if ($naln>$y4 || $naln<1900) {$ntt=$y4;} //nếu có thì kiểm tra nó có nằm trong giá trị hợp lệ không 
                                                        // nếu không hợp thì naln được gán cho năm hiện tại
                                                        else {$ntt=$naln;}}//nếu hợp lệ nó mới được gán giá trị vào ntt
                                    else {$ntt=$y4;} // nếu giá trị nhập vào không phải là số nó cũng được gán cho $y4, tức là năm hiện tại                   
                } else {$ntt=$y4;} // nếu có tham số thì lấy giá trị của $nln, còn nếu không có thì lấy năm hiện tại

                $nss=(int)$ntt; // lấy năm so sánh và chuyển về dạng số, cái này là 4 số, có giá trị hợp lệ từ 1900 đến tối đa là năm hiện tại

                if (mb_strlen($s_mna)==4) {//Với chuỗi năm là 4 số
                        if (($s_mna>$nss) || ($s_mna<$nann_tt)) {$ns_hl=0;}
                        $con_nam4so=$nho_chuoi_nam;
                }
                
                // Đánh giá tham số ưu tiên truyền vào
                if (isset($utn)) { // kiểm tra xem giá trị ưu tiên có được truyền vào hàm hay không
                                    $utn=(int)$utn; //chuyển nó về dạng số vì hàm is_int kiểm tra chặt
                                    if (is_int($utn)) { // kiểm tra xem nó có phải là số nguyên hay không?
                                                        if ($utn>20 || $utn<19) {$utn_tt=20;}
                                                        else {$utn_tt=$utn;}//nếu hợp lệ mới được gán
                                    }
                                    else {$utn_tt=20;} // nếu giá trị nhập vào không phải là số nó cũng được gán là 20                
                } else {$utn_tt=20;} // nếu có tham số thì lấy giá trị của $utn, còn nếu không có thì lấy giá trị mặc định là 20
                

                if (mb_strlen($mna)==2) {//Với chuỗi năm là 2 số
                           $rep='/^\d{2}/'; //biểu thức chính quy để chọn 2 ký tự đầu rồi thay thế nó bằng rỗng ở biểu thức bên dưới để chúng ta có 2 số cuối
                           $nss_tach=preg_replace($rep,'',$nss);//lấy 2 số cuối của năm cần so sánh
                           $nn_so=(int)$nss_tach; //chuyển thành dạng số
                           $y2=date("y"); // lấy giá trị 2 năm cuối của năm hiện tại
                           // giá trị ưu tiên dùng để quyết định ghép số ở phần này
                                if ($utn_tt==19) {$nam4so="19".$nho_chuoi_nam;} 
                                if ($utn_tt==20) {if ($s_mna>=0 && $s_mna<=$y2) {$nam4so="20".$nho_chuoi_nam;} else {$nam4so="19".$nho_chuoi_nam;}}
                        
                            $con_nam4so=(int)$nam4so;
                            if(($con_nam4so>$nss) || ($con_nam4so<$nann_tt)) {$ns_hl=0;}
                 }
             $kqi=$mn2."/".$mt2."/".$con_nam4so;
              
        } else {$kqi=$nscu5;$ns_hl=0;} // nếu hợp chuẩn sẽ được chuẩn hóa, nếu không sẽ trả về $nscu5
$ntn_arr=array();

$ntn_arr[0]=$kq; // xem có phải là chuỗi ngày tháng năm hợp chuẩn không, 1 là hợp chuẩn, 0 là không hợp chuẩn
$ntn_arr[1]=$kqi; // nếu hợp chuẩn sẽ được chuẩn hóa, nếu không sẽ trả về $nscu5
$ntn_arr[2]=$ns_hl; // báo xem năm có hợp lệ so với yêu cầu của năm lớn nhất không, giá trị 0, 1. Nếu bằng 1 là hợp lệ

return $ntn_arr;
}
$nscu2="1-2-99";$nann2="1997";$naln2="2012";$utn2="20";
$tim=chuan_hoa_ntn($nscu2,$nann2,$naln2,$utn2);
$kqt="";

foreach ($tim as $kqc) {
    echo $kqc."</br>";
}

Vài kết quả demo:

Đầu vào: $nscu2="1-2-09";$nann2="2005";$naln2="2015";$utn2="20";
Đầu ra: 
1 -> dữ liệu đúng chuẩn thứ tự ngày tháng năm
01/02/2009 -> dữ liệu được chuẩn hóa
1 -> năm nằm trong khoảng thiết lập

-----
Đầu vào: $nscu2="1-2-09";$nann2="2010";$naln2="2015";$utn2="20";
Đầu ra:
1
01/02/2009
0 -> năm nằm ngoài khoảng thiết lập

-----
Đầu vào: $nscu2="1-2-9";$nann2="2010";$naln2="2015";$utn2="20";
Đầu ra:
0 -> không phải dữ liệu ngày tháng
1/2/9
0 -> khi đã không phải dữ liệu ngày tháng, giá trị cuối cùng chắc chắn là 0


-----
Đầu vào: $nscu2="1.2.89";$nann2="1980";$naln2="2015";$utn2="20";
Đầu ra:
1 -> đúng dữ liệu ngày tháng năm
01/02/1989 -> dữ liệu được chuẩn hóa
1 -> năm nằm trong khoảng thiết lập

-----
Đầu vào: $nscu2="1.2.15";$nann2="1980";$naln2="2015";$utn2="19";
Bạn chú ý $utn2 đã chuyển thành 19
Đầu ra:
1
01/02/1915 -> nếu $utn
 bằng 20, năm sẽ được chuyển thành 2015
0

----
Đầu vào: $nscu2="1.2.15";$nann2="cdsd";$naln2="êr";$utn2="rer";
Bạn chú ý các 3 biến cuối cùng nhập sai dữ liệu tiêu chuẩn
Đầu ra:
1
01/02/2015
1

OK, như vậy là tạm ổn rồi, xin chào và hẹn gặp lại các bạn trong bài viết khác.

Leave a Comment