Wątek przeniesiony 2016-01-24 13:41 z PHP przez dzek69.

Formatowanie daty zgodnie z istniejacymi w kalendarzu

0

Witam,
mam taki problem. Napisałem 3 funkcje, które zwracają mi odpowiednio 12 liczb(miesiace), 31 liczb(dni) i lata od 1915 do teraz. Tak jak jest to zrobione przy rejesracji na facebooku. Teraz hciałbym to zapisać w bazie danych pod kolumna BirthDate. Napisałem taki kod:

public function getDate() {
    $month = $this->Month;
    return $this->Year . '-' . $month . '-' . $this->Day;
}

public function getDbFormatedDate() {
    $dateDeadline = date_create($this->getDate());
    return date_format($dateDeadline, 'Y-m-d');
} 

I teraz wszystko niby działa ale gdy np wybiorę date, która nie istnieje np. 31.02.2016 to zapisuje mi się 02.03.2016.</code> Albo gdy wybiorę <code>31.04.2016</code> to zapisuje mi się <code>01.05.2016. Myślałem, że można by porównać jakoś te 2 wartości czyli tą wybraną z tą która ma się zapisać i wyświetlić jakis error, że taka data nie istnieje. Ktoś ma może jakiś pomysł jak można to zrobić?

1

A nie możesz przeprowadzić walidacji?

var_dump(checkdate(2, 29, 2015)); // false
var_dump(checkdate(2, 29, 2016)); // true

Możesz też przeprowadzić uprzednią walidację po stronie klienta tzn. w momencie kiedy user wybierze rok i miesiac (zakladajac, ze masz 3 selekty: rok, miesiac, dzien) to aktualizujesz odpowiednio ilość dni w selekcie dzien. Mozesz uzyc takiej funkcji - to jest odpowiednik tego jak to robi php:

function checkdate(m, d, y) {
  return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0))
    .getDate();
}

Są również gotowe date pickery, które robią to za Ciebie :)

0

Datapicker nie wchodzi w grę. Chce to zrobić za pomocą tych dropdownlist. Ogólnie jest to napisane w yii2. I wszystko juz działa tylko zostało mi uporać się z tym bugiem. Chciałbym to zrobić jakoś tak, że po wybraniu daty sprawdzić czy się zapisała ta, która wybrałem czy jest to inna, jesli inna, tzn ze ta która wybrałem nie istnieje w wtedy wyrzucic błąd, że taka data nie istnieje. Tylko nie mam pomysłu jak to złapać.

1

@zwiro przecież Ci dałem 3 rozwiązania post wyżej -.-
Możesz przeprowadzić walidację już u klienta i wyświetlić np. alert, że ten dzień nie istnieje. Możesz również dynamicznie pokazywać i ukrywać dni, które nie istnieją dla danego miesiąca zakładając, że rózniące się to 30/31 i 28/29 lutego.

Możesz również to zrobić po stronie serwera i po wysłaniu formularza zwrócić błąd, że podana data jest nieprawidłowa.

Nie musisz jej zapisywać. Jeżeli jest błędna to po cholerą ją wgl zapisywać. Po prostu syp błędami, że user jest idiotą i podał 31 lutego. Gdzie leży problem?

0

ale do tej funkcji checkdate musze podac 3 argumenty a jest tak funcja, ktora sprawdza to z jednego argumentu w postaci calej daty? np

$data='2014-10-10' ;
checkdata($data);
1

Sam sobie tworzysz dodatkowe problemy ;) Skoro masz trzy osobne selekty dla każdej części daty to przecież w $_POST bedziesz mial osobno miesiac, osobno dzien i osobno rok. Wydaje mi sie, ze nie ale mozna to latwo zaimplementowac. Poszukaj jak zrobic ze stringa obiekt daty jezeli Ci to tak bardzo potrzebne.

0

Tylko, że to jest tak, że np miesiąc pobieram z tablicy i np styczen nie jest tutaj w posataci 01 tylko 1 dopiero później ja to konwertuję na date i zmienia mi się ta 1 na 01 ale spróbuję zaraz użyć Twojej funkcji i się zobaczy.

1

@zwiro kombinujesz jak koń pod górę. W jakiej postaci byś tego nie miał to nie stwarza problemu. Po pierwsze możesz zmieć funkcję generującą Ci select, żebyś miał liczby Ci potrzebne. Ktoś klika submit i masz w poście:

// var_dump($_POST);
array(
	//...
	"birthday_year" => 1994,
	"birthday_month" => 10,
	"birthday_day" => 15,
	//..
);

Teraz chcesz sprawdzic, czy ta data jest prawidłowa, więc sobie robisz:

$data = $_POST;
$isValidDate = checkdate($data['birthday_day'], $data['birthday_month'], $data['birthday_year']);

if(!$isValidDate) {
	//throw new YUDontKnowGregorianCalendarException...
}

// mktime zwóci Ci ms, dlatego formatujemy to do Y-m-d i otrzymujemy stringa.. którego możemy wpakować do bazy
$data['birthday_date'] = date('Y-m-d', mktime(0, 0, 0, $data['birthday_day'], $data['birthday_month'], $data['birthday_year']));

var_dump($data['birthday_date']); // 1994-10-15 

Tu nie ma żadnej filozofii :D

0

Nom chyba już działa tak jak chciałem, dzięki za pomoc :)

0

Miałbym jeszcez jedno pytanko;p Chciałbym zablokować możliwość wybrania daty poźniejszej od dzisiaj. Wyczytałem ze aby porównac daty nalezy uzyc funkcji strtotime(która dodaje sekundy dzieki ktorym mozena porównać) ale próbuje to zrobić i nie za bardzo wiem w którym miejscu to zrobić. Mam taki kod i to nie działa:

 public function getDate() {
    $month = $this->month;
    return $this->year . '-' . $month . '-' . $this->day;
}
 
public function getDbFormatedDate() {
    if (checkdate($this->month, $this->day, $this->year) || $this->strtotime(getDate())>strtotime(date("Y-m-d"))){
    $dateDeadline = date_create($this->getDate());
    $this->BirthDate= date_format($dateDeadline, 'Y-m-d');
    Yii::$app->session->setFlash('success', Yii::t('app', 'Zmiany w profilu zostały zapisane'));
    }else
        Yii::$app->getSession()->setFlash('error', 'nie ma takeij daty');
}  

1 użytkowników online, w tym zalogowanych: 0, gości: 1