Tag Archive date

PHPExcel: จัดรูปแบบ format ข้อมูล

เมื่อวานเขียน export ข้อมูลออกเป็นไฟล์ excel โดยใช้เวลาไม่นาน เพราะโครงสร้างการทำงานมันเหมือนๆ งานที่เคยทำมา แต่มาตกม้าตายเอาที่การฟอร์เมตของแต่ละ column ให้ตรงกับชนิดข้อมูล เช่น type เป็น date ก็ควรให้เห็นเป็นวันที่ไม่ใช่เลข 1234155 อะไรก็ไม่ทราบ

[code language=”php” title=”PHPExcel/columnsType.php”]<?php

include ‘../vendor/phpoffice/phpexcel/Classes/PHPExcel.php’;

set_time_limit(0);

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
->setName(‘Arial’)
->setSize(11);

$defaultStyle->getNumberFormat()
->setFormatCode(‘yyyy-mm-dd’);

/* Set document properties */
$title = ‘columnsType_’ . date(‘Y-m-d_H:i’);
$objPHPExcel->getProperties()->setCreator(‘CMS’)
->setCategory(‘Exports Datas’)
->setDescription($title)
->setKeywords(‘Exports Datas ‘ . date(‘Y-m-d’))
->setSubject($title)
->setTitle($title);

/* create new sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle(‘Exports Datas’);

$columns = [
‘row_number’ => [‘title’ => ‘No.’, ‘type’ => ‘row_number’],

‘price’ => [‘title’ => ‘ราคา’, ‘type’ => ‘currency’],

‘dateEnd’ => [‘title’ => ‘เริ่มจำหน่าย’, ‘type’ => ‘date’],
‘dateStart’ => [‘title’ => ‘เริ่มจำหน่าย’, ‘type’ => ‘date’],

‘dateApproved’ => [‘title’ => ‘เวลาอนุมัติ’, ‘type’ => ‘datetime’],

‘height’ => [‘title’ => ‘สูง (เมตร)’, ‘type’ => ‘float’],
‘width’ => [‘title’ => ‘กว้าง (เมตร)’, ‘type’ => ‘float’],

‘calculate’ => [‘title’ => ‘สูตรคํานวณหวย’, ‘type’ => ‘formula’],

‘image’ => [‘title’ => ‘ภาพ’, ‘type’ => ‘image’],

‘items’ => [‘title’ => ‘จำนวน’, ‘type’ => ‘integer’],

‘productName’ => [‘title’ => ‘ชื่อสินค้า’, ‘type’ => ‘string’],

‘timeEnd’ => [‘title’ => ‘เวลาขาย’, ‘type’ => ‘time’],
‘timeStart’ => [‘title’ => ‘เวลาปิดการขาย’, ‘type’ => ‘time’],

‘url’ => [‘title’ => ‘page’, ‘type’ => ‘url’],
];

/* header */
$colNo = -1;
$rowNo = 1;
$colStrings = [];
foreach ($columns as $fieldId => $field) {
$colNo++;
$colStrings[$colNo] = $colString = PHPExcel_Cell::stringFromColumnIndex($colNo);
$objWorkSheet->setCellValue($colString . ‘1’, $field[‘title’]);
$objWorkSheet->setCellValue($colString . ‘2’, ‘type = ‘ . $field[‘type’]);
}
$headerHeight = $rowNo = 2;

$objPHPExcel->getActiveSheet()->freezePane($colString . ($headerHeight + 1));

/* random data */
$datas = [];
for ($a = 0; $a < 10; $a++) {
$temp = [];

$temp[‘calculate’] = ‘=RAND()’;
$temp[‘dateApproved’] = date(DATE_ISO8601, mt_rand(0, 1499291999));
$temp[‘dateEnd’] = date(‘Y-m-d’, mt_rand(0, 1499291999));
$temp[‘dateStart’] = date(‘Y-m-d’, mt_rand(0, 1499291999));
$temp[‘height’] = mt_rand(0, 10) / 10;
$temp[‘image’] = ‘http://lorempixel.com/400/200/sports/?st=’ . mt_rand(1, 500);
$temp[‘items’] = mt_rand(999, 9999999);
$temp[‘price’] = mt_rand(100, 10000);
$temp[‘productName’] = substr(str_shuffle(str_repeat($x = ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’, ceil(10 / strlen($x)))), 1, 10);
$temp[‘timeEnd’] = date(‘H:i:s’, mt_rand(0, 1499291999));
$temp[‘timeStart’] = date(‘H:i:s’, mt_rand(0, 1499291999));
$temp[‘url’] = ‘https://plusmagi.com/?s=’ . mt_rand(1, 500);
$temp[‘width’] = mt_rand(0, 10) / 10;

array_push($datas, $temp);
}

/* add data */
$row_number = 0;
foreach ($datas as $item) {
$colNo = -1;
$row_number++;
$rowNo++;
foreach ($columns as $fieldId => $field) {
$colNo++;

$coordinate = $colStrings[$colNo] . $rowNo;

switch ($field[‘type’]) {
case ‘date’:
case ‘datetime’:
case ‘time’:{
$ts = strtotime($item[$fieldId]);
$value = PHPExcel_Shared_Date::PHPToExcel($ts);
}break;

case ‘image’:{
$value = $item[$fieldId];

$gdImage = imagecreatefromjpeg($value);
$objDrawing = new PHPExcel_Worksheet_MemoryDrawing(); /*create object for Worksheet drawing*/

$objDrawing->setCoordinates($coordinate); /*set image to cell*/
$objDrawing->setDescription(‘Customer Signature’); /*set description to image*/
$objDrawing->setHeight(50);
$objDrawing->setImageResource($gdImage);
$objDrawing->setName(‘Customer Signature’); /*set name to image*/
$objDrawing->setOffsetX(25); /*setOffsetX works properly*/
$objDrawing->setOffsetY(10); /*setOffsetY works properly*/
$objDrawing->setWidth(100); /*set width, height*/

$objDrawing->setWorksheet($objWorkSheet); /*save*/

$objWorkSheet->getRowDimension($rowNo)->setRowHeight(60); /* set row height*/
}break;

case ‘row_number’:{
$value = $row_number;
}break;

case ‘url’:{
$value = str_replace(‘http://’, ”, $item[$fieldId]);
$objWorkSheet->getCell($coordinate)
->getHyperlink()
->setTooltip(‘Click here to access page’)
->setUrl($item[$fieldId]);
}break;

default:{
$value = $item[$fieldId];
}break;
}

$objWorkSheet->setCellValue($coordinate, $value);
}
}

/* auto width column */
$cellIterator = $objWorkSheet->getRowIterator()->current()->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true);
foreach ($cellIterator as $cell) {
$objWorkSheet->getColumnDimension($cell->getColumn())->setAutoSize(true);
}

/* format for columns */
$colNo = -1;
foreach ($columns as $fieldId => $field) {
$colNo++;

$coordinate = $colStrings[$colNo] . ($headerHeight + 1) . ‘:’ . $colStrings[$colNo] . $rowNo;

switch ($field[‘type’]) {

case ‘currency’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(‘#,##0.00’);
/*->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER);*/
}break;

case ‘date’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH);
}break;

case ‘datetime’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);
/*->setFormatCode(‘Y-m-d H:i:s’);*/
}break;

case ‘float’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
}break;

case ‘integer’:
case ‘row_number’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(‘#,##’);
}break;

case ‘time’:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
/*->setFormatCode(‘Y-m-d H:i:s’);*/
}break;

default:{
$objWorkSheet->getStyle($coordinate)
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
}break;
}

}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, ‘Excel2007’);
header(‘Content-Type: application/vnd.ms-excel’);
header(‘Content-Disposition: attachment;filename="’ . $title . ‘.xlsx"’);
header(‘Cache-Control: max-age=0’);
header(‘Cache-Control: no-store, no-cache, must-revalidate, max-age=0’);
header(‘Cache-Control: post-check=0, pre-check=0’, false);
header(‘Pragma: no-cache’);
$objWriter->save(‘php://output’);[/code]

หลักการต้องทำงานคู่กัน 2 ส่วนคือ

  1. ส่วนใส่ข้อมูล บางชนิดต้องแปลงข้อมูลก่อน เช่น date, datetime, timestamp และ time ต้องเปลี่ยนเป็น unix timestamp ก่อน
  2. ส่วนกำหนด cell format (ในตัวอย่างให้วิธีกำหนดทั้ง column ไปเลย) ต้องเลือกรูปแบบที่เหมาะสมโดยจะกำหนดเอง[code language=”php” title=”custom format”]->setFormatCode(‘Y-m-d H:i:s’);[/code] หรือจะใช้ตามมาตราฐานก้ได้ Class PHPExcel_Style_NumberFormat ก็ได้

PHP วันที่ เวลา คำนวณ

ตัวอย่างการเพิ่ม ลด แสดงเวลา คำนวณ ช่วงเวลาใน php[code language=”php” title=”phpMonthsDiff.php”]<?php
$date = new DateTime(‘now’);
echo ‘<br>วันเวลาปัจจุบัน ‘, $date->format(‘d/m/Y’);
echo ‘<br>ถ้าเป็นที่สหรัฐจะเขียนแบบนี้ ‘, $date->format(‘m/d/Y’);
$dateUS = new DateTime(‘now’, new DateTimeZone(‘America/New_York’));
echo ‘<br>เวลาของเค้าคือ ‘, $dateUS->format(‘m/d/Y H:i:s’);
echo ‘<br>ถ้าเป็น MySQL จะเก็บแบบนี้ ‘, $date->format(‘Y-m-d H:i:s’);
echo ‘<br>ถ้าเป็น ISO 8601 จะเก็บแบบนี้ ‘, $date->format(‘c’);
echo ‘<br>ถ้าเป็น Unix จะเก็บแบบนี้ ‘, $date->format(‘U’);
echo ‘<hr>’;
echo ‘<br>เพิ่มอีก 1 วัน ‘, $date->modify(‘+1 day’)->format(‘d/m/Y’);
echo ‘<br>เพิ่มอีก 7 วัน ‘, $date->modify(‘+1 day’)->format(‘d/m/Y’);
echo ‘<br>เพิ่มอีก 1 เดือน ‘, $date->modify(‘+1 month’)->format(‘d/m/Y’);
echo ‘<br>เพิ่มอีก 1 ปี ‘, $date->modify(‘+1 year’)->format(‘d/m/Y’);
echo ‘<hr>’;
echo ‘<br>ลดอีก 1 วัน ‘, $date->modify(‘-1 day’)->format(‘d/m/Y’);
echo ‘<br>ลดอีก 7 วัน ‘, $date->modify(‘-1 day’)->format(‘d/m/Y’);
echo ‘<br>ลดอีก 1 เดือน ‘, $date->modify(‘-1 month’)->format(‘d/m/Y’);
echo ‘<br>ลดอีก 1 ปี ‘, $date->modify(‘-1 year’)->format(‘d/m/Y’);
echo ‘<hr>’;
$timeStart = DateTime::createFromFormat(‘d/m/Y’, ‘5/8/1982’);
echo ‘<br>ฉันเกิดวันที่ ‘, $timeStart->format(‘d/m/Y’);
echo ‘<hr>’;
echo ‘<br>อายุ ‘, $timeStart->diff($date)->format(‘%y’), ‘ ปี ‘, $timeStart->diff($date)->format(‘%m’), ‘ เดือน ‘, $timeStart->diff($date)->format(‘%d’), ‘ วัน’;
echo ‘<br>คิดอายุเป็น ‘, $timeStart->diff($date)->format(‘%a’), ‘ วัน’;
echo ‘<br>ถ้าจะหากิจกรรมระหว่างวันเกิด ถึงปัจจุบันคือ xxx BETWEEN ‘, $timeStart->format(‘Y-m-d 00:00:00’), ‘ AND ‘, $date->format(‘Y-m-d 23:59:59’);
[/code]

ผลที่ได้

วันเวลาปัจจุบัน 11/11/2016
ถ้าเป็นที่สหรัฐจะเขียนแบบนี้ 11/11/2016
เวลาของเค้าคือ 11/11/2016 14:29:35
ถ้าเป็น MySQL จะเก็บแบบนี้ 2016-11-11 20:29:35
ถ้าเป็น ISO 8601 จะเก็บแบบนี้ 2016-11-11T20:29:35+01:00
ถ้าเป็น Unix จะเก็บแบบนี้ 1478892575


เพิ่มอีก 1 วัน 12/11/2016
เพิ่มอีก 7 วัน 13/11/2016
เพิ่มอีก 1 เดือน 13/12/2016
เพิ่มอีก 1 ปี 13/12/2017


ลดอีก 1 วัน 12/12/2017
ลดอีก 7 วัน 11/12/2017
ลดอีก 1 เดือน 11/11/2017
ลดอีก 1 ปี 11/11/2016


ฉันเกิดวันที่ 05/08/1982


อายุ 34 ปี 3 เดือน 6 วัน
คิดอายุเป็น 12517 วัน
ถ้าจะหากิจกรรมระหว่างวันเกิด ถึงปัจจะปัญคือ xxx BETWEEN 1982-08-05 00:00:00 AND 2016-11-11 23:59:59

ถ้าต้องการหาจำนวนเดือน ให้อ่าน นับ เดือนโดย PHP อ่านเพิ่มเติม date — Format a local time/date, The DateTimeZone class, The DateInterval class

นับ เดือนโดย PHP

หลายวันก่อนมีสมาชิกในชมรมคนทำเว็บโพสว่า php คิดเดือนให้ผิด เชื่อถือไม่ได้ เราก็ใช้ php มานาน ก็คิดว่าเค้าเขียน code ผิดรึเปล่า แต่เค้าก็บอกว่าลบ code ออกไปแล้ว แต่ก็ให้ตัวอย่างวันที่มา ลองเขียน code date_diff ดูมันนับผิดจริงๆ ลองไล่หาสาเหตุดูเข้าใจว่ามันคิดผิดเพราะนับเป็นวัน สาเหตุ คือ php จะแปลงวันที่เป็นตัวเลข timestamp อย่าง

  • 2010-04-28 22:41:43 = 1272508903
  • 2007-02-14 20:25:25 จะเป็น 1171502725

และแต่ละเดือนมีวันไม่เท่ากัน แถมบางปีเดือนกุมพาพันธ์ ก็มี 28 / 29 วัน แต่ date_diff ของ php เหมือนจะไม่ได้คิดเรื่องนี้ เอาเวลาตายตัวมาคิด ทำให้ต้องใช้วิธี แยกปี แยกเดือน แล้วเอามาใส่สูตรเอาเอง

[code language=”php” title=”phpMonthsDiff.php”]<?php

$dateRanges = [
[’01/02/2016′, ’01/03/2016′],
[’01/02/2016′, ’01/04/2016′],
[’01/11/2013′, ’30/11/2013′],
[’01/01/2013′, ’31/12/2013′],
[’31/01/2011′, ’28/02/2011′],
[’01/09/2009′, ’01/05/2010′],
[’01/01/2013′, ’31/03/2013′],
[’15/02/2013′, ’15/04/2013′],
[’01/02/1985′, ’31/12/2013′],
];

foreach ($dateRanges as $range) {
list($dateStart, $dateEnd) = $range;

$timeStart = DateTime::createFromFormat(‘d/m/Y’, $dateStart);
$timeEnd = DateTime::createFromFormat(‘d/m/Y’, $dateEnd);

$months = $timeStart->diff($timeEnd)->format(‘%m’);

echo ‘<br>’, $dateStart, ‘ => ‘, $dateEnd, ‘ = ‘, $months, ‘ months’;
}
echo ‘<hr>’;
foreach ($dateRanges as $range) {
list($dateStart, $dateEnd) = $range;

$timeStart = DateTime::createFromFormat(‘d/m/Y’, $dateStart);
$timeEnd = DateTime::createFromFormat(‘d/m/Y’, $dateEnd);

$months = abs(($timeEnd->format(‘Y’) – $timeStart->format(‘Y’)) * 12 + ($timeEnd->format(‘m’) – $timeStart->format(‘m’)));

echo ‘<br>’, $dateStart, ‘ => ‘, $dateEnd, ‘ = ‘, $months, ‘ months’;
}
[/code]

ผลที่ได้คือ

  • 01/02/2016 => 01/03/2016 = 1 months
  • 01/02/2016 => 01/04/2016 = 2 months
  • 01/11/2013 => 30/11/2013 = 0 months
  • 01/01/2013 => 31/12/2013 = 11 months
  • 31/01/2011 => 28/02/2011 = 0 months
  • 01/09/2009 => 01/05/2010 = 8 months
  • 01/01/2013 => 31/03/2013 = 2 months
  • 15/02/2013 => 15/04/2013 = 2 months
  • 01/02/1985 => 31/12/2013 = 10 months

  • 01/02/2016 => 01/03/2016 = 1 months
  • 01/02/2016 => 01/04/2016 = 2 months
  • 01/11/2013 => 30/11/2013 = 0 months
  • 01/01/2013 => 31/12/2013 = 11 months
  • 31/01/2011 => 28/02/2011 = 1 months
  • 01/09/2009 => 01/05/2010 = 8 months
  • 01/01/2013 => 31/03/2013 = 2 months
  • 15/02/2013 => 15/04/2013 = 2 months
  • 01/02/1985 => 31/12/2013 = 346 months

PHPExcel แสดงตัวเลขเป็นวันที่

×Warning! ใช้วิธีในบทความ PHPExcel: จัดรูปแบบ format ข้อมูล จะดีกว่าวิธีนี้

เขียนระบบส่งออกข้อมูล ทดสอบดูโดยใช้ LibreOffice Calc ปกติดี แต่ใน Microsoft Excel 2013 กลับแสดงตัวเลขทั้งหมดเป็นวันที่

งานรีบ (ตลอด) ไม่อยากเขียนเงื่อนไขให้เช็กว่าช่องนี้คอลัมน์นั้นเป็นตัวหนังสือ หรือว่าตัวเลข ก็ตั้งให้ที่ column เป็น text ไปเลยละกัน[code language=”php” title=”PHPExcel_writer_as_text_all_field.php”]
<?php

error_reporting(E_ALL);
ini_set(‘display_errors’, true);
ini_set(‘display_startup_errors’, true);

include ‘config.php’;

/* PHPExcel_IOFactory – Reader */
include ‘../vendor/phpoffice/phpexcel/Classes/PHPExcel.php’;

$objPHPExcel = new PHPExcel();

/* Set default style */
$defaultStyle = $objPHPExcel->getDefaultStyle();

$defaultStyle->getFont()
->setName(‘Arial’)
->setSize(11);

$defaultStyle->getNumberFormat()
->setFormatCode(‘yyyy-mm-dd’);

/* Set document properties */
$title = ‘Subscription_Datas_’ . date(‘Y-m-d_H-i’);
$objPHPExcel->getProperties()->setCreator(‘Pitt Phunsanit’)
->setCategory(‘Subscription Datas’)
->setDescription($title)
->setKeywords(‘Subscription Datas ‘ . date(‘Y-m-d’))
->setSubject($title)
->setTitle($title);

/* create new sheet */
$objWorkSheet = $objPHPExcel->getActiveSheet();
$objWorkSheet->setTitle(‘Subscription Datas’);

$objWorkSheet->setCellValue(‘A1’, ‘subscription_id’);
$objWorkSheet->setCellValue(‘B1’, ‘first name’);
$objWorkSheet->setCellValue(‘C1’, ‘last name’);
$objWorkSheet->setCellValue(‘D1′, ’email’);
$objWorkSheet->setCellValue(‘E1’, ‘mobile’);
$objWorkSheet->setCellValue(‘F1’, ‘major’);
$objWorkSheet->setCellValue(‘G1’, ‘congratulations year’);
$objWorkSheet->setCellValue(‘H1’, ‘date create’);

$sql = "SELECT *
FROM subscriptions
WHERE enable = 1
ORDER BY sort ASC, skill_id ASC;";
$query = $conn->prepare($sql);
$query->execute();
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$colNo = -1;
$rowNo = 1;

foreach ($results[0] as $key => $value) {
$colNo++;
$colStrings[$key] = $column = PHPExcel_Cell::stringFromColumnIndex($colNo);
$objWorkSheet->setCellValue($column . $rowNo, $key);
}
$objPHPExcel->getActiveSheet()->getStyle(‘A1:’ . $column . ‘1’)->getFont()->setBold(true);

foreach ($results as $result) {
$rowNo++;
foreach ($result as $key => $value) {
$objWorkSheet->setCellValueExplicit($colStrings[$key] . $rowNo, $value, PHPExcel_Cell_DataType::TYPE_STRING);
}
}

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, ‘Excel2007’);
header(‘Content-Type: application/vnd.ms-excel’);
header(‘Content-Disposition: attachment; filename="’ . $title . ‘.xlsx"’);
header(‘Cache-Control: max-age=0’);
header(‘Cache-Control: no-store, no-cache, must-revalidate, max-age=0’);
header(‘Cache-Control: post-check=0, pre-check=0’, false);
header(‘Pragma: no-cache’);
$objWriter->save(‘php://output’);[/code]

ที่แก้จริงๆ คือ ใช้[code language=”php” title=”PHPExcel_Cell_DataType::TYPE_STRING”]$objWorkSheet->setCellValueExplicit($colStrings[$key] . $rowNo, $value, PHPExcel_Cell_DataType::TYPE_STRING);[/code]กรอกข้อมูลพร้อมกำหนดชนิดของข้อมูลใน column จะ formula, inline, null, numeric, string ที่ต้องการ จะใช้ชนิดอื่นก็ใช้ตามคู่มือ Class: PHPExcel_Cell_DataType

YII2: formatter

ถ้าทำระบบที่ออกแบบให้ลูกค้าจากต่างประเทศมาใช้งานได้อย่างสดวก อาจจะต้องเปลี่ยนการแสดงผลให้ตามความเคยชินของลูกค้า อย่างเช่น วันที่ คนไทยจะใช้ d/M/Y คือ วันที่/เดือน/ปี แต่คนอเมริกันจะใช้ M/d/Y คือ เดือนมาก่อน/วันที่/ปี แต่อัฟริการใต้และฐานข้อมูลส่วนใหญจะเก็บแบบ Y-M-d คือ ปี-เดือน-วัน จะสามารเรียงข้อมูลตามวันเวลา ได้ง่ายที่สุด แต่ไม่นิยมใช้กันในชีวิตประจำวัน ซึ่งถ้าไม่สังเกตุดีๆ อาจจะเข้าใจกันผิดได้

Yii2 ได้อำนวยความสดวกในส่วนนี้ให้โดยเพียงแค่ไปที่ไฟล์ \common\config\main.php เพิ่ม[code language=”php” title=”main.php”]
‘components’ => [

‘formatter’ => [
‘currencyCode’ => ‘THB’,
‘dateFormat’ => ‘d/M/Y’,
‘datetimeFormat’ => ‘d/M/Y H:i:s’,
‘defaultTimeZone’ => ‘Asia/Bangkok’,
‘locale’ => ‘th-TH’,
‘sizeFormatBase’ => 1024,
‘timeFormat’ => ‘H:i:s’,
],

[/code] ก็จะสามารถใช้ความสามารถนี้ได้

เริ่มจากวันและเวลากันก่อน[code language=”php” title=”วันที่และเวลา”]
$date = date(‘c’);
echo ‘<br>$date = ‘.$date,
‘<br>’,
‘<br>dateFormat = ‘.Yii::$app->formatter->dateFormat,
‘<br>asDate($date) = ‘.Yii::$app->formatter->asDate($date),
‘<br>asDate($date, \’Y-M-d\’) = ‘.Yii::$app->formatter->asDate($date, ‘Y-M-d’),
‘<br>’,
‘<br>datetimeFormat = ‘.Yii::$app->formatter->datetimeFormat,
‘<br>asDatetime($date) = ‘.Yii::$app->formatter->asDatetime($date),
‘<br>asTimestamp($date) = ‘.Yii::$app->formatter->asTimestamp($date);
[/code]ผลที่ได้คือ
$date = 2016-05-26T19:41:22+02:00

dateFormat = d/M/Y
asDate($date) = 26/5/2016
asDate($date, ‘Y-M-d’) = 2016-5-26

datetimeFormat = d/M/Y H:i:s
asDatetime($date) = 26/5/2016 19:41:22
asTimestamp($date) = 1464284482

เงินก็สามารถเปลี่ยนการแสดงผลได้เหมือนกัน[code language=”php” title=”สกุลเงิน”]
$value = 910097693;
echo ‘<br>$value = ‘.$value,
‘<br>’,
‘<br>currencyCode = ‘.Yii::$app->formatter->currencyCode,
‘<br>asCurrency($value) = ‘.Yii::$app->formatter->asCurrency($value),
‘<br>asCurrency($value, \’USD\’) = ‘.Yii::$app->formatter->asCurrency($value, ‘USD’);
[/code]ผลที่ได้คือ
$value = 910097693

currencyCode = THB
asCurrency($value) = THB 910,097,693.00
asCurrency($value, ‘USD’) = USD 910,097,693.00

ขนาดไฟล์ก็สามารถแปลงได้เหมือนกัน[code language=”php” title=”ขนาดไฟล์”]
$value = 910097693;
echo ‘<br>$value = ‘.$value,
‘<br>’,
‘<br>sizeFormatBase = ‘.Yii::$app->formatter->sizeFormatBase,
‘<br>asSize($value) = ‘.Yii::$app->formatter->asSize($value),
‘<br>asShortSize($value) = ‘.Yii::$app->formatter->asShortSize($value),
‘<br>asSize($value, 4) = ‘.Yii::$app->formatter->asSize($value, 4);
[/code]ผลที่ได้คือ
$value = 910097693

sizeFormatBase = 1024
asSize($value) = 867.94 mebibytes
asShortSize($value) = 867.94 MiB
asSize($value, 4) = 867.9368 mebibytes

อ่านเพิ่มเติม

Import วันที่โดย PHPExcel

ใช้ PHPExcel ดึงข้อมูลออกมา แต่ไม่สามารถ insert เข้า database ได้เลย ลอง debug เอา query string ออกมาดูก็เห็นสาเหตุ เพราะวันที่โดนแปลงจาก 1982-08-05 ไปเป็นตัวเลขประมาณ 3455 ทุก row เลย พอเข้า sql server มันก็ฟ้องมาว่าไม่ใช่วันที่นะ

หาเจอในเน็ต how to get date from excel using PHPExcel library แล้วก็หลายๆที่ ก็ใช้วิธี[code language=”php”]
$cell = $objWorksheet->getCell(‘A2’);
$value = trim($cell->getValue());
/* detect if the cell value is formated to date or not */
if (\PHPExcel_Shared_Date::isDateTime($cell)) {
$value = date(‘Y-m-d’, \PHPExcel_Shared_Date::ExcelToPHP($value));
}
[/code]แต่ผลที่ได้ก็เหมือนเดิม

เกือบจะยอมแพ้แล้วจน ไปเจอคนจุดประเด็นว่า isDateTime มันตรวจโดยใช้ format mm-dd-yyyy ใน PHPExcel detect if the cell value is formated to date or not ลองเทสดูก็จริง เพราะเดิมใช้เป็น format yyyy-mm-dd ลองเปลี่ยนเป็น mm-dd-yyyy ดู สามารถดึงออกมาเป็นวันที่แล้ว ไม่ใช้ int เหมือนเดิม

เพราะว่า sql server มันใช้รูปแบบ yyyy-mm-dd และไม่อยากจะเปลี่ยนไปเปลี่ยนมา เรียงตาม ปี เดือน วัน มันดูง่ายดีแล้ว วันไหนก่อนหลัง ก็ลองหาทางดู จะเปลี่ยนคอนฟิกใหม่ ให้ใช้วันที่แบบ yyyy-mm-dd โดยเพิ่ม[code language=”php” title=”PHPExcel 1=Date 2=Format”]
$objPHPExcel->getDefaultStyle()->getNumberFormat()
->setFormatCode(\PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);
[/code] โดยมีรูปแบบอื่นๆ ให้เลือกคือ Class: PHPExcel_Style_NumberFormat

ทดลองนำเข้าข้อมูลอีกครั้ง สามารถนำเข้าข้อมูลได้โดยไม่มีปัญหาแล้ว

หล้งจากแก้ข้อมูลแล้วต้องแน่ใจว่าใส่ข้อมูลถูก format เป็น yyyy-mm-dd จริงๆ เพราะว่าตอนเทสเจอใส่ 10/09/1987 มา ค่า value ก่อนแปลงได้ -2208211200 แทนที่จะเป็น 143856000 และหลังแปลงได้ปี 2036-02-16 ไม่ใช่ปี 1987 วันที่มันจะผิดไปหมดเลยครับ อาจจะใช้[code language=”php”]
if (!preg_match(‘/^(19|20)\d\d[\-\/.](0[1-9]|1[012])[\-\/.](0[1-9]|[12][0-9]|3[01])$/’, $value)) {
$this->error = true;

$cell->setValue(‘Your date "’. $cell->getValue().’" does not match the YYYY-MM-DD required format.’);
$objWorksheet->getStyle($coordinate)->applyFromArray($this->stylesError);
}
[/code]

อ่านเพิ่มเติม อ่านข้อมูลจาก excel

คุมการแสดงผลตามเวลา

ตัวอย่าง query กำหนดเวลาแสดงผลของ mysql ให้แสดง ไม่แสดงตามเวลาที่กำหนด โดยยูเซอร์เลือกที่จะใส่ไม่ใส่ time, expire, start, end ก็ได้ เช่น จะแสดงหลังวันที่ xxx ไปตลอดกาลก็ใส่แต่วันที่เริ่มต้น จะแสดงจนถึงวันที่เท่าไหร่ก็ใส่เฉพาะวันที่สิ้นสุด จะแสดงในช่วงเวลาก็ใส่ทั้งคู่ กลับกัน ไม่ใส่ทั้งคู่ก็เหมือนไม่กำหนดเงือนไขอะไรเลย[sourcecode language=”sql”]
SELECT *,
CASE
WHEN datePublish != ‘0000-00-00’
AND dateExpire != ‘0000-00-00’ THEN
IF(datePublish <= Curdate()
AND dateExpire >= Curdate(), true, false)
WHEN datePublish != ‘0000-00-00’ THEN
IF(datePublish <= Curdate(), true, false
)
WHEN dateExpire != ‘0000-00-00’ THEN
IF(dateExpire >= Curdate(), true, false)
ELSE true
END AS published
FROM pp_contents
HAVING published = true[/sourcecode]

คำนวนวันที่ใน PHP

วันนี้เข้าไปแก้งานบนระบบเก่าๆ เลยขอเขียนเตือนความจำเป็นอนุสรณ์ไว้ซะหน่อย
ปัจจุบัน ถ้าต้องการหาวันที่ย้อนหลังจะเขียนตามตัวอย่าง
[sourcecode language=”php”]
$date = new DateTime(‘2012-07-09’);
$date->sub(new DateInterval(‘P3D’));
echo $date->format(‘Y-m-j’);
[/sourcecode]
ซึ่งถ้าใช้กับ php ตัวที่เก่ากว่า 5.3 ลงมาจะมี error
Fatal error: Call to undefined method DateTime::sub() in
แก้ได้โดยไปเขียนแบบเก่าๆ คือ
[sourcecode language=”php”]
$date = strtotime(‘-3 day’ ,strtotime(‘2012-07-09’)) ;
echo date(‘Y-m-j’ ,$date);
[/sourcecode]
ดูเพิ่มเติม

วันและเวลาในจาว่าสคริปต์ : เพิ่ม ลด วัน เวลา

ถ้าอยากรู้ว่าอีก 3 วันข้างหน้า เป็นวันอะไร วันที่เท่าไหร่ เราสามารถใช้วิธีเพิ่มค่าให้ ออบเจ็ควันที่และเวลาได้
หลักการคือ อยากจะเพิ่ม หรือ ลดอะไร ก็เรียกเมทอด มาแสดงค่า แล้ว บวก หรือ ลบ จากนั้นเปลี่ยนกลับเป็นออบเจ็ควันที่และเวลาอีกครั้ง[sourcecode language=”javascript”]var dateTimeObj = new Date();
document.writeln(‘<br /> วันเวลาปัจจุบัน ‘+dateTimeObj.toString() );
dateTimeObj.setDate(dateTimeObj.getDate() + 1);
document.writeln(‘<br /> เพิ่มอีก 1 วัน ‘+dateTimeObj.toString() );
dateTimeObj.setDate(dateTimeObj.getDate() + 7);
document.writeln(‘<br /> เพิ่มอีก 7 วัน ‘+dateTimeObj.toString() );
dateTimeObj.setMonth(dateTimeObj.getMonth() + 1);
document.writeln(‘<br /> เพิ่มอีก 1 เดือน ‘+dateTimeObj.toString() );
dateTimeObj.setYear(dateTimeObj.getFullYear() + 1);
document.writeln(‘<br /> เพิ่มอีก 1 ปี ‘+dateTimeObj.toString() );[/sourcecode]ดูเพิ่มเติม

วันและเวลาในจาว่าสคริปต์

การทำงานเกี่ยวกับ วันที่และเวลาบน จาว่าสคริปต์ ก่อนอื่นเราต้องสร้างออบเจ็ควันที่และเวลาขึ้นมาก่อนโดยประกาศ new Date()
ประกาศได้หลายรูปแบบคือ
• dateTimeObj = new Date() จะได้วันเวลาปัจจุบัน
• dateTimeObj = new Date(1297876193291) มิลลิวินาทีโดยนับหนึ่งตั้งแต่วันที่ 1970/01/01
• dateTimeObj = new Date(‘February17, 2011 21:13:00’) ( เวลาจะใส่หรือไม่ก็ได้ครับ )
• dateTimeObj = new Date(2011,1,17,21,13,0) รูปแบบคือ ปีค.ศ. ,เดือน – 1 ,วันที่ ,ชั่วโมง (24 ชั่วโมง) ,นาที วินาที ( เวลาจะใส่หรือไม่ก็ได้ครับ )
เมื่อได้ออบเจ็ควันที่และเวลา ( ในตัวอย่างคือ dateTimeObj ) มาแล้วสามารถ เมทอดแสดงค่ารูปแบบต่างๆ เช่น
[sourcecode language=”javascript”]
alert (‘วันที่คือ ‘ + dateTimeObj.getDate() + ‘/’ + dateTimeObj.getMonth() + ‘/’ + dateTimeObj.getFullYear() );
[/sourcecode]
เมทอดที่ใช้บ่อย เช่น

getDate() วันที่ ( 1 – 31 )
getDay() ลำดับของวัน ( 0 – 6 )
getFullYear() ปี 4 หลัก
getHours() ชั่วโมง ( 0 – 23 )
getMilliseconds() มิลลิวินาที ( Millisecond ) ( 0 – 999 )
getMinutes() นาที ( 0 – 59 )
getMonth() เดือน ( 0 – 11 )
getSeconds() วินาที ( 0 – 59 )
toString() Thu Feb 17 2011 00:30:21 GMT+0700 (SE Asia Standard Time)

จะเห็นว่าส่วนใหญ่จะเริ่มต้นโดยนับจาก 0 อันนี้ทำให้ต้องระมัดระวังในการใช้งาน เช่น ถ้าจะหาความแตกต่างระหว่างวันที่ 2 วันคือ
[sourcecode language=”javascript”]
today = new Date();
dateTimeObj = new Date(2011,1,17,21,13,0);
/* 17/02/2011 13.00 น. */
difference = dateTimeObj – today;
days = Math.round( difference / (1000*60*60*24) );
/* ( 17/02/2011 – วันนี้ ) หารด้วย ( มิลลิวินาที x วินาที x นาที x วัน ) จากนั้นปัดเศษขึ้น */
alert(‘วันต่างกัน ‘ + days + ‘ วัน’ );
[/sourcecode]
สังเกตว่า ในหลายๆ จุด ค่าตัวเลขจะน้อยกว่าที่เราใช้ตามปกติอยู่ 1 ค่า
ดูเพิ่มเติม