php แปลงวันที่และเวลาเป็น UTC


90

ฉันต้องการวิธีง่ายๆในการแปลงการประทับเวลาวันที่เป็น UTC (จากเขตเวลาใดก็ตามที่เซิร์ฟเวอร์อยู่) หวังว่าจะได้รับโดยไม่ต้องใช้ไลบรารีใด ๆ

คำตอบ:


30

ลองgetTimezone และ setTimezoneดูตัวอย่าง

(แต่นี่ใช้คลาส)

อัพเดท:

หากไม่มีชั้นเรียนใด ๆ คุณสามารถลองสิ่งนี้:

$the_date = strtotime("2010-01-19 00:00:00");
echo(date_default_timezone_get() . "<br />");
echo(date("Y-d-mTG:i:sz",$the_date) . "<br />");
echo(date_default_timezone_set("UTC") . "<br />");
echo(date("Y-d-mTG:i:sz", $the_date) . "<br />");

หมายเหตุ: คุณอาจต้องตั้งค่าเขตเวลากลับไปที่เดิมด้วย


56
คุณควรใช้gmdateแทนการเปลี่ยนเขตเวลาเริ่มต้นเป็น UTC เนื่องจากgmdateใช้ UTC โดยอัตโนมัติ
โผล่

30
-1 เนื่องจากคุณไม่ต้องการเปลี่ยนเขตเวลาเริ่มต้นทั่วโลกสำหรับสิ่งนี้ มันแค่ขอผลข้างเคียงโดยไม่ได้ตั้งใจ
Ward Bekker

@Phill 'sz' ที่นี่คืออะไร?
Shahid Karimi

2
ฉันคิดว่าควรเป็น "Ym-dTG ... " แทน "Yd-mTG ... "
Alex Angelico

มันไม่ได้ผลสำหรับฉันในโครงการ laravel กลับมาในวันเดียวกัน
Dharmender Tuli

109

ใช้strtotimeเพื่อสร้างการประทับเวลาจากสตริงที่กำหนด (ตีความว่าเป็นเวลาท้องถิ่น) และใช้gmdateเพื่อรับเป็นวันที่ UTC ที่จัดรูปแบบไว้

ตัวอย่าง

ตามที่ร้องขอนี่คือตัวอย่างง่ายๆ:

echo gmdate('d.m.Y H:i', strtotime('2012-06-28 23:55'));

2
@cherouvim ไม่คิดว่ามันจำเป็น แต่เพิ่มเข้าไปอีก ... หวังว่ามันจะช่วยได้
โผล่

5
gmdate () เป็นหนึ่งในฟังก์ชัน PHP ที่ฉันหวังว่าฉันจะสะดุดเมื่อนานมาแล้ว nl2br ใคร?
Charlie Schliesser

1
GMT และ UTC ไม่เหมือนกันเสมอไป
Jay Sheth

@JaySheth ในทางปฏิบัติ UTC และ GMT มีความหมายเหมือนกัน
โผล่

1
@poke GMT เคารพเวลาออมแสง UTC ไม่ได้และนั่นคือเหตุผลที่ใช้ดังนั้นคุณจึงไม่ต้องแยกปัจจัยอื่นใดใน
Necro

72

ใช้ DateTime:

$given = new DateTime("2014-12-12 14:18:00");
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 14:18:00 Asia/Bangkok

$given->setTimezone(new DateTimeZone("UTC"));
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 07:18:00 UTC

คำถามระบุว่าแปลงการประทับเวลาเป็นการประทับเวลาและ DateTime ไม่ยอมรับการประทับเวลาเป็นอินพุต คุณจะต้องแปลงเป็นสตริงจากนั้นจึงแปลงกลับ
felwithe


14

หากคุณมีวันที่ในรูปแบบนี้ YYYY-MM-HH dd: mm: ss คุณสามารถหลอก php ได้โดยการเพิ่ม UTC ต่อท้าย "สตริงวันที่และเวลา" ของคุณและใช้ strtotime เพื่อแปลง

date_default_timezone_set('Europe/Stockholm');
print date('Y-m-d H:i:s',strtotime("2009-01-01 12:00"." UTC"))."\n";
print date('Y-m-d H:i:s',strtotime("2009-06-01 12:00"." UTC"))."\n";

สิ่งนี้จะพิมพ์สิ่งนี้:

2009-01-01 13:00:00
2009-06-01 14:00:00

และอย่างที่คุณเห็นมันดูแลปัญหาเวลาออมแสงเช่นกัน

วิธีแก้แปลก ๆ .... :)


ฉันไม่เข้าใจจริงๆว่าทำไม OP ถึงไม่เลือกคำแนะนำของคุณ :D
php_nub_qq

@php_nub_qq อาจเป็นเพราะมันทำงานโดยการเปลี่ยนเขตเวลาสำหรับสคริปต์ทั้งหมดซึ่งอาจไม่เป็นที่ต้องการและอาจส่งผลที่ไม่ได้ตั้งใจ
felwithe

@felwithe มันจะไม่ถ้าคุณข้ามบรรทัดแรกซึ่งเป็นเพียงการสาธิต
php_nub_qq

11

แปลงสตริงเขตเวลาท้องถิ่นเป็นสตริง UTC
เช่นเขตเวลานิวซีแลนด์

$datetime = "2016-02-01 00:00:01";
$given = new DateTime($datetime, new DateTimeZone("Pacific/Auckland"));
$given->setTimezone(new DateTimeZone("UTC"));
$output = $given->format("Y-m-d H:i:s"); 
echo ($output);
  • NZDT: UTC + 13: 00
    ถ้า $ datetime = "2016-02-01 00:00:01", $ output = "2016-01-31 11:00:01";
    ถ้า $ datetime = "2016-02-29 23:59:59", $ output = "2016-02-29 10:59:59";
  • NZST: UTC + 12: 00
    ถ้า $ datetime = "2016-05-01 00:00:01", $ output = "2016-04-30 12:00:01";
    ถ้า $ datetime = "2016-05-31 23:59:59", $ output = "2016-05-31 11:59:59";

https://en.wikipedia.org/wiki/Time_in_New_Zealand


6

หากคุณไม่สนใจที่จะใช้คลาสDateTimeของ PHP ซึ่งมีให้ตั้งแต่ PHP 5.2.0 มีหลายสถานการณ์ที่อาจเหมาะกับสถานการณ์ของคุณ

  1. หากคุณมี$givenDtวัตถุ DateTime ที่คุณต้องการแปลงเป็น UTC สิ่งนี้จะแปลงเป็น UTC:

    $givenDt->setTimezone(new DateTimeZone('UTC'));
    
  2. หากคุณต้องการต้นฉบับใน$givenDtภายหลังคุณอาจต้องการโคลนออบเจ็กต์ DateTime ที่กำหนดก่อนที่จะแปลงอ็อบเจ็กต์ที่ถูกโคลน:

    $utcDt = clone $givenDt;
    $utcDt->setTimezone(new DateTimeZone('UTC'));
    
  3. หากคุณมีเพียงสตริงวันที่และเวลาเช่น$givenStr = '2018-12-17 10:47:12'คุณต้องสร้างวัตถุวันที่และเวลาก่อนจากนั้นจึงแปลง โปรดทราบว่าสิ่งนี้ถือว่า$givenStrอยู่ในเขตเวลาที่กำหนดค่าไว้ของ PHP

    $utcDt = (new DateTime($givenStr))->setTimezone(new DateTimeZone('UTC'));
    
  4. หากสตริงวันที่และเวลาที่กำหนดอยู่ในบางเขตเวลาที่แตกต่างจากในการกำหนดค่า PHP ของคุณให้สร้างออบเจ็กต์วันที่และเวลาโดยระบุเขตเวลาที่ถูกต้อง (ดูรายการเขตเวลาที่ PHP รองรับ ) ในตัวอย่างนี้เราถือว่าเขตเวลาท้องถิ่นในอัมสเตอร์ดัม:

    $givenDt = new DateTime($givenStr, new DateTimeZone('Europe/Amsterdam'));
    $givenDt->setTimezone(new DateTimeZone('UTC'));
    

4

เนื่องจากstrtotimeต้องการรูปแบบอินพุตเฉพาะจึงสามารถใช้DateTime :: createFromFormatได้ (ต้องใช้php 5.3+ )

// set timezone to user timezone
date_default_timezone_set($str_user_timezone);

// create date object using any given format
$date = DateTime::createFromFormat($str_user_dateformat, $str_user_datetime);

// convert given datetime to safe format for strtotime
$str_user_datetime = $date->format('Y-m-d H:i:s');

// convert to UTC
$str_UTC_datetime = gmdate($str_server_dateformat, strtotime($str_user_datetime));

// return timezone to server default
date_default_timezone_set($str_server_timezone);

4

บางครั้งฉันใช้วิธีนี้:

// It is not importnat what timezone your system is set to.
// Get the UTC offset in seconds:
$offset = date("Z");

// Then subtract if from your original timestamp:
$utc_time = date("Y-m-d H:i:s", strtotime($original_time." -".$offset." Seconds"));

การทำงานทุก ส่วนใหญ่ของเวลา


3
สองปัญหาที่นี่ อันดับแรกคุณไม่ควรลบคุณควรบวกค่าชดเชย ประการที่สองจะใช้ไม่ได้หากเขตเวลาท้องถิ่นเป็น DST ในขณะนี้และวันที่ที่ต้องการไม่อยู่ใน DST การชดเชยจะถูกปิดภายในหนึ่งชั่วโมง หรือในทางกลับกัน ใช่มันใช้งานได้เกือบตลอดเวลา แต่ก็ไม่เสมอไป
ajon



0

ลอง

วันที่สะท้อน ('F d Y', strtotime ('2010-01-19 00:00:00'));

จะส่งออก:

19 มกราคม 2553

คุณควรเปลี่ยนเวลารูปแบบเพื่อดูผลลัพธ์อื่น ๆ


0

ฟังก์ชันนอร์มัลไลเซชันวัตถุประสงค์ทั่วไปเพื่อจัดรูปแบบการประทับเวลาจากเขตเวลาใด ๆ ไปยังเขตอื่น ๆ มีประโยชน์มากสำหรับการจัดเก็บการประทับเวลาของผู้ใช้จากเขตเวลาต่างๆในฐานข้อมูลเชิงสัมพันธ์ สำหรับการเปรียบเทียบฐานข้อมูลจะจัดเก็บการประทับเวลาเป็น UTC และใช้กับgmdate('Y-m-d H:i:s')

/**
 * Convert Datetime from any given olsonzone to other.
 * @return datetime in user specified format
 */

function datetimeconv($datetime, $from, $to)
{
    try {
        if ($from['localeFormat'] != 'Y-m-d H:i:s') {
            $datetime = DateTime::createFromFormat($from['localeFormat'], $datetime)->format('Y-m-d H:i:s');
        }
        $datetime = new DateTime($datetime, new DateTimeZone($from['olsonZone']));
        $datetime->setTimeZone(new DateTimeZone($to['olsonZone']));
        return $datetime->format($to['localeFormat']);
    } catch (\Exception $e) {
        return null;
    }
}

การใช้งาน:

$from = ['localeFormat' => "d/m/Y H:i A", 'olsonZone' => 'Asia/Calcutta'];

$to = ['localeFormat' => "Y-m-d H:i:s", 'olsonZone' => 'UTC'];

datetimeconv("14/05/1986 10:45 PM", $from, $to); // returns "1986-05-14 17:15:00"

0

หรือคุณสามารถลองสิ่งนี้:

<?php echo (new DateTime("now", new DateTimeZone('Asia/Singapore')))->format("Y-m-d H:i:s e"); ?>

สิ่งนี้จะส่งออก:

2017-10-25 17:13:20 เอเชีย / สิงคโปร์

คุณสามารถใช้สิ่งนี้ภายในแอตทริบิวต์ค่าของช่องป้อนข้อความหากคุณต้องการแสดงวันที่แบบอ่านอย่างเดียวเท่านั้น

ลบ 'e' หากคุณไม่ต้องการแสดงภูมิภาค / ประเทศของคุณ


0

ทำตามขั้นตอนเหล่านี้เพื่อรับเวลา UTCของเขตเวลาใด ๆ ที่ตั้งไว้ในระบบท้องถิ่นของผู้ใช้ (สิ่งนี้จำเป็นสำหรับเว็บแอปพลิเคชันเพื่อบันทึกเขตเวลาต่างๆเป็น UTC):

  1. Javascript (ฝั่งไคลเอ็นต์):

    var dateVar = new Date();
    var offset = dateVar.getTimezoneOffset();
    //getTimezoneOffset - returns the timezone difference between UTC and Local Time
    document.cookie = "offset="+offset;
    
  2. PHP (ฝั่งเซิร์ฟเวอร์):

    public function convert_utc_time($date)
    {
        $time_difference = isset($_COOKIE['offset'])?$_COOKIE['offset']:'';
        if($time_difference != ''){
            $time = strtotime($date);
            $time = $time + ($time_difference*60); //minutes * 60 seconds
            $date = date("Y-m-d H:i:s", $time);
        } //on failure of js, default timezone is set as UTC below
        return $date;
    }
    ..
    ..
    //in my function
    $timezone = 'UTC';
    $date = $this->convert_utc_time($post_date); //$post_date('Y-m-d H:i:s')
    echo strtotime($date. ' '. $timezone)
    

-1

เพื่อเป็นการปรับปรุงคำตอบของ Phill Pafford (ฉันไม่เข้าใจ 'Yd-mTG: i: sz' ของเขาและเขาแนะนำให้เปลี่ยนเขตเวลากลับ) ดังนั้นฉันจึงเสนอสิ่งนี้ (ฉันซับซ้อนโดยการเปลี่ยนรูปแบบ HMTL เป็นธรรมดา / ข้อความ ... ):

<?php
header('content-type: text/plain;');
$my_timestamp = strtotime("2010-01-19 00:00:00");

// stores timezone
$my_timezone = date_default_timezone_get();
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date)\n";

// changes timezone
date_default_timezone_set("UTC");
echo date("Y-m-d\TH:i:s\Z", $my_timestamp)."\t\t (ISO8601 UTC date)\n";
echo date("Y-m-d H:i:s", $my_timestamp)."\t\t (your UTC date)\n";

// reverts change
date_default_timezone_set($my_timezone);
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date is back)\n"; 
?>

2
คุณควรแก้ไขคำตอบของคุณเพื่ออธิบายว่าสิ่งนี้ช่วยปรับปรุงคำตอบของ Phil ได้อย่างไร คุณเปลี่ยนรหัสอะไรและทำไมถึงดีขึ้น
โคดี้เกรย์

การเปลี่ยนเขตเวลา PHP เริ่มต้นเพื่อแปลงการประทับเวลาสองครั้งเป็นการแฮ็กที่ใช้งานได้จริง แต่ไม่ใช่วิธีแก้ปัญหาที่สวยงาม
Coprolal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.