[TUTORIAL] Πράξεις με τον χρόνο.

Σε αυτή την περιοχή μπορείτε να βρείτε ή να αναζητήσετε πληροφορίες σχετικές με την PHP

Συντονιστές: WebDev Moderators, Super-Moderators, PHP Moderators

Απάντηση
Άβαταρ μέλους
Banavas
Script Master
Δημοσιεύσεις: 1367
Εγγραφή: 21 Νοέμ 2004 20:25
Επικοινωνία:

[TUTORIAL] Πράξεις με τον χρόνο.

Δημοσίευση από Banavas » 29 Μάιος 2010 12:05

Είναι συνηθισμένο όταν δημιουργούμε μια εφαρμογή να χρειαστεί να κάνουμε υπολογισμούς που σχετίζονται με τον χρόνο. Να συγκρίνουμε, να προσθέσουμε ή να αφαιρέσουμε ημερομηνίες, Να βρούμε πόσος χρόνος πέρασε ή απομένει από ένα γεγονός κλπ.

Παραδείγματα: Θέλουμε να ελέγξουμε αν μια δoθείσα ημερομηνία έχει περάσει ή ανήκει στο μέλλον. Θέλουμε να εμφανίσουνε σε ένα πίνακα εγγραφές των τελευταίων ν ημερών. Θέλουμε να εμφανίζουμε ένα διαφημιστικό για συγκεκρικένο χρόνο και μετά να σταματήσει η εμφάνιση αυτόματα.
Μπορώ να αναφέρω εκατοντάδες τέτοια παραδείγματα, σίγουρα και εσεις θα έχετε τα δικά σας.

Η PHP διαθέτει αρκετές συναρτήσεις σχετικές με τον χρόνο και τις ημερομηνίες από τις οποίες θα ασχοληθούμε μόνο με τρείς. Τις date(), time() mktime().
Ασ' δούμε τι κάνει η κάθε μία.

Η date(format,timestamp) μπορεί να εξάγει και να φορμάρει συγκεκριμένα στοιχεία μιας δωθείσης στιγμής. Αν παραλείψουμε το κομμάτι timestamp τοτε το αποτέλεσμα θα αφορά την τρέχουσα χρονική στιγμή δηλαδή το τώρα. Επιλέγουμε ποιά στοιχεία θέλουμε να πάρουμε από την συγκεκριμένη χρονική στιγμή και δημιουργούμε το κατάλληλο "format" για το πως θα εμφανιστούν αυτά τα στοιχεία.
Στην πράξη: η date("d/m/Y") θα εμφανίσει την τρέχουσα ημερομηνία στην συνήθη μρφή για Ελλάδα. Η date("Y-m-d") θα εμφανίσει την τρέχουσα ημερομηνία σε μορφή Unix. Μπορούμε να εξάγουμε μια πληθώρα στοιχείων με την κατάλληλη επιλογή των γραμμάτων συμβόλων που είναι προκαθορισμένα για αυτό το σκοπό.

Οι ακόλουθοι χαρακτήρες αναγνωρίζονται από το format string:
-------------------------------------------------------------
a - "am" ή "pm"
A - "AM" ή "PM"
B - Swatch Internet time
d - ημέρα του μήνα, 2 ψηφία με ηγετικά μηδενικά ("01" έως "31").
D - ημέρα της εβδομάδας, παρατίθεται με 3 γράμματα. π.χ. "Fri"
F - μήνας, παρατίθεται το πλήρες όνομα. π.χ. "January"
g - ώρα, σε 12ωρη μορφή χωρίς ηγετικά μηδενικά ("1" έως "12").
G - ώρα, 24ωρη μορφή χωρίς ηγετικά μηδενικά ("0" έως "23").
h - ώρα, 12ωρη μορφή ("01" έως "12").
H - ώρα, 24ωρη μορφή ("00" έως "23").
i - λεπτά ("00" έως "59").
I (κεφαλαίο i) - "1" εάν είναι Θερινή Ώρα, αλλιώς "0".
j - ημέρα του μήνα χωρίς ηγετικά μηδενικά ("1" έως "31").
l (μικρό 'L') - ημέρα της εβδομάδας, παρατίθεται το πλήρες όνομα. π.χ. "Friday"
L - boolean για το αν είναι δίσεκτο έτος ("0" ή "1").
m - μήνας ("01" έως "12").
M - μήνας, παρατίθεται με 3 γράμματα. π.χ. "Jan"
n - μήνας χωρίς ηγετικά μηδενικά ("1" έως "12").
O - διαφορά με την Greenwich time σε ώρες. π.χ. "+0200"
r - ημερομηνία σε μορφή RFC 822; π.χg. "Thu, 21 Dec 2000 16:01:07 +0200" (προστέθηκε στην PHP 4.0.4)
s - δευτερόλεπτα ("00" έως "59")
S - το αγγλικο τακτικό επίθεμα για την ημέρα του μήνα, 2 χρακτήτων ("st", "nd", "rd" ή "th").
t - πλήθος ημερών στο δοσμένο μήνα ("28" έως "31").
T - Η ρύθμιση ζώνης ώρας της μηχανής; π.χ. "EST" ή "MDT"
U - δυτερόλεπτα από την Unix Epoch (January 1 1970 00:00:00 GMT)
w - ημέρα της εβδομάδας, αριθμητικά ("0" (Κυριακή) to "6" (Σάββατο)).
W - πλήθος εβδομάδων του έτος κατά το ISO-8601, οι εβδομάδες αρχίζουν Δευτέρα (προστέθηκε στην PHP 4.1.0)
Y - έτος, 4 ψηφία; π.χ. "1999"
y - έτος, 2 ψηφία; π.χ. "99"
z - ημέρα του έτους ("0" έως "365").
Z - διαφορά της ζώνης ώρας σε δευτερόλεπτα ("-43200" έως "43200"). Η διαφορά για ζώνες ώρας δυτικά του UTC είναι πάντα αρνητική, και για αυτές ανατολικά του UTC πάντα θετική.

Άλλα παραδείγματα: Η date("F") θα δώσει το πλήρες όνομα του τρέχοντος μήνα (November). Πως όμως θα εμφανίσουμε το όνομα του μήνα στα Ελληνικά; Ένας εύκολος τρόπος είναι με την χρήση array με τα ονόματα των μηνών στα Ελληνικά και την date("n").

$months = Array("0","Ιανουαρίου","Φεβρουαρίου","Μαρτίου","Απριλίου","Μαίου","Ιουνίου","Ιουλίου","Αυγούστου","Σεπτεμβρίου","Οκτωβρίου","Νοεμβρίου","Δεκεμβρίου");
echo $months[date("n")];
(Εδώ το πρώτο element του array μπήκε επειδή η αρίθμηση των element ενός array ξεκινάει από το 0, ώστε να αντιστοιχηθούν οι μήνες με τον σωστό αριθμό μήνα πχ 8=Αύγουστος).

αντίστοιχα
$days = Array ("Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο") ;
echo $days[date("w")];
(Εδώ δεν χρειάζεται να βάλουμε σαν πρώτο element το "0" διότι η date("w") μας δίνει 0 για την κυριακή).

Τώρα μπορούμε να τα συνδυάσουμε και να δώσουμε την πλήρη ημερομηνία στα Ελληνικά:
echo "Σήμερα είναι ". $days[date("w")] . " " . date("d") . " " . $months[date("n")] . " " . date("Y") ;

--------------
Η time() μας δίνει ένα νούμερο π.χ. 1202799799 το οποίο είναι ο αριθμός των δευτερολέπτων που πέρασαν από την 1/1/1970 και ονομάζεται timestamp.
Αυτός ο αριθμός δευτερολέπτων αφορά μια συγκεκριμένη χρονική στιγμή. Έχοντας αυτόν τον αριθμό μπορούμε να εξάγουμε όποια πληροφορία θέλουμε για αυτή την συγκεκριμένη στιγμή,
π.χ. ποιά ημερομηνία αντιπροσωπεύει: echo date("d-m-Y",1202799799); // 12-02-2008
ή ποιά χρονική στιγμή της ημερομηνίας αυτής: echo date("h:i:s",1202799799); // 09:03:19

Είναι φανερό οτι είναι πολύ έυκολο να γίνουν πράξεις συγκρίσεων και προσθαφαιρέσεων με timestamps αφού είναι απλά νούμερα χωρίς σύμβολα και κάθε μελλοντικό timestamp είναι μεγαλύτερο από νεότερά του. Αν Αφαιρέσουμε δύο timestamp θα βρούμε το χρόνο που μεσολάβησε σε δευτερόλεπτα, ή αν το διαιρέσουμε δια 86400 σε μέρες.
Εδώ υπάρχει ένα μικρό πρόβλημα όταν η αρχική ημερομηνία και η τελικη δεν βρίσκονται μέσα στην ίδια ζώνη θερινής χειμερινής ώρας οπότε το πραγματικό αποτέλεσμα διαφέρει κατά μία ώρα +- και η διαίρεση δια 86400 να μην δίνει στρόγγυλο αριθμό, αλλά εφόσον μας ενδιαφέρει το πόσες μέρες πέρασαν από την μια ημερομηνία ως την άλλη αυτό λύνεται εύκολα με στρογγύλευση του αριθμού.

Η time() λοιπόν μας δίνει το timestamp της τρέχουσας χρονικής στιγμής, πως όμως θα βρούμε το timestamp μιας άλλης χρονικής στιγμής ώστε να κάνουμε πράξεις μεταξύ τους;

--------------
Η mktime("seconds","minutes","hours","month","day","year") (Η σειρά των παραμέτρων είναι λίγο αλλόκοτη γι αυτό χρειάζεται προσοχή) μπορεί να κατασκευάσει το timestamp της χρονικής στιγμής που δίνουμε σαν παραμέτρους. Αν οι πράξεις που θέλουμε να κάνουμε αφορούν μόνο ημέρες δίνουμε στις τρείς πρώτες παραμέτρους "0".
Το παρακάτω μας δίνει το τρέχον timestamp (με έναν μάλλον χαζό τρόπο αφού είναι ίδιο με το time() ).
mktime(date("s"),date("i"),date("H"),date("m"),date("d"),date("Y")). Είναι όμως πολύ χρήσιμο όταν θέλουμε να βρούμε το timestamp για κάποια χρονική στιγμή για την οποία δεν ξέρουμε τα ακριβή στοιχεία (παραμέτρους της mktime().)
Παράδειγμα: θέλουμε το timestamp για μετά από 10 μέρες από σήμερα ή ακριβώς ένα χρόνο μετά.
Το παραπάνω μπορεί να γραφτεί: mktime(date("s"),date("i"),date("H"),date("m"),date("d")+10,date("Y")) ή
mktime(date("s"),date("i"),date("H"),date("m"),date("d"),date("Y")+1)
Το μεγάλο πλεονέκτημα με την mktime() είναι οτι δεν χρειάζεται να ανησυχούμε για το αν ο μήνας έχει 30 ή 31 μερες αν το έτος είναι δίσεκτο, ή αν πέφτουμε σε αλλαγή μήνα από φεβρουάριο προς Μάρτιο, h mktime() θα μας δώσει την σωστή ημερομηνία.

Ο συνδυασμός λοιπόν των τριών συναρτήσεων της PHP μας δίνει την δυνατότητα να υπολογίζουμε ή να συγκρίνουμε εύκολα ημερομηνίες.

Στην πράξη:
παράδειγμα 1.
Θέλουμε να βάλουμε μια ανακοίνωση στο site μας και να σταματήσει να εμφανίζεται αυτόματα μετά από κάποια στιγμή που θα ορίσουμε πχ 31-12-2009 23:59:59 δηλαδή με την εκπνοή του χρόνου.
Για να κάνουμε την συγκριση αν πέρασε η δοθείσα χρονική στιγμή πρέπει να βρούμε το timestamp για αυτή τη χρονική στιγμή και να το συγκρίνουμε με το τρέχον.

$enddate = mktime("59","59","23","12","31","2009");
if ($enddate > time()) { echo "ΑΝΑΚΟΙΝΩΣΗ: μλπα - μπλα - μπλα"΄}

Παράδειγμα 2.
Βάζουμε μια προσφορά στο site μας και θέλουμε να λήξει σε 10 μέρες. Για να μην έχουμε τον νου μας πότε θα λήξει ώστε να την αφαιρέσουμε από το site μπορούμε να την εμφανίζουμε μέχρι την λήξη και μετά να μην εμφανίζεται (αυτόματα).

$regdate = "20/10/2009"; // καταγράφουμε την ημερομηνία καταχώρησης
$d = explode("/",$regdate); //παίρνουμε τα στοιχεία της ημερομηνίας σε array
$day = $d[0]+10; // προσθέτουμε τις μέρες που διαρκεί η εμφάνιση
$end_timestamp = mktime("0","0","0",$d[1],$day,$d[2]); //δημιουργούμε το timestamp της ημερομηνίας λήξης
$thismoment = time(); // το τρέχον timestamp
if ($end_timestamp > $thismoment) // η σύγκριση
{ echo "ΠΡΟΣΦΟΡΑ: μλπα - μπλα - μπλα"΄} // H προσφορά

Παράδειγμα 3.
Θέλουμε σε ένα σύστημα κρατήσεων να βρούμε πόσες διανυκτερεύσεις ζητάει ο πελάτης (ο οποίος δίνει ημερομηνία άφιξης και ημερομηνία αναχώρησης)

Ημερομηνίες που έδωσε ο πελάτης
$date_arr = "23/07/2010";
$date_dep = "05/08/2010";

$d1=explode("/",$date_arr);
$d2=explode("/",$date_dep);

$arrival_date = mktime("0","0","0",$d1[1],$d1[0],$d1[2]);
$departure_date = mktime("0","0","0",$d2[1],$d2[0],$d2[2]);

$dianikterefseis = round(($departure_date - $arrival_date)/86400);
Happy coding....
Μάρκος
http://lasernet.gr

Άβαταρ μέλους
vcore
Δημοσιεύσεις: 354
Εγγραφή: 20 Δεκ 2003 01:19
Τοποθεσία: Crete
Επικοινωνία:

[TUTORIAL] Πράξεις με τον χρόνο.

Δημοσίευση από vcore » 29 Μάιος 2010 15:11

'Αψογος.... thanks ;)
Easy CMS
------------
Το να ζητάς βοήθεια δεν σημαίνει ότι είσαι εξαρτημένος.

Άβαταρ μέλους
loxy
Δημοσιεύσεις: 208
Εγγραφή: 17 Ιούλ 2007 01:18

[TUTORIAL] Πράξεις με τον χρόνο.

Δημοσίευση από loxy » 29 Μάιος 2010 15:14

Πολυ ωραιο, tutorial .
Παντα χρησιμο...

Άβαταρ μέλους
vassilism
Δημοσιεύσεις: 1950
Εγγραφή: 17 Μαρ 2007 14:47
Επικοινωνία:

[TUTORIAL] Πράξεις με τον χρόνο.

Δημοσίευση από vassilism » 29 Μάιος 2010 15:34

Μπράβο Μάρκο :clap:
Αυτό ήταν ένα βοήθημα που έλειπε.

Άβαταρ μέλους
telas
Honorary Member
Δημοσιεύσεις: 1594
Εγγραφή: 12 Μαρ 2004 12:54
Τοποθεσία: Kastoria
Επικοινωνία:

[TUTORIAL] Πράξεις με τον χρόνο.

Δημοσίευση από telas » 29 Μάιος 2010 16:41

nice :)
Web Design - Δημιουργία Ιστοσελίδας - http://www.computerman.gr/
My Photography - http://www.tilaveridis.com/
Τεχνολογικά προιόντα - http://www.bigbox.gr/

Απάντηση

Επιστροφή στο “PHP Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες