[Php] '일반적인 주'(일요일에서 토요일까지)에 변환 된 시간대를 표시하는 방법은 무엇입니까?


Answers

평일의 진공 상태를 고려할 때 질문에 의미가 없습니다. 이 평일은 실제 전환 일이어야합니다. 시간 변환 규칙이 연도 (DST)와 연도를 통해 변경되기 때문입니다 (정치인은 때때로 시간대 및 / 또는 DST 시작 / 종료 날짜를 변경합니다).

즉, 8 월 첫 주에 사용할 수있는 주간 사용 계획이 있다고 가정 해 봅시다. 여기에 8 월 1 일부터 8 월 7 일까지의 주로 정의됩니다.

<?php
$tz1 = new DateTimezone("Asia/Calcutta");
$indiaAvail = array(
    new DatePeriod(new DateTime("2010-08-01 10:00:00", $tz1),
        new DateInterval("PT2H15M"), 1),
    new DatePeriod(new DateTime("2010-08-07 03:00:00", $tz1),
        new DateInterval("PT8H"), 1),
);


$tz2 = new DateTimezone("America/New_York");
//convert periods:
$times = array_map(
    function (DatePeriod $p) use ($tz2) {
       $res = array();
       foreach ($p as $d) {
           $res[] = $d->setTimezone($tz2);
       }
       return $res;
    },
    $indiaAvail
);

$res = array();
foreach ($times as $t) {
    $t1 = reset($t);
    $t2 = next($t);
    if ($t1->format("d") == $t2->format("d")) {
        $res[$t1->format("l")][] = $t1->format("g:ia") . " to ".
            $t2->format("g:ia");
    }
    else {
        $res[$t1->format("l")][] = $t1->format("g:ia") . " to 11:59pm";
        $res[$t2->format("l")][] = "12:00am to ". $t2->format("g:ia");
    }
}

print_r($res);

주는

Array
(
    [Sunday] => Array
        (
            [0] => 12:30am to 2:45am
        )

    [Friday] => Array
        (
            [0] => 5:30pm to 11:59pm
        )

    [Saturday] => Array
        (
            [0] => 12:00am to 1:30am
        )

)

평일 같은 바구니에 평일을 넣을 수는 있지만 실제로는 요일을 명시하지 않고 (또는 "토요일 (1 주일 후)"및 "토요일 (주일)"을 추가하지 않아도되는 것을 방지 할 수있는 방법은 없습니다.) 그래도 네가 원하는거야.

Question

우리는 한 명의 사용자가 다음과 같이 모든 주 동안 자신의 "일반적인 가용성"을 설정할 수있는 스케줄링 응용 프로그램을 개발 중입니다.

Sunday | Monday | ... | Friday | Saturday

인도의 한 사람에게 자신의 "유용성"을 나타낼 것을 요청할 때, 우리는 다음과 같이 값을 드롭 다운하여 선택하도록 요청합니다 :

12:00am
12:30am
01:00am
...
11:30pm

"출발"시간 (시작)과 "종료"시간 (종료)을 모두 선택하도록 요청합니다.

우리가 데이터베이스에서 저장하는 것은이 값들뿐입니다 (다음 예제 참조).

user_id avail_day   from        to  
1     Sunday        12:00:00    12:15:00
2     Monday        12:00:00    12:15:00

본질적으로 다음과 같이 보입니다 (로컬 시간대에서)

(A)
Sunday | Monday | ... | Friday | Saturday
-----------------------------------------
       |        |     |        | 8:30am to 10:30am

별도의 정보로서, 현재 GMT + 5:30 시간 인 IST (Indian Standard Time)에서 일하기로 선택한 것을 알고 있으므로, 그가 선택한 값이 현재 그가 속한 시간대에 해당한다고 가정 할 수 있습니다 에서.

자, 현재 GMT - 4 시간 (EDT) 인 동부 해안에있는 사람 B의 경우 이번에는 실제로

Friday, 23:00:00 to Saturday, 01:00:00

다음을 수행하는 방법을 파악하는 데 도움이 필요합니다.
(a) IST의 사람 A의 이전 "텍스트 값"을 EST 사람의 로컬 값으로 변환합니다 (주와 시간을 TEXT 값으로 만 알 수 있음)
(b) 그런 다음 일요일에 시작하여 토요일에 끝나는 "표준 주"에 표시하는 방법을 알아야합니다. 우리가 원하는 것은 다음과 같아야합니다 :

(B)
Sunday | Monday | ... |       Friday       |      Saturday
--------------------------------------------------------------
       |        |     | 11:00pm to 12:00am | 12:00am to 1:00am

(A)를 (B)로 변환하는 현명한 방법은 무엇입니까?

Artefacto 의 코드를 일반적인 함수 (Revision 2)로 만들었습니다.

// This function should be used relative to a "from_date"
// The $from_timebegin and $from_timeend MUST be for the same day, not rolling over to the next
function shift_timezones_onweek3($from_timezone, $from_date, $from_timebegin, $from_timeend, $to_timezone)
{
    $tz1 = new DateTimezone($from_timezone);

    $datetime1 = new DateTime("$from_date $from_timebegin", $tz1);
    $datetime2 = new DateTime("$from_date $from_timeend", $tz1);

    $interval = $datetime1->diff($datetime2);

    $indiaAvail = array(
        array($datetime1, $datetime2)
    );


    $tz2 = new DateTimezone($to_timezone);
    //convert periods:
    $times = array_map(
        function (array $p) use ($tz2) {
           $res = array();
           foreach ($p as $d) {
               $res[] = $d->setTimezone($tz2);
           }
           return $res;
        },
        $indiaAvail
    );

    $res = array();
    foreach ($times as $t) {
        $t1 = reset($t);
        $t2 = next($t);
        if ($t1->format("d") == $t2->format("d")) {
            $res[$t1->format("l")][] = $t1->format("g:ia") . " to ".
                $t2->format("g:ia");
        }
        else {
            $res[$t1->format("l")][] = $t1->format("g:ia") . " to 11:59pm";
            $res[$t2->format("l")][] = "12:00am to ". $t2->format("g:ia");
        }
    }

    return $res;
}



이건 어때:

  • 사용자에게 시간대를 제공하도록 요청합니다 (IP 주소를 기반로 사용자의 위치를 ​​파악하여 감지 할 수도 있지만 사용자는 여전히이를 변경하려고 할 수 있습니다)
  • 제공된 시간을 웹 서버의 시간으로 변환하고 저장하십시오.
  • 시간을 표시 할 때 보는 사용자의 시간대로 변환합니다.

Pear :: Date 패키지는 다음 작업을 수행하는 데 도움이 될 수 있습니다.
http://www.go4expert.com/forums/showthread.php?t=3494

희망이 도움이 마누엘




PHP의 기본 제공 DateTime 클래스 를 사용하여 시간대 변환을 수행하십시오. UTC로 데이터를 데이터베이스에 저장하십시오. 표준 주간 일정을 표시 할 때 현지 시간대를 사용하십시오. 시간대 차이 ± 23 시간을 처리하려면 변환하기 전에 DB에서 9 일 (± 1 일)을 쿼리해야합니다.

편집 : 시간을 현재 사용자의 현지 시간으로 변환하려면 각 이벤트의 시간대를 가져와야합니다. 스케줄 된 이벤트를 이벤트를 만든 사용자의 사용자 정보에 결합하십시오. 이렇게하면 사용자의 시간대로 변환 할 시간대가 생깁니다.

다음의 가짜 PHP가 표시됩니다.

 $usersTZ = new DateTimeZone('EDT');
 $now = new DateTime("now", $usersTZ);
 $today = $now->format("Y-m-d");
 $sql = "SELECT A.date, A.start, A.end, B.tz FROM schedule A JOIN users B ON (schedule.user_id = users.user_id) WHERE A.date BETWEEN '$sunday_minus_1_day' AND '$saturday_plus_1_day' ORDER BY A.date, A.start";
 foreach ($db->dothequery($sql) as $event) {
     $eventTZ = new DateTimeZone($event['tz']);
     $eventStartDate = new DateTime("$today {$event['start']}", $eventTZ);
     $eventStartDate->setTimeZone($usersTZ);
     $eventEndDate = /* do the same for the end date */
     if ($eventStartDate->format("Y-m-d") != $eventEndDate->format("Y-m-d")) {
          /* create 2 events */
     } else {
          /* save the event to list of events with the new start and end times */
     }
 }
 /* sort events, their order may be different now */

물론 TZ로 시작 및 종료 시간을 DB에 저장하고 DB가 모든 노력을 할 수 있다면 훨씬 더 간단 할 것입니다.